Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8

В sisih pisanan Aku nyoba ngandhani insinyur elektronik hobi sing tuwuh saka celana Arduino kepiye lan kenapa kudu maca lembar data lan dokumentasi liyane kanggo mikrokontroler. Teks kasebut dadi gedhe, mula aku janji bakal nuduhake conto praktis ing artikel sing kapisah. Nah, dheweke diarani jamur susu ...

Dina iki aku bakal nuduhake sampeyan carane nggunakake lembar data kanggo ngatasi cukup prasaja, nanging perlu kanggo akeh proyek, tugas ing STM32 (Blue Pill) lan STM8 controller. Kabeh proyèk demo darmabakti kanggo LED favorit, kita bakal padhang ing jumlah gedhe, kang kita kudu nggunakake kabeh limo peripheral menarik.

Teks kasebut maneh dadi gedhe, mula aku nggawe konten:

Pil Biru STM32: 16 LED karo driver DM634
STM8: Nyetel enem pin PWM
STM8: 8 RGB LED ing telung pin, interrupts

Penafian: Aku dudu insinyur, aku ora pura-pura duwe kawruh sing jero babagan elektronik, artikel kasebut ditujukan kanggo para amatir kaya aku. Nyatane, aku nganggep aku rong taun kepungkur minangka target pamirsa. Yen ana wong sing ngandhani yen lembar data ing chip sing ora dingerteni ora medeni diwaca, aku ora bakal ngenteni akeh wektu kanggo nggoleki sawetara potongan kode ing Internet lan nyiptakake kruk nganggo gunting lan tape adesif.

Fokus artikel iki yaiku ing lembar data, dudu proyek, mula kode kasebut bisa uga ora rapi lan asring sempit. Proyèk dhewe banget prasaja, sanajan cocok kanggo kenalan pisanan karo chip anyar.

Muga-muga artikelku bakal nulungi wong ing tahap kecemplung sing padha ing hobi.

STM 32

16 LED karo DM634 lan SPI

Proyek cilik nggunakake Pil Biru (STM32F103C8T6) lan driver LED DM634. Nggunakake lembar data, kita bakal nemtokake driver, port STM IO lan ngatur SPI.

DM634

chip Taiwanese karo 16 16-dicokot PWM output, bisa disambungake ing rentengan. Model 12-bit low-end dikenal saka proyek domestik Paket ringan. Ing sawijining wektu, milih antarane DM63x lan TLC5940 sing kondhang, aku milih DM amarga sawetara alasan: 1) TLC ing Aliexpress mesthi palsu, nanging iki ora; 2) DM nduweni PWM otonom kanthi generator frekuensi dhewe; 3) bisa dituku kanthi murah ing Moskow, tinimbang ngenteni bingkisan saka Ali. Lan, mesthi, iku menarik kanggo sinau carane ngontrol chip dhewe, tinimbang nggunakake perpustakaan siap-digawe. Kripik saiki utamané diwenehi ing paket SSOP24; padha gampang solder menyang adaptor.

Amarga pabrikan iku wong Taiwan, lembar data chip ditulis ing Cina Inggris, kang tegese bakal nyenengake. Pisanan kita ndeleng pinout (Sambungan Pin) kanggo mangerteni sikil sing arep disambungake, lan katrangan saka pin (Katrangan Pin). 16 pin:

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8
Sumber Sink DC (Open Drain)

Sink / Output saluran mbukak - saluran; sumber arus mlebu; output disambungake menyang lemah ing negara aktif - LED disambungake menyang driver dening cathodes. Secara listrik, iki, mesthi, dudu "saluran sing mbukak" (mbukak saluran), nanging ing lembar data asring ditemokake sebutan kanggo pin ing mode saluran.

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8
Resistor eksternal antarane REXT lan GND kanggo nyetel nilai saiki output

Resistor referensi dipasang ing antarane pin REXT lan lemah, sing ngontrol resistensi internal output, deleng grafik ing kaca 9 lembar data. Ing DM634, resistance iki uga bisa dikontrol dening piranti lunak, nyetel padhange sakabèhé (padhange global); Aku ora bakal nerangake rincian ing artikel iki, aku mung bakal sijine resistor 2.2 - 3 kOhm kene.

Kanggo ngerti carane ngontrol chip, ayo kang katon ing gambaran saka antarmuka piranti:

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8

Ya, iki, Inggris Cina ing kabeh kamulyan. Nerjemahake masalah iki, sampeyan bisa ngerti yen pengin, nanging ana cara liya - deleng carane sambungan menyang TLC5940 sing padha karo fungsi kasebut diterangake ing lembar data:

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8
... Mung telung pin sing dibutuhake kanggo ngetik data menyang piranti. Sinyal munggah saka sinyal SCLK mindhah data saka pin SIN menyang register internal. Sawise kabeh data wis dimuat, sinyal XLAT dhuwur cendhak latches data sequentially ditransfer menyang ndhaftar internal. Register internal minangka gerbang sing dipicu dening level sinyal XLAT. Kabeh data ditularaké dicokot paling pinunjul pisanan.

Latch - kancing / kancing / kunci.
Rising edge - pinggir utama pulsa
MSB pisanan – paling pinunjul (paling kiwa) dicokot maju.
kanggo data jam - ngirim data kanthi urutan (bit by bit).

tembung latch asring ditemokake ing dokumentasi kanggo Kripik lan diterjemahake kanthi macem-macem cara, mula kanggo pangerten aku bakal ngidini aku

