Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8

В bagian kahiji Kuring nyoba ngabejaan insinyur éléktronika hobi anu tumuwuh nepi ti calana Arduino kumaha jeung naha maranéhanana kudu maca lembar data jeung dokuméntasi séjén pikeun microcontrollers. Téks tétéla badag, jadi kuring jangji baris némbongkeun conto praktis dina artikel misah. Nya, anjeunna nyebat dirina salaku jamur susu ...

Dinten ieu kuring bakal nunjukkeun anjeun kumaha ngagunakeun lembar data pikeun ngabéréskeun anu saderhana, tapi dipikabutuh pikeun seueur proyék, tugas dina STM32 (Pél Biru) sareng pangendali STM8. Sadaya proyék demo didédikasikeun ka LED karesep kuring, kami bakal terang dina jumlah anu ageung, anu kami kedah nganggo sagala jinis périferal anu pikaresepeun.

Téksna deui tétéla ageung, janten pikeun genah kuring ngadamel kontén:

Pil STM32 Blue: 16 LED sareng supir DM634
STM8: Nyetel genep pin PWM
STM8: 8 RGB LEDs on tilu pin, interrupts

Bantahan: Abdi sanés insinyur, kuring henteu pura-pura gaduh pangaweruh anu jero dina éléktronika, tulisan éta dimaksudkeun pikeun amatir sapertos kuring. Kanyataanna, kuring dianggap sorangan dua taun ka tukang salaku target panongton. Upami aya anu nyarios ka kuring yén lembar data dina chip anu teu biasa henteu pikasieuneun dibaca, kuring moal nyéépkeun waktos milarian sababaraha potongan kode dina Internét sareng nyiptakeun kruk kalayan gunting sareng pita napel.

Fokus artikel ieu dina lembar data, sanés proyék, janten kodeu tiasa henteu rapih sareng sering keram. Proyék sorangan saderhana pisan, sanaos cocog pikeun kenalan munggaran sareng chip énggal.

Abdi ngarepkeun tulisan kuring bakal ngabantosan batur dina tahap immersion anu sami dina hobi.

STM32

16 LEDs kalawan DM634 na SPI

Proyék leutik nganggo Pil Biru (STM32F103C8T6) sareng supir LED DM634. Ngagunakeun datasheets, urang bakal angka kaluar supir, STM IO palabuhan sarta ngonpigurasikeun SPI.

DM634

chip Taiwanese kalawan 16 16-bit outputs PWM, bisa disambungkeun di ranté. Model low-end 12-bit dipikanyaho ti proyék domestik Lightpack. Dina hiji waktu, milih antara DM63x jeung TLC5940 well-dipikawanoh, Kuring milih DM pikeun sababaraha alesan: 1) TLC on Aliexpress pasti palsu, tapi ieu teu; 2) DM boga PWM otonom jeung generator frékuénsi sorangan; 3) eta bisa dibeuli inexpensively di Moscow, tinimbang ngantosan parsél ti Ali. Na, tangtosna, éta metot pikeun neuleuman kumaha carana ngadalikeun chip sorangan, tinimbang ngagunakeun perpustakaan siap-dijieun. Chip ayeuna utamana dibere dina pakét SSOP24; aranjeunna gampang solder ka adaptor.

Kusabab produsénna Taiwanese, lembar data chip ditulis dina basa Inggris Cina, nu hartina bakal senang. Mimiti urang tingali pinout (Sambungan Pin) pikeun ngartos leg mana anu nyambungkeun naon, sareng pedaran ngeunaan pin (Pin Pedaran). 16 pin:

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8
Sumber Tilelep DC (Lorong Buka)

tilelep / Buka-solokan kaluaran - solokan; sumber arus inflowing; kaluaran disambungkeun ka taneuh dina kaayaan aktip - LEDs disambungkeun ka supir ku cathodes. Sacara listrik, ieu, tangtosna, sanés "solokan terbuka" (solokan muka), tapi dina lembar data sering aya sebutan pikeun pin dina modeu solokan.

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8
Résistor éksternal antara REXT sareng GND pikeun nyetél nilai ayeuna kaluaran

Résistor rujukan dipasang antara pin REXT sareng taneuh, anu ngatur résistansi internal kaluaran, tingali grafik dina kaca 9 tina lembar data. Dina DM634, résistansi ieu ogé tiasa dikontrol ku parangkat lunak, netepkeun kacaangan sakabéh (kacaangan global); Kuring moal lebet kana detil dina tulisan ieu, kuring ngan ukur nempatkeun résistor 2.2 - 3 kOhm di dieu.

Pikeun ngartos kumaha carana ngontrol chip, hayu urang tingali katerangan antarmuka alat:

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8

Hehehehe, ieu, Cina Inggris dina sakabéh kamulyaan na. Narjamahkeun masalah ieu, anjeun tiasa ngartos upami anjeun hoyong, tapi aya cara anu sanés - tingali kumaha sambungan kana TLC5940 anu sami sacara fungsional dijelaskeun dina lembar data:

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8
... Ngan tilu pin diperlukeun pikeun ngasupkeun data kana alat. Ujung rising sinyal SCLK mindahkeun data tina pin SIN ka register internal. Sanggeus kabéh data geus dimuat, sinyal XLAT tinggi pondok latches data ditransfer sequentially kana registers internal. Registers internal mangrupikeun gerbang anu dipicu ku tingkat sinyal XLAT. Sakabéh data dikirimkeun bit paling signifikan munggaran.

kancing – kait/kait/konci.
Rising tepi - ujung ngarah tina pulsa
MSB heula – paling signifikan (paling kénca) bit maju.
pikeun data jam - ngirimkeun data sacara berurutan (saeutik-saeutik).

kecap kancing sering dipendakan dina dokuméntasi pikeun chip sareng ditarjamahkeun ku sababaraha cara, ku kituna pikeun pamahaman kuring bakal ngantepkeun kuring sorangan.

program atikan leutikSupir LED dasarna mangrupikeun register shift. "Ngalih" (regu) dina ngaran - bitwise gerakan data di jero alat: unggal bit anyar shoved jero ngadorong sakabéh ranté ka hareup di hareup eta. Kusabab teu aya anu hoyong ningali kedip-kedip kacau tina LED salami shift, prosésna lumangsung dina register panyangga anu dipisahkeun tina register kerja ku damper (kancing) nyaéta jenis ruang tunggu dimana bit disusun dina urutan anu dipikahoyong. Nalika sadayana tos siap, jepret dibuka sareng bit dianggo, ngagentos angkatan sateuacana. Kecap kancing dina dokuméntasi pikeun microcircuits ampir salawasna ngakibatkeun damper misalna, euweuh urusan dina kombinasi naon dipaké.

Janten, transfer data ka DM634 dilaksanakeun sapertos kieu: nyetél input DAI kana nilai bit anu paling signifikan tina jauh LED, tarik DCK ka luhur sareng ka handap; Nyetél input DAI kana nilai bit salajengna, narik DCK; jeung saterusna nepi ka sakabéh bit geus dikirimkeun (jam dina), sanggeus urang narik LAT. Ieu tiasa dilakukeun sacara manual (bit-bang), tapi leuwih sae pikeun ngagunakeun panganteur SPI husus tailored pikeun ieu, sabab dibere dina STM32 urang dina dua salinan.

Bulao Pél STM32F103

Bubuka: Controllers STM32 langkung kompleks tibatan Atmega328 tibatan sigana pikasieuneun. Leuwih ti éta, pikeun alesan hemat energi, ampir kabéh périferal dipareuman di mimiti, sarta frékuénsi jam nyaéta 8 MHz ti sumber internal. Untungna, programer STM wrote kode nu brings chip nepi ka "diitung" 72 MHz, sarta pangarang sadaya IDE kuring nyaho kaasup kana prosedur initialization, jadi urang teu perlu jam (tapi anjeun tiasa upami anjeun hoyong). Tapi anjeun kedah ngaktipkeun périferal.

Dokuméntasi: Pil Biru dilengkepan ku chip STM32F103C8T6 anu populér, aya dua dokumén anu mangpaat pikeun éta:

  • Lembar data pikeun mikrokontroler STM32F103x8 sareng STM32F103xB;
  • Manual Rujukan pikeun sakabéh garis STM32F103 tur leuwih.

Dina lembar data urang tiasa resep:

  • Pinouts - chip pinouts - bisi urang mutuskeun nyieun papan sorangan;
  • Mémori Peta - peta memori pikeun chip husus. The Rujukan Manual boga peta pikeun sakabéh garis, sarta eta nyebutkeun registers nu urang teu boga.
  • Tabel Definisi Pin - daptar fungsi utama sareng alternatif pin; Pikeun "pil biru" anjeun tiasa mendakan gambar anu langkung saé dina Internét kalayan daptar pin sareng fungsina. Ku alatan éta, urang geuwat google Blue Pill pinout sarta tetep gambar ieu dina leungeun:

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8
NB: aya kasalahan dina gambar ti Internét, anu dicatet dina komentar, hatur nuhun pikeun éta. Gambarna parantos diganti, tapi ieu mangrupikeun palajaran - langkung saé mariksa inpormasi sanés tina lembar data.

Urang nyabut lembar data, buka Manual Rujukan, sareng ti ayeuna urang ngan ukur nganggo éta.
Prosedur: urang nungkulan input / output baku, ngonpigurasikeun SPI, ngahurungkeun périferal perlu.

Input Kaluaran

Dina Atmega328, I / O dilaksanakeun saderhana pisan, naha seueur pilihan STM32 tiasa ngabingungkeun. Ayeuna urang ngan ukur peryogi kasimpulan, tapi ieu ogé ngagaduhan opat pilihan:

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8
buka solokan, push-tarik, alternatif push-tarik, alternatif buka solokan

"Tarik-dorong" (dorong-tarik) nyaéta kaluaran biasa tina Arduino, pin tiasa nyandak nilaina HIGH atanapi LOW. Tapi kalayan "solokan kabuka" aya kasusah, sanaos kanyataanna sadayana saderhana di dieu:

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8
Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8
Konfigurasi kaluaran / nalika port ditugaskeun pikeun kaluaran: / panyangga kaluaran diaktipkeun: / - mode solokan kabuka: "0" dina register kaluaran ngamungkinkeun N-MOS, "1" dina register kaluaran ninggalkeun port dina modeu Hi-Z ( P-MOS teu diaktipkeun ) / - mode push-tarik: "0" dina register kaluaran ngaktifkeun N-MOS, "1" dina register kaluaran ngaktifkeun P-MOS.

Sagala bédana antara solokan kabuka (solokan muka) tina "dorong-tarik" (dorong-tarik) nyaéta yén dina pin kahiji teu bisa nampa kaayaan TINGGI: nalika nulis hiji ka register kaluaran, eta mana kana mode lalawanan tinggi (impedansi tinggi, Hai-Z). Nalika nulis enol, pin behaves sami dina duanana modus, duanana logis tur listrik.

Dina modeu kaluaran normal, pin saukur nyiarkeun eusi register kaluaran. Dina "alternatif" eta dikawasa ku périferal pakait (tingali 9.1.4):

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8
Mun bit port ieu ngonpigurasi salaku pin fungsi alternatif, register pin ditumpurkeun sarta pin disambungkeun ka pin periferal.

fungsionalitas alternatif unggal pin dijelaskeun dina Pin Harti Lembar data aya dina gambar anu diunduh. Pikeun patarosan naon anu kudu dilakukeun upami pin ngagaduhan sababaraha fungsi alternatif, jawabanna dipasihkeun ku catetan kaki dina lembar data:

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8
Upami sababaraha périferal nganggo pin anu sami, pikeun ngahindarkeun konflik antara fungsi alternatif, ngan ukur hiji périferal kedah dianggo sakaligus, togél nganggo jam periferal ngaktifkeun bit (dina daptar RCC anu pas).

Tungtungna, pin dina modeu kaluaran ogé boga speed jam. Ieu mangrupikeun fitur hemat energi anu sanés; dina kasus urang, urang ngan ukur nyetél éta maksimal sareng hilap.

Janten: kami nganggo SPI, anu hartosna dua pin (kalayan data sareng sinyal jam) kedah janten "fungsi push-pull alternatif", sareng anu sanésna (LAT) kedah "push-tarik biasa". Tapi sateuacan masihan aranjeunna, hayu urang nungkulan SPI.

SPI

program atikan leutik sejen

SPI atanapi Serial Periferal Interface (antarmuka periferal serial) mangrupakeun panganteur basajan tur pohara efektif pikeun nyambungkeun MK kalawan MK sejen tur dunya luar sacara umum. Prinsip operasi na geus ditétélakeun di luhur, dimana ngeunaan supir LED Cina (dina manual rujukan, tingali bagian 25). SPI tiasa beroperasi dina mode master ("master") sareng budak ("budak"). SPI ngagaduhan opat saluran dasar, anu henteu sadayana tiasa dianggo:

  • MOSI, Master Output / Input Budak: pin ieu ngirimkeun data dina modeu master, sareng nampi data dina modeu budak;
  • MISO, Master Input / Budak Output: sabalikna, éta narima di master, sarta transmits di budak;
  • SCK, Jam Serial: Nyetél frékuénsi pangiriman data dina master atanapi nampi sinyal jam dina budak. Intina nganiaya ketukan;
  • SS, Budak Pilih: kalayan bantosan saluran ieu, budak terang yén aya anu dipikahoyong ti anjeunna. Dina STM32 disebut NSS, dimana N = négatip, i.e. controller jadi budak lamun aya taneuh dina saluran ieu. Ieu ngagabungkeun ogé kalawan mode Open Drain Output, tapi éta carita sejen.