program pendidikan cilikDriver LED ateges register shift. "Ngalih" (shift) ing jeneng - bitwise gerakan data nang piranti: saben dicokot anyar shoved nang nyurung kabeh chain maju ing ngarepe. Amarga ora ana sing pengin mirsani kedhip-kedip LED sing kacau sajrone shift, proses kasebut ditindakake ing register buffer sing dipisahake saka register kerja kanthi damper (latch) minangka jinis ruang tunggu ing ngendi bit disusun miturut urutan sing dikarepake. Yen kabeh wis siyap, rana mbukak lan bit bisa digunakake, ngganti kumpulan sadurunge. Tembung latch ing dokumentasi kanggo microcircuits meh tansah gawe katut damper kuwi, ora ketompo apa kombinasi digunakake.

Dadi, transfer data menyang DM634 ditindakake kaya mangkene: nyetel input DAI menyang nilai bit paling pinunjul saka LED sing adoh, narik DCK munggah lan mudhun; nyetel input DAI menyang Nilai saka dicokot sabanjuré, narik DCK; lan sateruse nganti kabeh bit wis dikirim (jam ing), sawise kita narik LAT. Iki bisa ditindakake kanthi manual (bit-bang), nanging luwih becik nggunakake antarmuka SPI sing dirancang khusus kanggo iki, amarga ditampilake ing STM32 ing rong salinan.

Pil Biru STM32F103

Pambuka: Pengontrol STM32 luwih rumit tinimbang Atmega328 tinimbang sing katon medeni. Menapa malih, kanthi alesan ngirit energi, meh kabeh peripheral dipateni ing wiwitan, lan frekuensi jam 8 MHz saka sumber internal. Begjanipun, programer STM wrote kode sing ndadekke chip nganti "diwilang" 72 MHz, lan penulis kabeh IDE aku ngerti klebu ing prosedur initialization, supaya kita ora perlu jam (nanging sampeyan bisa yen sampeyan pengin). Nanging sampeyan kudu nguripake peripheral.

Dokumentasi: Pil Biru dilengkapi chip STM32F103C8T6 sing populer, ana rong dokumen sing migunani:

Ing lembar data kita bisa uga kasengsem ing:

  • Pinouts - chip pinouts - yen kita arep nggawe papan dhewe;
  • Peta memori - peta memori kanggo chip tartamtu. Manual Referensi duwe peta kanggo kabeh baris, lan kasebut ndhaptar sing ora duwe.
  • Tabel Definisi Pin - nyathet fungsi utama lan alternatif saka pin; kanggo "pil biru" sampeyan bisa nemokake gambar sing luwih trep ing Internet kanthi dhaptar pin lan fungsine. Mulane, kita langsung google Blue Pill pinout lan nyimpen gambar iki ing tangan:

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8
NB: ana kesalahan ing gambar saka Internet, sing dicathet ing komentar, matur nuwun. Gambar kasebut wis diganti, nanging iki minangka pelajaran - luwih becik mriksa informasi ora saka lembar data.

Kita mbusak lembar data, bukak Manual Referensi, lan wiwit saiki mung digunakake.
Prosedur: kita menehi hasil karo input / output standar, ngatur SPI, nguripake peripheral perlu.

Input Output

Ing Atmega328, I / O diimplementasikake kanthi gampang, mula akeh pilihan STM32 bisa mbingungake. Saiki kita mung butuh kesimpulan, nanging iki duwe papat pilihan:

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8
mbukak saluran, push-narik, alternatif push-narik, alternatif mbukak saluran

"Pull-push" (push-narik) punika output biasanipun saka Arduino, pin bisa njupuk Nilai salah siji HIGH utawa LOW. Nanging karo "mbukak saluran" ana kangelan, sanajan nyatane kabeh prasaja ing kene:

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8
Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8
Konfigurasi output / nalika port ditugasake kanggo output: / buffer output diaktifake: / - mode saluran mbukak: "0" ing register output mbisakake N-MOS, "1" ing register output ninggalake port ing mode Hi-Z ( P-MOS ora diaktifake ) / - mode push-pull: "0" ing register output ngaktifake N-MOS, "1" ing register output ngaktifake P-MOS.

Kabeh prabédan antarane saluran mbukak (mbukak saluran) saka "push-pull" (push-narik) yaiku yen ing pin pisanan ora bisa nampa negara HIGH: nalika nulis siji menyang register output, dadi mode resistance dhuwur (impedansi dhuwur, Hi-Z). Nalika nulis nul, pin tumindak padha ing loro mode, loro logis lan elektrik.

Ing mode output normal, pin mung nyebarake isi register output. Ing "alternatif" dikontrol dening peripheral sing cocog (pirsani 9.1.4):

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8
Yen bit port diatur minangka pin fungsi sulih, ndhaftar pin dipatèni lan pin disambungake menyang pin peripheral.

Fungsi alternatif saben pin diterangake ing Definisi Pin Lembar data ana ing gambar sing diundhuh. Kanggo pitakonan apa sing kudu ditindakake yen pin duwe sawetara fungsi alternatif, jawaban diwenehi cathetan sikil ing lembar data:

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8
Yen sawetara peripheral nggunakake pin padha, supaya konflik antarane fungsi alternatif, mung siji peripheral kudu digunakake ing wektu, toggled nggunakake jam peripheral ngaktifake bit (ing RCC register cocok).

Pungkasan, pin ing mode output uga duwe kacepetan jam. Iki minangka fitur hemat energi liyane; ing kasus kita, kita mung nyetel maksimal lan lali.

Dadi: kita nggunakake SPI, tegese loro pin (kanthi data lan sinyal jam) kudu "fungsi push-pull alternatif", lan siji liyane (LAT) kudu "push-pull biasa". Nanging sadurunge ditugasake, ayo ditangani karo SPI.

SPI

Program pendidikan cilik liyane