Kawas sagalana sejenna, SPI on STM32 téh euyeub di fungsionalitas, nu ngajadikeun eta rada hese ngarti. Salaku conto, éta tiasa dianggo henteu ngan ukur ku SPI, tapi ogé kalayan antarmuka I2S, sareng dina dokuméntasi déskripsina dicampur, perlu pikeun motong kaleuwihan dina waktosna. Tugas urang saderhana pisan: urang ngan ukur kedah ngirim data nganggo MOSI sareng SCK. Urang buka bagian 25.3.4 (komunikasi half-duplex, komunikasi half-duplex), dimana urang manggihan 1 jam sareng 1 kawat data unidirectional (1 sinyal jam sareng 1 aliran data saarah):

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8
Dina modeu ieu, aplikasi ngagunakeun SPI dina modeu ngirimkeun wungkul atanapi nampi wungkul. / Modeu ngan ukur sami sareng mode duplex: data dikirimkeun dina pin ngirimkeun (MOSI dina mode master atanapi MISO dina mode budak), sareng pin nampi (MISO atanapi MOSI masing-masing) tiasa dianggo salaku pin I / O biasa. . Dina hal ieu, aplikasi ngan perlu malire panyangga Rx (lamun dibaca, moal aya data ditransfer dinya).

Hebat, pin MISO gratis, hayu urang sambungkeun sinyal LAT ka dinya. Hayu urang tingali Budak Pilih, anu dina STM32 tiasa dikontrol sacara program, anu saé pisan. Kami maca paragraf anu nami anu sami dina bagian 25.3.1 Pedaran Umum SPI:

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8
Software kontrol NSS (SSM = 1) / Inpormasi pilihan budak dikandung dina bit SSI tina SPI_CR1 register. Pin NSS éksternal tetep bébas pikeun kaperluan aplikasi séjén.

Waktosna nyerat ka register. Kuring mutuskeun pikeun nganggo SPI2, milarian alamat dasarna dina lembar data - dina bagian 3.3 Peta Mémori:

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8

Nya, hayu urang mimitian:

#define _SPI2_(mem_offset) (*(volatile uint32_t *)(0x40003800 + (mem_offset)))

Buka bagian 25.3.3 kalawan judul timer explanatory "Konfigurasi SPI dina Master Mode":

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8

1. Nyetél frékuénsi jam serial kalawan bit BR [2: 0] dina SPI_CR1 register.

Registers dikumpulkeun dina bagian manual rujukan tina nami anu sami. Pindah alamat (Alamat offset) pikeun CR1 - 0x00, sacara standar sadayana bit diberesihan (Reset nilai 0x0000):

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8

Bit BR nyetel divider jam controller, sahingga nangtukeun frékuénsi di mana SPI bakal beroperasi. Frékuénsi STM32 kami bakal 72 MHz, supir LED, numutkeun lembar data na, beroperasi kalayan frékuénsi dugi ka 25 MHz, janten urang kedah ngabagi opat (BR [2: 0] = 001).

#define _SPI_CR1 0x00

#define BR_0        0x0008
#define BR_1        0x0010
#define BR_2        0x0020

_SPI2_ (_SPI_CR1) |= BR_0;// pclk/4

2. Setel bit CPOL jeung CPHA pikeun nangtukeun hubungan antara mindahkeun data jeung waktu jam serial (tingali diagram dina kaca 240)

Kusabab urang nuju maca lembar data di dieu sareng henteu ningali skématik, hayu urang langkung caket kana déskripsi téks tina CPOL sareng CPHA bit dina kaca 704 (SPI Umum Katerangan):

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8
Fase jam sareng polaritasna
Ngagunakeun CPOL na CPHA bit tina SPI_CR1 register, Anjeun programmatically bisa milih opat hubungan timing. Bit CPOL (polaritas jam) ngadalikeun kaayaan sinyal jam nalika henteu aya data anu dikirimkeun. Bit ieu ngadalikeun mode master sareng slave. Upami CPOL direset, pin SCK rendah dina modeu istirahat. Upami bit CPOL disetel, pin SCK luhur nalika modeu istirahat.
Nalika CPHA (fase jam) bit diatur, strobe bubu bit tinggi ujung kadua sinyal SCK (ragrag lamun CPOL jelas, naek lamun CPOL disetel). Data direbut ku parobahan kadua dina sinyal jam. Lamun bit CPHA jelas, strobe bubu bit tinggi nyaéta ujung rising sinyal SCK (ujung ragrag lamun CPOL diatur, rising ujung lamun CPOL diberesihan). Data direbut dina robahan kahiji dina sinyal jam.

Sanggeus nyerep pangaweruh ieu, urang datang ka kacindekan yen duanana bit kudu tetep nol, sabab Kami hoyong sinyal SCK tetep rendah nalika henteu dianggo, sareng data dikirimkeun dina ujung naékna pulsa (tingali Gbr. Rising Edge dina lembar data DM634).

Ngomong-ngomong, di dieu urang mimiti mendakan fitur kosakata dina lembar data ST: di antarana aya frasa "ngareset bit kana nol" ditulis. pikeun ngareset saeutikteu pikeun mupus saeutik, siga, contona, Atmega.

3. Setel bit DFF pikeun nangtukeun naha blok data 8-bit atawa 16-bit format

Kuring husus nyandak DM16 634-bit ku kituna teu ganggu ku ngirimkeun data PWM 12-bit, kawas DM633. Masuk akal pikeun nyetél DFF ka hiji:

#define DFF         0x0800

_SPI2_ (_SPI_CR1) |= DFF; // 16-bit mode

4. Konpigurasikeun bit LSBFIRST dina SPI_CR1 register pikeun nangtukeun format block

LSBFIRST, sakumaha ngaranna nunjukkeun, ngonpigurasikeun transmisi kalawan saeutik saeutik signifikan munggaran. Tapi DM634 hayang nampa data mimitian ti bit paling signifikan. Ku alatan éta, urang ninggalkeun eta reset.

5. Dina modeu hardware, lamun input ti NSS pin diperlukeun, nerapkeun sinyal tinggi ka NSS pin salila sakabéh runtuyan mindahkeun bait. Dina modeu software NSS, set SSM jeung SSI bit dina SPI_CR1 register. Upami pin NSS dianggo salaku kaluaran, ngan ukur bit SSOE anu kedah disetél.

Pasang SSM sareng SSI pikeun hilap kana mode hardware NSS:

#define SSI         0x0100
#define SSM         0x0200

_SPI2_ (_SPI_CR1) |= SSM | SSI; //enable software control of SS, SS high

6. Bit MSTR jeung SPE kudu disetel (tetep disetel ngan lamun sinyal NSS tinggi)

Sabenerna, ku bit ieu kami nunjuk SPI kami salaku master sareng hurungkeun:

#define MSTR        0x0004
#define SPE         0x0040

_SPI2_ (_SPI_CR1) |= MSTR; //SPI master
//когда все готово, включаем SPI
_SPI2_ (_SPI_CR1) |= SPE;

SPI dikonpigurasikeun, hayu urang langsung nyerat fungsi anu ngirim bait ka supir. Teraskeun maca 25.3.3 "Konpigurasikeun SPI dina modeu master":

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8
Urutan mindahkeun data
Pangiriman dimimitian nalika bait ditulis kana panyangga Tx.
bait data dimuat kana shift register di sajajar mode (ti beus internal) salila pangiriman bit munggaran, nu satutasna dikirimkeun ka sekuen modeu pin MOSI, mimiti atawa panungtung bit maju gumantung kana setelan tina bit LSBFIRST dina CPI_CR1 register. Bandéra TXE diatur sanggeus pangiriman data ti Tx panyangga pikeun shift register, sarta ogé dibangkitkeun hiji ngaganggu lamun bit TXEIE dina CPI_CR1 register diatur.