SPI utawa Serial Peripheral Interface (antarmuka peripheral serial) punika antarmuka prasaja lan banget efektif kanggo nyambungake MK karo MK liyane lan donya njaba umume. Prinsip operasi kasebut wis diterangake ing ndhuwur, babagan driver LED Cina (ing manual referensi, deleng bagean 25). SPI bisa digunakake ing mode master ("master") lan slave ("slave"). SPI duwe papat saluran dhasar, sing ora kabeh bisa digunakake:

  • MOSI, Output Master / Input Budak: pin iki ngirimake data ing mode master, lan nampa data ing mode budak;
  • MISO, Master Input / Slave Output: ing nalisir, iku ditampa ing master, lan ngirim ing abdi;
  • SCK, Jam Serial: nyetel frekuensi transmisi data ing master utawa nampa sinyal jam ing abdi. Ateges ngengingi ngalahaken;
  • SS, Slave Select: kanthi bantuan saluran iki, budak ngerti yen ana sing dikarepake saka dheweke. Ing STM32 diarani NSS, ing ngendi N = negatif, yaiku. controller dadi abdi yen ana lemah ing saluran iki. Digabungake kanthi apik karo mode Open Drain Output, nanging iki crita liyane.

Kaya kabeh liyane, SPI ing STM32 sugih ing fungsi, kang ndadekake iku rada angel kanggo ngerti. Contone, bisa digunakake ora mung karo SPI, nanging uga karo antarmuka I2S, lan ing dokumentasi gambaran sing pipis, iku perlu kanggo Cut mati keluwihan ing proses pas wektune. Tugas kita gampang banget: kita mung kudu ngirim data mung nggunakake MOSI lan SCK. Kita pindhah menyang bagean 25.3.4 (komunikasi setengah dupleks, komunikasi setengah dupleks), ing ngendi kita nemokake 1 jam lan 1 kabel data unidirectional (1 sinyal jam lan 1 aliran data searah):

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8
Ing mode iki, aplikasi nggunakake SPI ing mode ngirim utawa mung nampa. / Mode mung ngirim padha karo mode duplex: data dikirim ing pin ngirim (MOSI ing mode master utawa MISO ing mode budak), lan pin nampa (MISO utawa MOSI mungguh) bisa digunakake minangka I / O pin biasa. . Ing kasus iki, aplikasi mung kudu nglirwakake buffer Rx (yen diwaca, ora bakal ana data sing ditransfer ing kana).

Apik, PIN MISO gratis, ayo nyambungake sinyal LAT. Ayo katon ing Slave Select, sing ing STM32 bisa dikontrol kanthi program, sing trep banget. Kita maca paragraf kanthi jeneng sing padha ing bagean 25.3.1 Deskripsi Umum SPI:

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8
Kontrol piranti lunak NSS (SSM = 1) / Informasi pilihan budak sing ana ing bit SSI saka register SPI_CR1. Pin NSS eksternal tetep gratis kanggo kabutuhan aplikasi liyane.

Iku wektu kanggo nulis menyang ndhaftar. Aku mutusake nggunakake SPI2, goleki alamat dhasar ing lembar data - ing bagean 3.3 Peta Memori:

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8

Inggih, ayo miwiti:

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

Bukak bagean 25.3.3 kanthi judhul sing jelas "Konfigurasi SPI ing Mode Master":

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8

1. Setel frekuensi jam serial karo bit BR [2: 0] ing SPI_CR1 register.

Register diklumpukake ing bagean manual referensi kanthi jeneng sing padha. Ngalih alamat (Alamat offset) kanggo CR1 – 0x00, kanthi standar kabeh bit dibusak (Reset nilai 0x0000):

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8