Kuring nyorot sababaraha kecap dina tarjamahan pikeun narik perhatian kana hiji fitur palaksanaan SPI di Controllers STM. Dina Atmega bendera TXE (Tx Kosong, Tx kosong tur siap pikeun nampa data) diatur ngan sanggeus sakabéh bait geus dikirim kaluar. Sarta di dieu bendera ieu diatur sanggeus bait geus diselapkeun kana register shift internal. Kusabab éta kadorong ka dinya kalayan sagala bit dina waktos anu sareng (sajajar), lajeng data ditransfer sequentially, TXE diatur saméméh bait sagemblengna dikirim. Ieu penting sabab dina kasus supir LED urang, urang kudu narik pin LAT sanggeus ngirim всех data, nyaéta. Bandéra TXE waé moal cekap pikeun urang.

Ieu ngandung harti yén urang kudu bandéra sejen. Hayu urang tingali 25.3.7 - "Bandera Status":

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8
<…>
Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8
bandéra SIBUK
Bandéra BSY diatur sareng dibersihkeun ku hardware (nulisna henteu aya pangaruh). Bandéra BSY nunjukkeun kaayaan lapisan komunikasi SPI.
Ieu ngareset:
nalika transfer parantos réngsé (iwal dina mode master upami transferna kontinyu)
nalika SPI ditumpurkeun
lamun aya kasalahan master mode (MODF=1)
Upami transferna henteu kontinyu, bendera BSY diberesihan antara unggal transfer data

Oké, ieu bakal mangpaat. Hayu urang manggihan dimana ayana Tx panyangga. Jang ngalampahkeun ieu, baca "SPI Data Register":

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8
Bit 15:0 DR [15:0] Data ngadaptar
Data anu ditampi atanapi data anu bakal dikirimkeun.
Register data dibagi jadi dua buffer - hiji keur nulis (transmit panyangga) jeung hiji keur maca (nampi panyangga). Nulis kana register data nyerat ka Tx panyangga, sarta maca tina register data bakal balik nilai dikandung dina panyangga Rx.

Nya, sareng ngadaptar status, dimana umbul TXE sareng BSY kapanggih:

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8

Urang nulis:

#define _SPI_DR  0x0C
#define _SPI_SR  0x08

#define BSY         0x0080
#define TXE         0x0002

void dm_shift16(uint16_t value)
{
    _SPI2_(_SPI_DR) = value; //send 2 bytes
    while (!(_SPI2_(_SPI_SR) & TXE)); //wait until they're sent
}

Nya, sabab urang kedah ngirimkeun 16 kali dua bait, dumasar kana jumlah kaluaran supir LED, sapertos kieu:

void sendLEDdata()
{
    LAT_low();
    uint8_t k = 16;
    do
    {   k--;
        dm_shift16(leds[k]);
    } while (k);

    while (_SPI2_(_SPI_SR) & BSY); // finish transmission

    LAT_pulse();
}

Tapi urang henteu terang kumaha carana narik pin LAT, janten urang bakal uih deui ka I / O.

Napelkeun pin

Dina STM32F1 registers jawab kaayaan tina pin anu rada mahiwal. Ieu jelas yén aya leuwih ti Atmega, tapi maranéhna ogé béda ti chip STM séjén. Bagian 9.1 Katerangan Umum ngeunaan GPIO:

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8
Unggal tujuan umum I / O port (GPIO) boga dua 32-bit registers konfigurasi (GPIOx_CRL na GPIOx_CRH), dua 32-bit registers data (GPIOx_IDR na GPIOx_ODR), 32-bit set / reset register (GPIOx_BSRR), 16-bit reset register (GPIOx_BRR) jeung 32- bit blocking register (GPIOx_LCKR).

Kahiji dua registers mahiwal, sarta ogé rada teu merenah, sabab 16 pin port sumebar di sakuliah aranjeunna dina format "opat bit per adi". Jelema. pin enol nepi ka tujuh aya dina CRL, sarta sésana aya dina CRH. Dina waktu nu sarua, registers sésana hasil ngandung bit sadaya pin port - mindeng sésana satengah "ditangtayungan".

Pikeun kesederhanaan, hayu urang mimitian ti tungtung daptar.

Kami henteu peryogi daptar blokir.

Set na reset registers rada lucu sabab sawaréh duplikat silih: Anjeun bisa nulis sagalana ukur dina BSRR, dimana 16 bit luhur bakal ngareset pin ka enol, sarta leuwih handap bakal disetel ka 1, atawa anjeun ogé tiasa. make BRR, handap 16 bit nu ukur ngareset pin. Abdi resep pilihan kadua. Registers ieu penting sabab nyadiakeun aksés atom ka pin:

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8
Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8
Atomic Set atanapi Reset
Teu perlu nganonaktipkeun interrupts nalika program GPIOx_ODR dina tingkat bit: hiji atawa leuwih bit bisa dirobah ku operasi nulis atom tunggal APB2. Ieu kahontal ku nulis "1" ka set / reset register (GPIOx_BSRR atawa, pikeun reset wungkul, GPIOx_BRR) tina bit nu kudu dirobah. bit sejenna bakal tetep unchanged.

The registers data boga ngaran cukup timer explanatory - IDR = ngasupkeun Arah ngadaptar, asupan ngadaptar; ODR = hasil Arah ngadaptar, kaluaran register. Kami henteu peryogi aranjeunna dina proyék ayeuna.

Sarta pamustunganana, registers kontrol. Kusabab urang resep kana pin SPI kadua, nyaéta PB13, PB14 sareng PB15, urang langsung ningali CRH:

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8

Sareng urang tingali yén urang kedah nyerat sababaraha bit tina 20 dugi ka 31.

Urang geus ilahar kaluar luhur naon urang hayang ti pin, jadi didieu kuring baris ngalakukeun tanpa screenshot a, Kuring ngan bakal nyebutkeun yén MODE nangtukeun arah (input lamun duanana bit disetel ka 0) jeung speed pin (urang kudu 50MHz, i.e. duanana pin ka "1"), sarta CNF susunan mode: biasa "push-tarikan" - 00, "alternatif" - 10. Sacara standar, sakumaha urang tingali di luhur, sadaya pin boga bit katilu ti handap (CNF0), eta susunan aranjeunna ka modeu asupan ngambang.

Kusabab kuring ngarencanakeun pikeun ngalakukeun hal anu sanés sareng chip ieu, pikeun kesederhanaan kuring parantos netepkeun sadaya nilai MODE sareng CNF anu mungkin pikeun daptar kontrol handap sareng luhur.

Kumaha bae siga kieu

#define CNF0_0 0x00000004
#define CNF0_1 0x00000008
#define CNF1_0 0x00000040
#define CNF1_1 0x00000080
#define CNF2_0 0x00000400
#define CNF2_1 0x00000800
#define CNF3_0 0x00004000
#define CNF3_1 0x00008000
#define CNF4_0 0x00040000
#define CNF4_1 0x00080000
#define CNF5_0 0x00400000
#define CNF5_1 0x00800000
#define CNF6_0 0x04000000
#define CNF6_1 0x08000000
#define CNF7_0 0x40000000
#define CNF7_1 0x80000000
#define CNF8_0 0x00000004
#define CNF8_1 0x00000008
#define CNF9_0 0x00000040
#define CNF9_1 0x00000080
#define CNF10_0 0x00000400
#define CNF10_1 0x00000800
#define CNF11_0 0x00004000
#define CNF11_1 0x00008000
#define CNF12_0 0x00040000
#define CNF12_1 0x00080000
#define CNF13_0 0x00400000
#define CNF13_1 0x00800000
#define CNF14_0 0x04000000
#define CNF14_1 0x08000000
#define CNF15_0 0x40000000
#define CNF15_1 0x80000000

#define MODE0_0 0x00000001
#define MODE0_1 0x00000002
#define MODE1_0 0x00000010
#define MODE1_1 0x00000020
#define MODE2_0 0x00000100
#define MODE2_1 0x00000200
#define MODE3_0 0x00001000
#define MODE3_1 0x00002000
#define MODE4_0 0x00010000
#define MODE4_1 0x00020000
#define MODE5_0 0x00100000
#define MODE5_1 0x00200000
#define MODE6_0 0x01000000
#define MODE6_1 0x02000000
#define MODE7_0 0x10000000
#define MODE7_1 0x20000000
#define MODE8_0 0x00000001
#define MODE8_1 0x00000002
#define MODE9_0 0x00000010
#define MODE9_1 0x00000020
#define MODE10_0 0x00000100
#define MODE10_1 0x00000200
#define MODE11_0 0x00001000
#define MODE11_1 0x00002000
#define MODE12_0 0x00010000
#define MODE12_1 0x00020000
#define MODE13_0 0x00100000
#define MODE13_1 0x00200000
#define MODE14_0 0x01000000
#define MODE14_1 0x02000000
#define MODE15_0 0x10000000
#define MODE15_1 0x20000000

Pin kami aya dina port B (alamat dasar - 0x40010C00), kode:

#define _PORTB_(mem_offset) (*(volatile uint32_t *)(0x40010C00 + (mem_offset)))

#define _BRR  0x14
#define _BSRR 0x10
#define _CRL  0x00
#define _CRH  0x04

//используем стандартный SPI2: MOSI на B15, CLK на B13
//LAT пусть будет на неиспользуемом MISO – B14

//очищаем дефолтный бит, он нам точно не нужен
_PORTB_ (_CRH) &= ~(CNF15_0 | CNF14_0 | CNF13_0 | CNF12_0);

//альтернативные функции для MOSI и SCK
_PORTB_ (_CRH) |= CNF15_1 | CNF13_1;

//50 МГц, MODE = 11
_PORTB_ (_CRH) |= MODE15_1 | MODE15_0 | MODE14_1 | MODE14_0 | MODE13_1 | MODE13_0;

Sareng, sasuai, anjeun tiasa nyerat definisi pikeun LAT, anu bakal dikedut ku ngadaptar BRR sareng BSRR:

/*** LAT pulse – high, then low */
#define LAT_pulse() _PORTB_(_BSRR) = (1<<14); _PORTB_(_BRR) = (1<<14)

#define LAT_low() _PORTB_(_BRR) = (1<<14)

(LAT_low ngan ku inersia, éta salawasna geus kitu, hayu eta tetep)

Ayeuna sagalana geus hébat, tapi teu jalan. Kusabab ieu STM32, aranjeunna ngahemat listrik, anu hartosna anjeun kedah ngaktipkeun clocking périferal anu diperyogikeun.

Hurungkeun jam

Arloji, ogé katelah Jam, tanggung jawab kana jam. Sarta kami geus bisa perhatikeun singketan RCC. Kami milarian dina dokuméntasi: ieu Reset sareng Kontrol Jam.

Sakumaha anu didadarkeun di luhur, untungna, bagian anu paling hese dina topik clocking dilakukeun pikeun urang ku urang ti STM, anu kami hatur nuhun pisan (sakali deui kuring bakal masihan tautan ka Situs web Di Halt, sangkan jelas kumaha ngabingungkeunana). Urang ngan butuh registers jawab sangkan clocking periferal (Jam Periferal Aktipkeun registers). Mimiti, hayu urang milarian alamat dasar RCC, éta dina awal "Peta Mémori":

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8

#define _RCC_(mem_offset) (*(volatile uint32_t *)(0x40021000 + (mem_offset)))

Teras klik kana tautan dimana anjeun nyobian mendakan anu aya dina piring, atanapi, langkung saé, ngalangkungan déskripsi ngeunaan pendaptaran anu ngamungkinkeun para bagian ngeunaan ngaktipkeun registers. Dimana urang bakal mendakan RCC_APB1ENR sareng RCC_APB2ENR:

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8
Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8

Jeung maranéhna, sasuai, ngandung bit nu ngawengku clocking of SPI2, IOPB (I / O Port B) jeung fungsi alternatif (AFIO).

#define _APB2ENR 0x18
#define _APB1ENR 0x1C

#define IOPBEN 0x0008
#define SPI2EN 0x4000
#define AFIOEN 0x0001

//включаем тактирование порта B и альт. функций
_RCC_(_APB2ENR) |= IOPBEN | AFIOEN;

//включаем  тактирование SPI2
_RCC_(_APB1ENR) |= SPI2EN;

Kode ahir bisa kapanggih di dieu.

Upami anjeun gaduh kasempetan sareng kahayang pikeun nguji, teras sambungkeun DM634 sapertos kieu: DAI ka PB15, DCK ka PB13, LAT ka PB14. Urang kakuatan supir ti 5 volt, ulah poho pikeun nyambungkeun grounds.

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8

STM8 PWM

PWM dina STM8

Nalika kuring ngan ukur ngarencanakeun tulisan ieu, kuring mutuskeun, sabagé conto, pikeun nyobian ngawasaan sababaraha fungsionalitas chip anu teu biasa nganggo ukur lembar data, ku kituna kuring henteu mungkas sareng tukang sapatu tanpa sapatu. STM8 idéal pikeun peran ieu: kahiji, kuring kungsi sababaraha papan Cina kalawan STM8S103, sarta Bréh, éta teu pisan populér, sarta ku kituna godaan maca sarta manggihan solusi dina Internet rests on kurangna ieu pisan solusi.

chip ogé boga lembar data и manual rujukan RM0016, dina kahiji aya pinout na ngadaptar alamat, dina kadua - sagalana sejenna. STM8 diprogram dina C dina IDE dahsyat ST Visual Ngembangkeun.

Clocking sareng I / O