Bit BR nyetel divider jam controller, saéngga nemtokake frekuensi ing SPI bakal operate. Frekuensi STM32 kita bakal dadi 72 MHz, driver LED, miturut lembar data, beroperasi kanthi frekuensi nganti 25 MHz, mula kita kudu dibagi dadi papat (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 lan CPHA kanggo nemtokake hubungan antarane transfer data lan wektu jam serial (ndeleng diagram ing kaca 240)

Awit kita lagi maca lembar data ing kene lan ora ndeleng skema, ayo deleng katrangan teks bit CPOL lan CPHA ing kaca 704 (SPI Katrangan Umum):

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8
Fase jam lan polaritas
Nggunakake CPOL lan CPHA bit saka SPI_CR1 register, sampeyan bisa programmatically milih papat sesambetan wektu. Bit CPOL (polaritas jam) ngontrol kahanan sinyal jam nalika ora ana data sing dikirim. Bit iki ngontrol mode master lan slave. Yen CPOL direset, pin SCK kurang ing mode istirahat. Yen bit CPOL disetel, pin SCK dhuwur nalika mode istirahat.
Nalika CPHA (fase jam) dicokot disetel, dhuwur dicokot sworo seru strobo pinggiran kapindho sinyal SCK (mudhun yen CPOL cetha, munggah yen CPOL disetel). Data kasebut dijupuk kanthi owah-owahan kapindho ing sinyal jam. Yen CPHA dicokot cetha, dhuwur dicokot trap strobe iku Rising pinggiran sinyal SCK (mudhun pinggiran yen CPOL disetel, Rising pinggiran yen CPOL wis dibusak). Data dijupuk nalika owah-owahan pisanan ing sinyal jam.

Duwe digunakke kawruh iki, kita teka menyang kesimpulan sing loro bit kudu tetep nul, amarga Kita pengin sinyal SCK tetep sithik nalika ora digunakake, lan data bakal dikirim ing pinggir pulsa sing mundhak (pirsani Fig. Rising Edge ing lembar data DM634).

Miturut cara, ing kene pisanan kita nemoni fitur kosakata ing lembar data ST: ana tembung "reset bit menyang nol" ditulis. kanggo ngreset dicokot, lan ora kanggo mbusak dicokot, kaya, contone, Atmega.

3. Setel bit DFF kanggo nemtokake apa blok data format 8-bit utawa 16-bit

Aku khusus njupuk DM16 634-dicokot supaya ora keganggu ngirim data PWM 12-dicokot, kaya DM633. Iku masuk akal kanggo nyetel DFF dadi siji:

#define DFF         0x0800

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

4. Ngatur bit LSBFIRST ing SPI_CR1 register kanggo nemtokake format pemblokiran

LSBFIRST, minangka jeneng tabet, configures transmisi karo dicokot paling pinunjul pisanan. Nanging DM634 pengin nampa data wiwit saka dicokot paling pinunjul. Mulane, kita ninggalake iku reset.

5. Ing mode hardware, yen input saka pin NSS dibutuhake, aplikasi sinyal dhuwur kanggo pin NSS sak kabeh urutan transfer byte. Ing mode piranti lunak NSS, setel bit SSM lan SSI ing register SPI_CR1. Yen pin NSS digunakake minangka output, mung bit SSOE sing kudu disetel.

Instal SSM lan SSI kanggo lali babagan mode hardware NSS:

#define SSI         0x0100
#define SSM         0x0200

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

6. Bit MSTR lan SPE kudu disetel (padha tetep disetel mung yen sinyal NSS dhuwur)

Bener, kanthi bit iki kita nemtokake SPI minangka master lan nguripake:

#define MSTR        0x0004
#define SPE         0x0040

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

SPI dikonfigurasi, ayo langsung nulis fungsi sing ngirim bita menyang driver. Terus maca 25.3.3 "Konfigurasi SPI ing mode master":

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8
Urutan transfer data
Transmisi diwiwiti nalika bait ditulis menyang buffer Tx.
Byte data dimuat menyang register shift ing sejajar mode (saka bis internal) sak transmisi bit pisanan, sawise kang ditularaké kanggo urut-urutan mode PIN MOSI, pisanan utawa pungkasan dicokot maju gumantung setelan bit LSBFIRST ing CPI_CR1 register. Gendéra TXE disetel sawise transmisi data saka Tx buffer kanggo shift register, lan uga njedulake gangguan yen dicokot TXEIE ing CPI_CR1 register disetel.

Aku nyorot sawetara tembung ing terjemahan kanggo narik kawigaten marang siji fitur saka implementasi SPI ing pengontrol STM. Ing Atmega bendera TXE (Tx Kosong, Tx kosong lan siap nampa data) disetel mung sawise kabeh byte wis dikirim njaba. Lan ing kene gendera iki disetel sawise bait wis dilebokake menyang register shift internal. Wiwit di-push ana karo kabeh bit ing wektu sing padha (ing podo karo), lan banjur data ditransfer sequentially, TXE disetel sadurunge bait rampung dikirim. Iki penting amarga ing kasus driver LED kita, kita kudu narik pin LAT sawise ngirim всех data, i.e. Gendéra TXE piyambak ora bakal cukup kanggo kita.

Iki tegese kita kudu gendéra liyane. Ayo ndeleng 25.3.7 - "Flag Status":

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8
<…>
Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8
bendera SIBUK
Gendéra BSY disetel lan diresiki dening hardware (nulis ora ana pengaruhe). Gendéra BSY nuduhake kahanan lapisan komunikasi SPI.
Iki ngreset:
nalika transfer rampung (kajaba ing mode master yen transfer terus-terusan)
nalika SPI dipatèni
nalika ana kesalahan mode master (MODF=1)
Yen transfer ora terus-terusan, bendera BSY dibusak ing antarane saben transfer data

Oke, iki bakal migunani. Ayo goleki ngendi buffer Tx dumunung. Kanggo nindakake iki, waca "Data Register SPI":

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8
Bits 15:0 DR[15:0] Data Register
Data sing ditampa utawa data sing bakal dikirim.
Register data dipérang dadi rong buffer - siji kanggo nulis (transmit buffer) lan siji kanggo maca (nampa buffer). Nulis kanggo ndhaftar data nulis menyang Tx buffer, lan maca saka ndhaftar data bakal bali Nilai sing ana ing Rx buffer.

Inggih, lan ndhaftar status, ing ngendi bendera TXE lan BSY ditemokake:

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8

Kita 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
}

Ya, amarga kita kudu ngirim 16 kaping rong bita, miturut jumlah output driver LED, kaya iki:

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();
}

Nanging kita durung ngerti carane narik pin LAT, supaya kita bakal bali menyang I / O.

Nemtokake pin

Ing STM32F1, ndhaftar tanggung jawab kanggo negara pin cukup mboten umum. Cetha yen ana luwih akeh tinimbang Atmega, nanging uga beda karo chip STM liyane. Bagian 9.1 Deskripsi Umum GPIO:

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8
Saben port I / O tujuan umum (GPIO) wis rong registrasi konfigurasi 32-dicokot (GPIOx_CRL lan GPIOx_CRH), rong ndhaftar data 32-dicokot (GPIOx_IDR lan GPIOx_ODR), 32-dicokot set / reset register (GPIOx_BSRR), 16-dicokot ndhaftar ulang (GPIOx_BRR) lan 32- register pemblokiran bit (GPIOx_LCKR).

Rong ndhaptar pisanan ora biasa, lan uga ora trep, amarga 16 pin port kasebar ing format "papat bit saben sadulur". Sing. pin nul kanggo pitu ing CRL, lan liyane ing CRH. Ing wektu sing padha, ndhaptar sing isih kasil ngemot bit kabeh pin port - asring isih setengah "diundhuh".