Sacara standar, STM8 beroperasi dina frékuénsi 2 MHz, ieu kudu dilereskeun langsung.

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8
HSI (High Speed ​​​​Internal) Jam
Sinyal jam HSI diturunkeun tina osilator RC internal 16 MHz sareng divider anu tiasa diprogram (1 ka 8). Ieu diatur dina jam divider register (CLK_CKDIVR).
Catetan: di mimiti, hiji osilator HSI RC kalawan divider 8 dipilih salaku sumber ngarah tina sinyal jam.

Kami mendakan alamat pendaptaran dina lembar data, pedaran dina refman sareng ningali yén ngadaptar kedah diberesihan:

#define CLK_CKDIVR *(volatile uint8_t *)0x0050C6

CLK_CKDIVR &= ~(0x18);

Kusabab urang bade ngajalankeun PWM tur sambungkeun LEDs, hayu urang nempo pinout nu:

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8

Chip leutik, seueur fungsi anu ditunda dina pin anu sami. Anu aya dina kurung kuadrat nyaéta "fungsi alternatif", digentos ku "bait pilihan" (bait pilihan) - hal kawas Atmega fuses. Anjeun tiasa ngarobah nilai maranéhanana sacara program, tapi teu perlu, sabab Pungsi anyar diaktipkeun ngan sanggeus reboot a. Ieu gampang ngagunakeun ST Visual Programmer (diundeur jeung Visual Ngembangkeun), nu bisa ngarobah bait ieu. Pinout nunjukkeun yén pin CH1 sareng CH2 tina timer munggaran disumputkeun dina kurung kuadrat; perlu pikeun ngeset AFR1 na AFR0 bit dina STVP, sarta kadua ogé bakal mindahkeun kaluaran CH1 timer kadua ti PD4 mun PC5.

Ku kituna, 6 pin bakal ngadalikeun LEDs: PC6, PC7 na PC3 pikeun timer munggaran, PC5, PD3 na PA3 pikeun kadua.

Nyetél pin I/O sorangan dina STM8 langkung saderhana sareng langkung logis tibatan dina STM32:

  • akrab tina register arah data Atmega DDR (Arah Data ngadaptar): 1 = kaluaran;
  • kadali munggaran register CR1, nalika kaluaran, Nyetél mode push-tarikan (1) atanapi solokan kabuka (0); saprak kuring nyambungkeun LEDs kana chip kalawan cathodes, Kuring ninggalkeun enol dieu;
  • kadali kadua register CR2, lamun kaluaran, Nyetél speed jam: 1 = 10 MHz

#define PA_DDR     *(volatile uint8_t *)0x005002
#define PA_CR2     *(volatile uint8_t *)0x005004
#define PD_DDR     *(volatile uint8_t *)0x005011
#define PD_CR2     *(volatile uint8_t *)0x005013
#define PC_DDR     *(volatile uint8_t *)0x00500C
#define PC_CR2     *(volatile uint8_t *)0x00500E

PA_DDR = (1<<3); //output
PA_CR2 |= (1<<3); //fast
PD_DDR = (1<<3); //output
PD_CR2 |= (1<<3); //fast
PC_DDR = ((1<<3) | (1<<5) | (1<<6) | (1<<7)); //output
PC_CR2 |= ((1<<3) | (1<<5) | (1<<6) | (1<<7)); //fast

Setélan PWM

Kahiji, hayu urang ngartikeun istilah:

  • Frékuénsi PWM - frékuénsi dimana timer ticks;
  • Otomatis-reload, AR - nilai autoloadable nepi ka mana timer bakal diitung (periode pulsa);
  • Acara Update, UEV - kajadian anu lumangsung nalika timer diitung kana AR;
  • Siklus Kawajiban PWM - Siklus tugas PWM, sering disebut "faktor tugas";
  • Capture / Bandingkeun Niley - nilai keur newak / ngabandingkeun, nu timer diitung bakal ngalakukeun hiji hal (dina kasus PWM, éta ngabalikeun sinyal kaluaran);
  • Nilai Preload - nilai preloaded. Bandingkeun nilai teu bisa ngarobah bari timer ticking, disebutkeun siklus PWM bakal megatkeun. Ku alatan éta, nilai anu dikirimkeun énggal disimpen dina panyangga sareng ditarik kaluar nalika waktosna dugi ka tungtung mundur sareng direset;
  • Ujung-jajar и Modeu garis tengah - alignment sapanjang wates sareng di tengah, sami sareng Atmel PWM gancang и PWM fase-leres.
  • OCiREF, Kaluaran Bandingkeun Sinyal Rujukan - sinyal kaluaran rujukan, kanyataanna, naon mucunghul dina pin pakait dina modeu PWM.

Sakumaha anu parantos jelas tina pinout, dua timer gaduh kamampuan PWM - anu kahiji sareng anu kadua. Duanana nyaéta 16-bit, anu kahiji ngagaduhan seueur fitur tambahan (khususna, éta tiasa ngitung kaluhur sareng kahandap). Urang kudu duanana gawé sarua, jadi kuring mutuskeun pikeun mimitian ku nu kadua écés poorer, ku kituna teu ngahaja ngagunakeun hal anu teu aya. Sababaraha masalah éta pedaran fungsionalitas PWM sadaya timers dina manual rujukan dina bab ngeunaan timer munggaran (17.5.7 PWM Mode), jadi Anjeun kudu luncat deui mudik sapanjang dokumen sadaya waktu.

PWM on STM8 boga kaunggulan penting leuwih PWM on Atmega:

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8
Wates Blok PWM
Konfigurasi akun ti handap ka luhur
Cacah handap-up aktip lamun bit DIR dina register TIM_CR1 diberesihan
conto
Contona ngagunakeun mode PWM munggaran. Sinyal rujukan PWM OCiREF dicekel luhur salami TIM1_CNT <TIM1_CCRi. Upami teu kitu, butuh tingkat low. Lamun nilai ngabandingkeun dina TIM1_CCRi register leuwih gede ti nilai autoload (TIM1_ARR register), sinyal OCiREF dilaksanakeun dina 1. Lamun nilai ngabandingkeun 0, OCiREF dilaksanakeun dina nol....

STM8 timer salila acara update cék heula ngabandingkeun nilai, sarta ngan lajeng ngahasilkeun sinyal rujukan. Timer Atmega mimiti ngaco sareng ngabandingkeun, hasilna compare value == 0 kaluaran mangrupa jarum, nu kudu diurus kumaha bae (Contona, ku programmatically inverting logika).

Janten naon anu urang hoyong laksanakeun: 8-bit PWM (AR == 255), cacah ti handap ka luhur, alignment sapanjang wates. Kusabab bohlam lampu disambungkeun ka chip ku katoda, PWM kudu kaluaran 0 (LED on) nepi ka ngabandingkeun nilai jeung 1 sanggeus.

Kami parantos maca ngeunaan sababaraha Modeu PWM, ku kituna urang manggihan register diperlukeun pikeun timer kadua ku néangan dina manual rujukan pikeun frase ieu (18.6.8 - TIMx_CCMR1):

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8
110: Modeu PWM munggaran - nalika cacah ti handap ka luhur, saluran kahiji aktip bari TIMx_CNT <TIMx_CCR1. Upami teu kitu, saluran kahiji teu aktip. [Salajengna dina dokumén aya salinan-témpél erroneous ti timer 1] 111: Modeu PWM Kadua - lamun cacah ti handap ka luhur, saluran kahiji teu aktip bari TIMx_CNT <TIMx_CCR1. Upami teu kitu, saluran kahiji aktip.

Kusabab LED dihubungkeun sareng MK ku katoda, modeu kadua cocog pikeun urang (hiji ogé, tapi urang henteu acan terang).

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8
Bit 3 OC1PE: Aktipkeun pin 1 preload
0: Preload register on TIMx_CCR1 ditumpurkeun. Anjeun tiasa nyerat ka TIMx_CCR1 iraha waé. Nilai anyar dianggo langsung.
1: Preload register on TIMx_CCR1 diaktipkeun. Maca / nulis operasi ngakses register preload. Nilai TIMx_CCR1 anu tos dimuat sateuacana dimuat kana daptar bayangan salami unggal acara update.
*Catetan: Pikeun modeu PWM tiasa dianggo leres, pendaptaran preload kedah diaktipkeun. Ieu teu perlu dina modeu sinyal tunggal (bit OPM diatur dina TIMx_CR1 register).

Oké, hayu urang hurungkeun sadayana anu urang peryogikeun pikeun tilu saluran timer kadua:

#define TIM2_CCMR1 *(volatile uint8_t *)0x005307
#define TIM2_CCMR2 *(volatile uint8_t *)0x005308
#define TIM2_CCMR3 *(volatile uint8_t *)0x005309

#define PWM_MODE2   0x70 //PWM mode 2, 0b01110000
#define OCxPE       0x08 //preload enable

TIM2_CCMR1 = (PWM_MODE2 | OCxPE);
TIM2_CCMR2 = (PWM_MODE2 | OCxPE);
TIM2_CCMR3 = (PWM_MODE2 | OCxPE);

AR diwangun ku dua registers dalapan bit, sagalana basajan:

#define TIM2_ARRH  *(volatile uint8_t *)0x00530F
#define TIM2_ARRL  *(volatile uint8_t *)0x005310

TIM2_ARRH = 0;
TIM2_ARRL = 255;

Timer kadua ngan ukur tiasa cacah ti handap ka luhur, alignment sapanjang wates, teu aya anu kedah dirobih. Hayu urang nyetel divider frékuénsi, contona, ka 256. Pikeun timer kadua, divider diatur dina TIM2_PSCR register sarta kakuatan dua:

#define TIM2_PSCR  *(volatile uint8_t *)0x00530E

TIM2_PSCR = 8;

Sadaya anu tetep nyaéta ngaktipkeun kacindekan sareng timer kadua sorangan. Masalah kahiji direngsekeun ku registers Capture / Bandingkeun bisa jadi: aya dua, tilu saluran sumebar di sakuliah aranjeunna asymmetrically. Di dieu urang ogé bisa diajar yén kasebut nyaéta dimungkinkeun pikeun ngarobah polaritasna sinyal, i.e. prinsipna mah, ieu mungkin migunakeun PWM Mode 1. Urang nulis:

#define TIM2_CCER1 *(volatile uint8_t *)0x00530A
#define TIM2_CCER2 *(volatile uint8_t *)0x00530B

#define CC1E  (1<<0) // CCER1
#define CC2E  (1<<4) // CCER1
#define CC3E  (1<<0) // CCER2

TIM2_CCER1 = (CC1E | CC2E);
TIM2_CCER2 = CC3E;

Sarta pamustunganana, urang ngamimitian timer dina TIMx_CR1 register:

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8

#define TIM2_CR1   *(volatile uint8_t *)0x005300

TIM2_CR1 |= 1;

Hayu urang nyerat analog saderhana AnalogWrite (), anu bakal nransferkeun nilai-nilai saleresna ka timer pikeun ngabandingkeun. The registers ngaranna predictably Capture / Bandingkeun registers, aya dua di antarana pikeun tiap channel: 8 bit-urutan handap dina TIM2_CCRxL jeung tingkat luhur dina TIM2_CCRxH. Kusabab kami parantos nyiptakeun PWM 8-bit, cekap nyerat ngan ukur bit anu paling henteu signifikan:

#define TIM2_CCR1L *(volatile uint8_t *)0x005312
#define TIM2_CCR2L *(volatile uint8_t *)0x005314
#define TIM2_CCR3L *(volatile uint8_t *)0x005316

void setRGBled(uint8_t r, uint8_t g, uint8_t b)
{
    TIM2_CCR1L = r;
    TIM2_CCR2L = g;
    TIM2_CCR3L = b;
}

Pamaca attentive bakal aya bewara yen urang boga PWM rada cacad, teu bisa ngahasilkeun 100% eusian (dina nilai maksimum 255, sinyal ieu inverted pikeun hiji siklus timer). Pikeun LEDs ieu teu masalah, jeung maca attentive geus bisa nebak kumaha carana ngalereskeun eta.

PWM dina timer kadua jalan, hayu urang ngaléngkah ka kahiji.

Timer kahiji gaduh bit anu sami dina register anu sami (ngan éta bit anu tetep "ditangtayungan" dina timer kadua aktip dianggo dina mimiti pikeun sagala rupa hal canggih). Ku alatan éta, cukup pikeun manggihan alamat tina registers sarua dina datasheet jeung nyalin kodeu. Nya, ubah nilai pembagi frekuensi, sabab ... timer kahiji hayang nampa teu kakuatan dua, tapi hiji nilai 16-bit pasti dina dua registers Prescaler High и saeutik. Urang ngalakukeun sagalana jeung ... timer munggaran teu jalan. Naon masalahna?

Masalahna ngan ukur tiasa direngsekeun ku ningali sadaya bagian ngeunaan register kontrol timer 1, dimana urang milarian anu henteu gaduh timer kadua. Bakal aya 17.7.30 ngadaptar istirahat (TIM1_BKR), dimana aya bit ieu:

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8
Aktipkeun kaluaran utama

#define TIM1_BKR   *(volatile uint8_t *)0x00526D

TIM1_BKR = (1<<7);

Éta sadayana pasti ayeuna, kode Tuh.

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8

STM8 Multiplex

Multiplexing on STM8

Proyék mini anu katilu nyaéta nyambungkeun dalapan LED RGB ka timer kadua dina modeu PWM sareng ngajantenkeun warna anu béda. Hal ieu dumasar kana konsép multiplexing LED, nyaéta yén upami anjeun ngaktipkeun sareng mareuman LEDs pisan, gancang pisan, sigana urang bakal terus hurung (kegigihan visi, inersia persépsi visual). Kuring sakali hal kawas ieu dina Arduino.

Algoritma karya sapertos kieu:

  • nyambungkeun anoda tina RGB LED munggaran;
  • cahayana eta, ngirimkeun sinyal perlu ka katoda;
  • antosan dugi ka ahir siklus PWM;
  • nyambungkeun anoda kadua RGB LED;
  • hurungkeun...