Kanggo gamblang, ayo miwiti saka mburi dhaftar.

Kita ora butuh register pamblokiran.

Set lan reset ndhaptar cukup lucu amarga padha sebagian duplikat saben liyane: sampeyan bisa nulis kabeh mung ing BSRR, endi sing luwih dhuwur 16 bit bakal ngreset pin menyang nul, lan ngisor bakal disetel kanggo 1, utawa sampeyan bisa uga. nggunakake BRR, ing ngisor 16 bit kang mung ngreset pin. Aku seneng pilihan kapindho. Register iki penting amarga menehi akses atom menyang pin:

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8
Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8
Atom Set utawa Reset
Ora perlu mateni interrupts nalika program GPIOx_ODR ing tingkat bit: siji utawa luwih bit bisa diganti karo operasi nulis atom siji APB2. Iki digayuh kanthi nulis "1" menyang ndhaftar set / reset (GPIOx_BSRR utawa, mung kanggo reset, GPIOx_BRR) saka bit sing kudu diganti. Bit liyane bakal tetep ora owah.

Register data duwe jeneng sing cukup jelas - IDR = input Register Arah, register input; ODR = output Register Arah, register output. Kita ora butuh wong-wong mau ing proyek saiki.

Lan pungkasanipun, ndhaftar kontrol. Awit kita kasengsem ing pin SPI kapindho, yaiku PB13, PB14 lan PB15, kita langsung ndeleng CRH:

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8

Lan kita weruh yen kita kudu nulis soko ing bit saka 20 kanggo 31.

Kita wis figured metu ndhuwur apa kita arep saka pin, supaya kene aku bakal nindakake tanpa gambar, Aku mung bakal ngomong sing MODE nemtokake arah (input yen loro bit disetel kanggo 0) lan kacepetan pin (kita kudu 50MHz, i.e. loro pin kanggo "1"), lan CNF nyetel mode: biasa "push-narik" - 00, "alternatif" - 10. Kanthi gawan, minangka kita waca ndhuwur, kabeh lencana duwe dicokot katelu saka ngisor (CNF0), iku mranata menyang mode input ngambang.

Awit aku rencana kanggo nindakake soko liyane karo chip iki, kanggo gamblang aku wis ditetepake kabeh bisa Nilai MODE lan CNF kanggo loro ndhaftar kontrol ngisor lan ndhuwur.

Piye carane iki

#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 kita ana ing port B (alamat dhasar - 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;

Lan, kanthi mangkono, sampeyan bisa nulis definisi kanggo LAT, sing bakal dicekel dening registrasi BRR lan 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 mung kanthi inersia, mesthi kaya ngono, ayo tetep)

Saiki kabeh apik, nanging ora bisa. Amarga iki STM32, padha ngirit listrik, tegese sampeyan kudu ngaktifake clocking peripheral sing dibutuhake.

Nguripake jam

Jam, uga dikenal minangka Jam, tanggung jawab kanggo jam. Lan kita wis bisa ngerteni singkatan RCC. Kita goleki ing dokumentasi: iki Reset lan Kontrol Jam.

Kaya sing kasebut ing ndhuwur, untunge, bagean sing paling angel babagan topik jam wis ditindakake dening wong-wong saka STM, sing kita matur nuwun kanthi sanget (sepisan maneh aku bakal menehi link menyang situs web Di Halt, kanggo nerangake carane bingung iku). Kita mung butuh ndhaptar sing tanggung jawab kanggo ngaktifake jam periferal (Jam Peripheral Enable Register). Pisanan, ayo golek alamat dhasar RCC, yaiku ing wiwitan "Peta Memori":

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8

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

Banjur klik ing link ing ngendi sampeyan nyoba golek soko ing piring, utawa, luwih apik, bukak katrangan saka ndhaptar sing bisa digunakake saka bagean babagan ngaktifake ndhaftar. Ing ngendi kita bakal nemokake RCC_APB1ENR lan RCC_APB2ENR:

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8
Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8

Lan padha, miturut, ngemot bit sing kalebu clocking SPI2, IOPB (I / O Port B) lan 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 pungkasan bisa ditemokake kene.

Yen sampeyan duwe kesempatan lan kepinginan kanggo nyoba, sambungake DM634 kaya iki: DAI menyang PB15, DCK menyang PB13, LAT menyang PB14. We daya driver saka 5 volt, aja lali kanggo nyambungake latar.

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8

STM8 PWM

PWM ing STM8

Nalika aku mung ngrancang artikel iki, aku mutusake, minangka conto, kanggo nyoba nguwasani sawetara fungsi saka chip sing ora pati ngerti nggunakake mung lembar data, supaya aku ora bakal dadi tukang sepatu tanpa sepatu bot. STM8 becik kanggo peran iki: sepisanan, aku duwe saperangan Papan Cina karo STM8S103, lan sareh, iku ora banget populer, lan mulane nggodha kanggo maca lan nemokake solusi ing Internet dumunung ing lack saka solusi iki banget.

Chip uga duwe lembar data и manual referensi RM0016, ing pisanan ana pinout lan ndhaftar alamat, ing kaloro - kabeh liya. STM8 wis diprogram ing C ing IDE elek Pangembangan Visual ST.

Clocking lan I/O

Kanthi gawan, STM8 beroperasi ing frekuensi 2 MHz, iki kudu didandani langsung.

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8
Jam HSI (High Speed ​​Internal).
Sinyal jam HSI asalé saka internal 16 MHz RC osilator karo divider programmable (1 kanggo 8). Iki disetel ing register divider jam (CLK_CKDIVR).
Cathetan: ing wiwitan, osilator RC HSI kanthi divider 8 dipilih minangka sumber sinyal jam.