Muhun, jsb. Tangtu, pikeun operasi geulis diperlukeun anoda disambungkeun tur LED "ignited" dina waktos anu sareng. Muhun, atawa ampir. Dina naon waé, urang kedah nyerat kode anu bakal ngahasilkeun nilai dina tilu saluran timer kadua, robih nalika UEV ngahontal, sareng dina waktos anu sami ngarobih LED RGB anu ayeuna aktip.

Kusabab switching LED otomatis, urang kudu nyieun "memori video" ti mana panangan interupsi bakal nampa data. Ieu susunan basajan:

uint8_t colors[8][3];

Pikeun ngarobih warna LED khusus, cekap nyerat nilai anu diperyogikeun kana Asép Sunandar Sunarya ieu. Sareng variabel bakal nanggungjawaban kana jumlah LED aktip

uint8_t cnt;

Demux

Pikeun multiplexing ditangtoskeun, urang peryogi, cukup aneh, demultiplexer CD74HC238. Demultiplexer - a chip nu implements operator dina hardware <<. Ngaliwatan tilu pin input (bit 0, 1 jeung 2) kami eupan eta tilu-bit angka X, sarta dina respon eta ngaktifkeun angka kaluaran (1<<X). Input sésa chip dipaké pikeun skala sakabéh desain. Urang peryogi chip ieu henteu ngan ukur pikeun ngirangan jumlah pin mikrokontroler anu dijajah, tapi ogé pikeun kaamanan - supados henteu ngahaja ngaktipkeun langkung seueur LED ti anu mungkin sareng henteu ngaduruk MK. chip hargana hiji Penny sarta kudu salawasna diteundeun dina kabinet ubar imah anjeun.

CD74HC238 kami bakal nanggungjawaban kanggo nyayogikeun tegangan ka anoda LED anu dipikahoyong. Dina multiplex full-fledged, éta bakal nyadiakeun tegangan kana kolom ngaliwatan P-MOSFET, tapi dina demo ieu mungkin langsung, sabab eta draws 20 mA, nurutkeun ratings maksimum mutlak dina lembar data. Ti Lembar data CD74HC238 urang peryogi pinouts sareng lambaran curang ieu:

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8
H = tingkat tegangan luhur, L = tingkat tegangan low, X - teu paduli

Urang sambungkeun E2 jeung E1 ka taneuh, E3, A0, A1 jeung A3 ka pin PD5, PC3, PC4 na PC5 of STM8. Kusabab tabel di luhur ngandung duanana tingkat low jeung luhur, urang ngonpigurasikeun pin ieu salaku push-tarikan pin.

PWM

PWM dina timer kadua dikonpigurasi dina cara nu sarua sakumaha dina carita saméméhna, kalawan dua béda:

Kahiji, urang kudu ngaktipkeun interupsi on Update Acara (UEV) nu bakal nelepon fungsi nu toggles LED aktip. Hal ieu dilakukeun ku cara ngarobah bit Update ngaganggu Aktipkeun dina register kalawan ngaran nétélakeun

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8
Ngaganggu Aktipkeun ngadaptar

#define TIM2_IER   *(volatile uint8_t *)0x005303

//enable interrupt
TIM2_IER = 1;

Beda kadua patali jeung fenomena multiplexing, kayaning ngabajak – cahaya parasit dioda. Dina hal urang, éta bisa muncul alatan kanyataan yén timer, sanggeus ngabalukarkeun hiji interupsi on UEV, terus keletik, sarta panangan interupsi teu boga waktu pikeun pindah LED saméméh timer mimiti nulis hal ka pin. Pikeun merangan ieu, anjeun bakal kudu invert logika (0 = kacaangan maksimum, 255 = euweuh cahayana) jeung ulah aya nilai siklus tugas ekstrim. Jelema. mastikeun yén sanggeus UEV LEDs kaluar lengkep pikeun hiji siklus PWM.

Ngarobah polaritasna:

//set polarity 
    TIM2_CCER1 |= (CC1P | CC2P);
    TIM2_CCER2 |= CC3P;

Hindarkeun setélan r, g sareng b ka 255 sareng émut ngabalikkeunana nalika dianggo.

Ngaganggu

Hakekat interupsi nyaéta yén dina kaayaan anu tangtu chip eureun ngajalankeun program utama sareng nyauran sababaraha fungsi éksternal. Interrupts lumangsung alatan pangaruh éksternal atawa internal, kaasup timer nu.

Nalika urang mimiti dijieun proyék di ST Visual Ngembangkeun, salian ti main.c kami nampi jandela kalayan file misterius stm8_interrupt_vector.c, otomatis kaasup dina proyék. Dina file ieu, hiji fungsi ditugaskeun ka unggal interupsi NonHandledInterrupt. Urang kedah ngabeungkeut fungsi urang kana interupsi anu dipikahoyong.

Lembar data ngagaduhan tabel vektor interupsi, dimana urang mendakan anu urang peryogikeun:

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8
13 TIM2 update / ngabahekeun
14 TIM2 newak / ngabandingkeun

Urang kedah ngagentos LED di UEV, janten urang kedah ngaganggu #13.

Sasuai, firstly, dina file stm8_interrupt_vector.c ngarobah ngaran standar tina fungsi jawab ngaganggu No.. 13 (IRQ13) ka anjeun sorangan:

{0x82, TIM2_Overflow}, /* irq13 */

Kadua, urang kedah nyiptakeun file main.h kalawan eusi handap:

#ifndef __MAIN_H
#define __MAIN_H

@far @interrupt void TIM2_Overflow (void);
#endif

Sarta pamustunganana, nulis fungsi ieu dina Anjeun main.c:

@far @interrupt void TIM2_Overflow (void)
{
    PD_ODR &= ~(1<<5); // вырубаем демультиплексор
    PC_ODR = (cnt<<3); // записываем в демультиплексор новое значение
    PD_ODR |= (1<<5); // включаем демультиплексор

    TIM2_SR1 = 0; // сбрасываем флаг Update Interrupt Pending

    cnt++; 
    cnt &= 7; // двигаем счетчик LED

    TIM2_CCR1L = ~colors[cnt][0]; // передаем в буфер инвертированные значения
    TIM2_CCR2L = ~colors[cnt][1]; // для следующего цикла ШИМ
    TIM2_CCR3L = ~colors[cnt][2]; // 

    return;
}

Sadaya anu tetep nyaéta ngaktipkeun interrupts. Hal ieu dilakukeun nganggo paréntah assembler rim - anjeun kedah milarian éta Manual Programming:

//enable interrupts
_asm("rim");

paréntah assembler sejen nyaeta sim – mareuman interrupts. Aranjeunna kedah dipareuman nalika nilai-nilai anyar ditulis kana "memori video", supados gangguan anu disababkeun dina waktos anu salah henteu ngarusak susunan.

Sadaya kode- dina GitHub.

Maca lembar data 2: SPI dina STM32; PWM, timers na interrupts on STM8

Upami sahenteuna aya anu mendakan tulisan ieu mangpaat, maka kuring henteu nyerat sia-sia. Kuring bakal bungah nampi koméntar sareng koméntar, kuring bakal nyobian ngajawab sadayana.

sumber: www.habr.com

Tambahkeun komentar