Kita nemokake alamat registrasi ing lembar data, katrangan ing refman lan ndeleng manawa registrasi kudu dibusak:

#define CLK_CKDIVR *(volatile uint8_t *)0x0050C6

CLK_CKDIVR &= ~(0x18);

Awit kita bakal mbukak PWM lan nyambungake LED, ayo goleki pinout:

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8

Chip punika cilik, akeh fungsi sing dilereni soko tugas ing pin padha. Sing ana ing kurung kothak yaiku "fungsi alternatif", diowahi kanthi "byte pilihan" (pilihan byte) - kaya Atmega sekring. Sampeyan bisa ngganti nilai sing programmatically, nanging ora perlu, amarga Fungsi anyar diaktifake mung sawise urip maneh. Iku luwih gampang nggunakake ST Visual Programmer (diundhuh karo Visual Develop), sing bisa ngganti bait iki. Pinout nuduhake yen CH1 lan CH2 pin saka timer pisanan didhelikake ing kurung kothak; iku perlu kanggo nyetel AFR1 lan AFR0 bit ing STVP, lan kaloro uga bakal nransfer output CH1 saka timer kapindho saka PD4 kanggo PC5.

Mangkono, 6 pin bakal ngontrol LED: PC6, PC7 lan PC3 kanggo timer pisanan, PC5, PD3 lan PA3 kanggo kaloro.

Nyiyapake pin I/O dhewe ing STM8 luwih gampang lan luwih logis tinimbang ing STM32:

  • akrab saka register arah data DDR Atmega (Daftar Arah Data): 1 = output;
  • kontrol pisanan ndhaftar CR1, nalika output, nyetel mode push-narik (1) utawa mbukak saluran (0); wiwit aku nyambung LED kanggo chip karo cathodes, Aku ninggalake zeros kene;
  • kontrol kapindho ndhaftar CR2, nalika output, nyetel kacepetan 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

Setelan PWM

Pisanan, ayo nemtokake istilah kasebut:

  • Frekuensi PWM - frekuensi karo wektu ticks;
  • Isi ulang otomatis, AR - Nilai autoloadable nganti wektu sing bakal diitung (periode pulsa);
  • Update Acara, UEV - acara sing kedadeyan nalika timer wis diitung menyang AR;
  • Siklus Tugas PWM - Siklus tugas PWM, asring disebut "faktor tugas";
  • Njupuk / mbandhingaké Nilai – Nilai kanggo dijupuk / mbandhingake, sing wektu wis diitung bakal nindakake soko (ing kasus PWM, ngowahi sinyal output);
  • Nilai Preload - Nilai sing wis dimuat. Bandingake nilai ora bisa ngganti nalika timer ticking, yen siklus PWM bakal break. Mulane, nilai sing ditularake anyar diselehake ing buffer lan ditarik metu nalika wektu tekan mburi countdown lan direset;
  • Edge-aligned и Mode selaras tengah - Alignment ing sadawane tapel wates lan ing tengah, padha karo Atmel PWM Cepet и PWM fase-bener.
  • OCiREF, Output Bandingake Referensi Sinyal - sinyal output referensi, nyatane, apa sing katon ing pin sing cocog ing mode PWM.

Kaya sing wis jelas saka pinout, loro timer duwe kemampuan PWM - pisanan lan kaloro. Loro-lorone 16-bit, sing pisanan nduweni akeh fitur tambahan (utamane, bisa ngetung munggah lan mudhun). We kudu loro kanggo bisa merata, supaya aku mutusaké kanggo miwiti karo temenan mlarat liya, supaya dadi ora sengaja nggunakake soko sing ora ana. Sawetara masalah iku gambaran saka fungsi PWM kabeh timers ing manual referensi ing bab bab timer pisanan (17.5.7 PWM Mode), supaya sampeyan kudu mlumpat bali lan kasebut ing saindhenging document kabeh wektu.

PWM ing STM8 nduweni kauntungan penting tinimbang PWM ing Atmega:

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8
Boundary Aligned PWM
Konfigurasi akun saka ngisor menyang ndhuwur
Ngisor-up pancacahan aktif yen dicokot DIR ing TIM_CR1 register wis dibusak
Conto:
Conto nggunakake mode PWM pisanan. Sinyal referensi PWM OCiREF dicekel dhuwur anggere TIM1_CNT < TIM1_CCRi. Yen ora, butuh tingkat sing kurang. Yen nilai perbandingan ing register TIM1_CCRi luwih gedhe tinimbang nilai autoload (registrasi TIM1_ARR), sinyal OCiREF ditahan ing 1. Yen nilai comparison 0, OCiREF dianakaké ing nul....

Timer STM8 sajrone nganyari acara mriksa dhisik mbandhingaké Nilai, lan mung banjur ngasilake sinyal referensi. Timer Atmega pisanan ngawut-awut banjur mbandhingake, asile compare value == 0 output punika jarum, kang kudu urusan karo piye wae (contone, dening programmatically kuwalik logika).

Dadi apa sing arep kita lakoni: 8-bit PWM (AR == 255), ngetang saka ngisor menyang ndhuwur, alignment ing sadawane wates. Wiwit bolam lampu disambungake menyang chip kanthi katoda, PWM kudu ngasilake 0 (LED on) nganti mbandhingaké Nilai lan 1 sawise.

Kita wis maca babagan sawetara Mode PWM, supaya kita nemokake registrasi sing dibutuhake kanggo wektu kapindho kanthi nggoleki ing manual referensi kanggo frasa iki (18.6.8 - TIMx_CCMR1):

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8
110: Mode PWM pisanan - nalika ngetang saka ngisor menyang ndhuwur, saluran pisanan aktif nalika TIMx_CNT <TIMx_CCR1. Yen ora, saluran pisanan ora aktif. [luwih ing dokumen ana salinan-tempel sing salah saka timer 1] 111: Mode PWM kapindho - nalika ngetang saka ngisor menyang ndhuwur, saluran pisanan ora aktif nalika TIMx_CNT < TIMx_CCR1. Yen ora, saluran pisanan aktif.

Wiwit LED disambungake menyang MK dening cathodes, mode kapindho cocog karo kita (sing pisanan uga, nanging kita durung ngerti).

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8
Bit 3 OC1PE: Aktifake pramuat pin 1
0: Register pramuat ing TIMx_CCR1 dipateni. Sampeyan bisa nulis menyang TIMx_CCR1 sawayah-wayah. Nilai anyar bisa langsung.
1: Register pramuat ing TIMx_CCR1 diaktifake. Operasi maca/nulis ngakses daftar pramuat. Nilai TIMx_CCR1 sing wis dimuat sadurunge dimuat menyang registrasi bayangan sajrone saben acara nganyari.
* Cathetan: Supaya mode PWM bisa mlaku kanthi bener, daftar pramuat kudu diaktifake. Iki ora perlu ing mode sinyal siji (bit OPM disetel ing register TIMx_CR1).

Oke, ayo nguripake kabeh sing dibutuhake kanggo telung saluran timer kapindho:

#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 kasusun saka rong register wolung bit, kabeh iku prasaja:

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

TIM2_ARRH = 0;
TIM2_ARRL = 255;

Timer kaping pindho mung bisa ngetung saka ngisor nganti ndhuwur, alignment ing wates, ora ana sing kudu diganti. Ayo nyetel divider frekuensi, contone, kanggo 256. Kanggo wektu kapindho, divider disetel ing register TIM2_PSCR lan daya saka loro:

#define TIM2_PSCR  *(volatile uint8_t *)0x00530E

TIM2_PSCR = 8;

Kabeh sing isih ana yaiku nguripake kesimpulan lan timer kapindho dhewe. Masalah pisanan ditanggulangi dening ndhaftar Jupuk / Bandingake Aktifake: ana loro, telung saluran sing kasebar ing asymmetrically. Ing kene kita uga bisa sinau manawa bisa ngganti polaritas sinyal kasebut, yaiku. ing asas, iku bisa kanggo nggunakake PWM Mode 1. Kita 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;

Lan pungkasane, kita miwiti timer ing register TIMx_CR1:

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8

#define TIM2_CR1   *(volatile uint8_t *)0x005300

TIM2_CR1 |= 1;

Ayo nulis analog prasaja saka AnalogWrite (), sing bakal nransfer nilai nyata menyang timer kanggo mbandhingake. Register kasebut dijenengi prediksi Njupuk / Bandingake ndhaftar, ana loro kanggo saben saluran: 8 bit urutan rendah ing TIM2_CCRxL lan urutan dhuwur ing TIM2_CCRxH. Amarga kita wis nggawe PWM 8-bit, cukup nulis mung bit sing paling ora penting:

#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;
}

Sing maca enten bakal sok dong mirsani sing kita duwe PWM rada risak, ora bisa kanggo gawé 100% isi (ing Nilai maksimum 255, sinyal kuwalik kanggo siji siklus wektu). Kanggo LED iki ora Matter, lan maca enten wis bisa guess carane ndandani.

PWM ing timer kapindho dianggo, ayo pindhah menyang pisanan.

Timer pisanan nduweni bit sing padha ing register sing padha (mung bit sing tetep "dicadhangake" ing timer kapindho aktif digunakake ing sing pisanan kanggo kabeh perkara sing luwih maju). Mulane, cukup kanggo nemokake alamat register sing padha ing lembar data lan nyalin kode kasebut. Inggih, ngganti nilai pembagi frekuensi, amarga ... wektu pisanan pengin nampa ora daya saka loro, nanging nilai pas 16-dicokot ing rong ndhaftar Prescaler Dhuwur и kurang. Kita nindakake kabeh lan ... timer pisanan ora bisa. Ana apa?

Masalah kasebut mung bisa ditanggulangi kanthi ndeleng kabeh bagean babagan ndhaptar kontrol timer 1, ing ngendi kita nggoleki sing ora ana ing timer kapindho. bakal ana 17.7.30 Register istirahat (TIM1_BKR), ngendi ana bit iki:

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8
Aktifake output utama

#define TIM1_BKR   *(volatile uint8_t *)0x00526D

TIM1_BKR = (1<<7);

Sing kabeh mesthi saiki, kode ing kono.

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8

STM8 Multiplex

Multiplexing ing STM8

Proyek mini katelu yaiku nyambungake wolung LED RGB menyang timer kapindho ing mode PWM lan nggawe warna sing beda-beda. Iki adhedhasar konsep multiplexing LED, yaiku yen sampeyan ngaktifake lan mateni LED kanthi cepet banget, mula kita bakal katon terus-terusan (keteguhan sesanti, inersia persepsi visual). Aku tau kaya iki ing Arduino.

Algoritma kerja katon kaya iki:

  • disambungake anode saka LED RGB pisanan;
  • surem, ngirim sinyal sing perlu kanggo cathodes;
  • ngenteni nganti pungkasan siklus PWM;
  • disambungake anode saka LED RGB kapindho;
  • nyalane...

Inggih, lsp. Mesthine, kanggo operasi sing apik, anode disambungake lan LED "dipencet" ing wektu sing padha. Inggih, utawa meh. Ing kasus apa wae, kita kudu nulis kode sing bakal ngasilake nilai ing telung saluran saka timer kapindho, ngganti nalika UEV wis tekan, lan ing wektu sing padha ngganti LED RGB aktif.

Wiwit ngoper LED otomatis, kita kudu nggawe "memori video" saka kang interrupted handler bakal nampa data. Iki minangka array prasaja:

uint8_t colors[8][3];

Kanggo ngganti warna LED tartamtu, cukup kanggo nulis nilai sing dibutuhake ing array iki. Lan variabel bakal tanggung jawab kanggo nomer LED aktif

uint8_t cnt;

Demux

Kanggo multiplexing sing tepat, kita butuh, cukup aneh, demultiplexer CD74HC238. Demultiplexer - chip sing ngleksanakake operator ing hardware <<. Liwat telung pin input (bit 0, 1 lan 2) kita menehi feed dadi nomer telu-bit X, lan minangka respon ngaktifake nomer output (1<<X). Input chip sing isih digunakake kanggo ukuran kabeh desain. Kita butuh chip iki ora mung kanggo nyuda jumlah pin sing dikuwasani mikrokontroler, nanging uga kanggo safety - supaya ora sengaja nguripake LED luwih akeh tinimbang bisa lan ora ngobong MK. Kripik biaya sen lan kudu tansah disimpen ing lemari obat ngarep.

CD74HC238 kita bakal tanggung jawab kanggo nyuplai voltase menyang anoda LED sing dikarepake. Ing multiplex lengkap, bakal nyedhiyakake voltase menyang kolom liwat P-MOSFET, nanging ing demo iki bisa langsung, amarga iku ndudohke 20 mA, miturut ratings maksimum Absolute ing datasheet. saka Lembar data CD74HC238 kita butuh pinout lan sheet cheat iki:

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8
H = tingkat voltase dhuwur, L = tingkat voltase kurang, X - ora peduli

Kita nyambungake E2 lan E1 menyang lemah, E3, A0, A1 lan A3 menyang pin PD5, PC3, PC4 lan PC5 saka STM8. Wiwit tabel ing ndhuwur ngemot tingkat kurang lan dhuwur, kita ngatur pin kasebut minangka pin push-pull.

PWM

PWM ing wektu kapindho dikonfigurasi kanthi cara sing padha kaya ing crita sadurunge, kanthi rong beda:

Kaping pisanan, kita kudu ngaktifake interupsi Update Acara (UEV) sing bakal nelpon fungsi sing mateni LED aktif. Iki rampung kanthi ngganti bit Nganyari Interrupt Aktifake ing ndhaftar karo jeneng ngandhani

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8
Interrupt ngaktifake ndhaptar

#define TIM2_IER   *(volatile uint8_t *)0x005303

//enable interrupt
TIM2_IER = 1;

Bentenipun kapindho ana hubungane karo fenomena multiplexing, kayata memedi - glow parasit saka dioda. Ing kasus kita, bisa uga amarga kasunyatan manawa wektu, sing nyebabake gangguan ing UEV, terus dicenthang, lan panangan interupsi ora duwe wektu kanggo ngalih LED sadurunge timer wiwit nulis soko menyang pin. Kanggo nglawan iki, sampeyan kudu ngowahi logika (0 = padhange maksimum, 255 = ora ana sing surem) lan ngindhari nilai siklus tugas sing ekstrem. Sing. mesthekake yen sawise UEV LED metu rampung kanggo siji siklus PWM.

Ngganti polaritas:

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

Aja nyetel r, g lan b kanggo 255 lan elinga kuwalik nalika digunakake.

interrupts

Inti saka interupsi yaiku yen ing kahanan tartamtu, chip mandheg nglakokake program utama lan nelpon sawetara fungsi eksternal. Interrupts dumadi amarga pengaruh eksternal utawa internal, kalebu timer.

Nalika kita pisanan nggawe proyek ing ST Visual Develop, saliyane main.c kita nampa jendhela karo file misterius stm8_interrupt_vector.c, kanthi otomatis kalebu ing proyek kasebut. Ing berkas iki, sawijining fungsi diutus kanggo saben interupsi NonHandledInterrupt. Kita kudu ngiket fungsi kita menyang interupsi sing dikarepake.

Lembar data nduweni tabel vektor interupsi, ing ngendi kita nemokake sing dibutuhake:

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8
13 nganyari TIM2 / kebanjiran
14 TIM2 dijupuk / mbandhingaké

Kita kudu ngganti LED ing UEV, supaya kita kudu ngganggu #13.

Mulane, pisanan, ing file stm8_interrupt_vector.c ngganti jeneng standar saka fungsi tanggung jawab kanggo ngganggu No.. 13 (IRQ13) kanggo dhewe:

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

Kapindho, kita kudu nggawe file main.h kanthi isi ing ngisor iki:

#ifndef __MAIN_H
#define __MAIN_H

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

Lan pungkasanipun, nulis fungsi iki ing Panjenengan 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;
}

Kabeh sing isih ana yaiku ngaktifake interupsi. Iki rampung nggunakake printah assembler rim - sampeyan kudu nggoleki ing Manual Pemrograman:

//enable interrupts
_asm("rim");

Perintah assembler liyane yaiku sim – mateni interrupts. Dheweke kudu dipateni nalika nilai anyar ditulis ing "memori video", supaya gangguan sing disebabake ing wektu sing salah ora ngrusak array.

Kabeh kode- ing GitHub.

Waca lembar data 2: SPI ing STM32; PWM, timer lan interrupts ing STM8

Yen paling ora ana sing nemokake artikel iki migunani, mula aku ora nulis kanthi sia-sia. Aku bakal seneng nampa komentar lan komentar, aku bakal nyoba mangsuli kabeh.

Source: www.habr.com

Add a comment