Pročitajte podatkovne tablice 2: SPI na STM32; PWM, mjerači vremena i prekidi na STM8
В prvi dio Pokušao sam reći inženjerima hobi elektronike koji su odrasli na Arduino hlačama kako i zašto bi trebali čitati podatkovne tablice i drugu dokumentaciju za mikrokontrolere. Tekst se pokazao velikim, pa sam obećao pokazati praktične primjere u zasebnom članku. Pa on je sebe nazvao mliječnom gljivom...
Danas ću vam pokazati kako koristiti podatkovne tablice za rješavanje prilično jednostavnih, ali potrebnih za mnoge projekte, zadataka na STM32 (Blue Pill) i STM8 kontrolerima. Svi demo projekti posvećeni su mojim omiljenim LED diodama, palit ćemo ih u velikim količinama, za što ćemo morati koristiti razne zanimljive periferije.
Tekst se opet pokazao ogromnim, pa radi praktičnosti izrađujem sadržaj:
Disclaimer: Nisam inženjer, ne pretendiram da imam duboko znanje u elektronici, članak je namijenjen amaterima poput mene. Zapravo, sebe sam prije dvije godine smatrao ciljnom publikom. Da mi je netko tada rekao da podatkovne tablice na nepoznatom čipu nije strašno čitati, ne bih trošio puno vremena tražeći neke dijelove koda na internetu i izmišljajući štake sa škarama i ljepljivom trakom.
Fokus ovog članka je na podatkovnim tablicama, a ne na projektima, tako da kôd možda nije baš uredan i često skučen. Sami projekti su vrlo jednostavni, iako prikladni za prvo upoznavanje s novim čipom.
Nadam se da će moj članak pomoći nekome u sličnoj fazi uranjanja u hobi.
STM32
16 LED s DM634 i SPI
Mali projekt koji koristi Blue Pill (STM32F103C8T6) i DM634 LED drajver. Koristeći podatkovne tablice, otkrit ćemo upravljački program, STM IO portove i konfigurirati SPI.
DM634
Tajvanski čip sa 16 16-bitnih PWM izlaza, može se spajati u lance. Niskobudžetni 12-bitni model poznat je iz domaćeg projekta Lightpack. Svojedobno sam, birajući između DM63x i dobro poznatog TLC5940, odabrao DM iz nekoliko razloga: 1) TLC na Aliexpressu je definitivno fejk, ali ovaj nije; 2) DM ima autonomni PWM s vlastitim generatorom frekvencije; 3) moglo se kupiti jeftino u Moskvi, umjesto da čeka paket od Alija. I, naravno, bilo je zanimljivo naučiti kako sami kontrolirati čip, a ne koristiti gotovu biblioteku. Čipovi su sada uglavnom predstavljeni u paketu SSOP24; lako ih je lemiti na adapter.
Budući da je proizvođač tajvanski, podatkovni list čip je napisan na kineskom engleskom, što znači da će biti zabavno. Prvo gledamo pinout (Pin priključak) kako biste razumjeli na koju nogu spojiti što i opis pinova (Opis pribadače). 16 pinova:
Istosmjerni izvori odvoda (otvoreni odvod)
Umivaonik / Izlaz s otvorenim odvodom – odvod; izvor dotočne struje; izlaz je spojen na masu u aktivnom stanju - LED diode su spojene na drajver katodama. Električno, ovo, naravno, nije "otvoreni odvod" (otvoreni odvod), ali u podatkovnim tablicama često se nalazi ova oznaka za pinove u načinu odvoda.
Vanjski otpornici između REXT i GND za postavljanje vrijednosti izlazne struje
Referentni otpornik instaliran je između pina REXT i mase, koji kontrolira unutarnji otpor izlaza, pogledajte grafikon na stranici 9 podatkovne tablice. U DM634, ovaj otpor također se može kontrolirati softverom, postavljajući ukupnu svjetlinu (globalna svjetlina); Neću ulaziti u detalje u ovom članku, ovdje ću samo staviti otpornik od 2.2 - 3 kOhma.
Da bismo razumjeli kako kontrolirati čip, pogledajmo opis sučelja uređaja:
Da, evo ga, kineski engleski u punom sjaju. Prevođenje ovoga je problematično, možete ga razumjeti ako želite, ali postoji drugi način - pogledajte kako je veza s funkcionalno sličnim TLC5940 opisana u podatkovnoj tablici:
... Za unos podataka u uređaj potrebna su samo tri pina. Uzlazni rub SCLK signala pomiče podatke sa SIN pina na interni registar. Nakon što su svi podaci učitani, kratki visoki XLAT signal zaključava sekvencijalno prenesene podatke u interne registre. Interni registri su vrata aktivirana razinom XLAT signala. Svi podaci se prvo prenose bitovima najvećeg značaja.
reza – zasun/zasun/zasun. Uzlazni rub – vodeći rub pulsa MSB prvi – najznačajniji (krajnji lijevi) bit naprijed. za podatke o satu – slati podatke sekvencijalno (bit po bit).
Riječ reza često se nalazi u dokumentaciji za čipove i prevodi se na razne načine, pa ću si zbog razumijevanja dopustiti
mali obrazovni programLED upravljački program je u biti registar posmaka. "Shift" (smjena) u nazivu - bitovno kretanje podataka unutar uređaja: svaki novi bit gurnut unutra gura cijeli lanac naprijed ispred sebe. Budući da nitko ne želi promatrati kaotično treptanje LED dioda tijekom pomaka, proces se odvija u međuspremničkim registrima odvojenim od radnih registara prigušivačem (reza) je neka vrsta čekaonice u kojoj se bitovi slažu u željenom nizu. Kada je sve spremno, zatvarač se otvara i bitovi počinju raditi, zamjenjujući prethodnu seriju. Riječ reza u dokumentaciji za mikro krugove gotovo uvijek podrazumijeva takav prigušivač, bez obzira u kojim kombinacijama se koristi.
Dakle, prijenos podataka na DM634 provodi se ovako: postavite DAI ulaz na vrijednost najznačajnijeg bita udaljenog LED-a, povucite DCK gore-dolje; postavite DAI ulaz na vrijednost sljedećeg bita, povucite DCK; i tako dalje dok se svi bitovi ne prenesu (uklj), nakon čega povlačimo LAT. To se može učiniti ručno (bit-bang), ali bolje je koristiti SPI sučelje posebno prilagođeno za to, budući da je predstavljeno na našem STM32 u dva primjerka.
Plava pilula STM32F103
Uvod: STM32 kontroleri mnogo su složeniji od Atmega328 nego što bi se moglo činiti zastrašujućim. Štoviše, zbog uštede energije, gotovo sve periferije su isključene u startu, a frekvencija takta je 8 MHz iz internog izvora. Srećom, programeri STM-a napisali su kod koji dovodi čip do "izračunatih" 72 MHz, a autori svih IDE-ova koje poznajem uključili su ga u proceduru inicijalizacije, tako da ne trebamo taktirati (ali možeš ako stvarno želiš). Ali morat ćete uključiti periferne uređaje.
Dokumentacija: Blue Pill je opremljen popularnim STM32F103C8T6 čipom, postoje dva korisna dokumenta za njega:
Data Sheet za mikrokontrolere STM32F103x8 i STM32F103xB;
Pinouts – chip pinouts – u slučaju da se odlučimo sami izraditi ploče;
Mapa memorije – mapa memorije za određeni čip. Referentni priručnik ima kartu za cijelu liniju i spominje registre koje naš nema.
Tablica s definicijama pinova – popis glavnih i alternativnih funkcija pinova; za “plavu pilulu” možete pronaći prikladnije slike na internetu s popisom pinova i njihovih funkcija. Stoga odmah guglamo Blue Pill pinout i držimo ovu sliku pri ruci:
NB: na slici s interneta došlo je do greške koja je zabilježena u komentarima, hvala na tome. Slika je zamijenjena, ali ovo je lekcija - bolje je provjeriti informacije ne iz podatkovnih tablica.
Uklanjamo podatkovnu tablicu, otvaramo Referentni priručnik i od sada koristimo samo njega.
Procedura: bavimo se standardnim ulazom/izlazom, konfiguriramo SPI, uključujemo potrebne periferije.
Ulaz izlaz
Na Atmega328, I/O je implementiran krajnje jednostavno, zbog čega obilje STM32 opcija može biti zbunjujuće. Sada nam trebaju samo zaključci, ali i oni imaju četiri opcije:
"Povuci gurni" (gurni povuci) je uobičajeni izlaz iz Arduina, pin može uzeti vrijednost HIGH ili LOW. Ali s "otvorenim odvodom" postoje poteškoće, iako je zapravo sve jednostavno ovdje:
Izlazna konfiguracija / kada je priključak dodijeljen izlazu: / izlazni međuspremnik omogućen: / – otvoreni način odvoda: “0” u izlaznom registru omogućuje N-MOS, “1” u izlaznom registru ostavlja priključak u Hi-Z načinu ( P-MOS nije aktiviran ) / – push-pull mod: "0" u izlaznom registru aktivira N-MOS, "1" u izlaznom registru aktivira P-MOS.
Sve razlike između otvorenog odvoda (otvoreni odvod) od "push-pull" (gurni povuci) je da prvi pin ne može prihvatiti HIGH stanje: kada upisuje jedan u izlazni registar, on prelazi u način rada visokog otpora (visoke impedancije, Bok-Z). Prilikom upisa nule, pin se ponaša isto u oba načina, i logički i električni.
U normalnom načinu izlaza, pin jednostavno emitira sadržaj izlaznog registra. U "alternativi" njime upravljaju odgovarajući periferni uređaji (vidi 9.1.4):
Ako je port bit konfiguriran kao alternativni funkcijski pin, pin registar je onemogućen i pin je spojen na periferni pin.
Alternativna funkcionalnost svakog pina opisana je u Definicije pin-a Podatkovna tablica nalazi se na preuzetoj slici. Na pitanje što učiniti ako pin ima nekoliko alternativnih funkcija, odgovor daje fusnota u podatkovnoj tablici:
Ako više perifernih uređaja koristi isti pin, kako bi se izbjegao sukob između alternativnih funkcija, u isto vrijeme treba koristiti samo jedan periferni uređaj, koji se uključuje pomoću bita za omogućavanje perifernog sata (u odgovarajućem RCC registru).
Konačno, pinovi u izlaznom načinu rada također imaju brzinu takta. Ovo je još jedna značajka za uštedu energije; u našem slučaju samo smo je postavili na maksimum i zaboravili.
Dakle: koristimo SPI, što znači da dva pina (s podacima i sa signalom takta) trebaju biti "alternativna push-pull funkcija", a drugi (LAT) treba biti "obična push-pull funkcija". Ali prije nego što ih dodijelimo, pozabavimo se SPI-jem.
SPI
Još jedan mali obrazovni program
SPI ili Serial Peripheral Interface (serijsko periferno sučelje) je jednostavno i vrlo učinkovito sučelje za povezivanje MK s drugim MK i vanjskim svijetom općenito. Načelo njegovog rada već je opisano gore, gdje o kineskom LED drajveru (u referentnom priručniku pogledajte odjeljak 25). SPI može raditi u glavnom ("master") i podređenom ("slave") načinu rada. SPI ima četiri osnovna kanala od kojih se ne mogu svi koristiti:
MOSI, glavni izlaz / podređeni ulaz: ovaj pin prenosi podatke u glavnom načinu rada, a prima podatke u podređenom načinu rada;
MISO, glavni ulaz / podređeni izlaz: naprotiv, prima u glavnom, a odašilje u podređenom;
SCK, Serial Clock: postavlja frekvenciju prijenosa podataka u glavnom ili prima signal takta u podređenom. U biti udarački ritmovi;
SS, Slave Select: uz pomoć ovog kanala rob zna da se od njega nešto traži. Na STM32 naziva se NSS, gdje je N = negativno, tj. kontroler postaje podređeni ako postoji uzemljenje u ovom kanalu. Dobro se kombinira s Open Drain Output modom, ali to je druga priča.
Kao i sve ostalo, SPI na STM32 je bogat funkcionalnošću, što ga čini donekle teškim za razumijevanje. Na primjer, može raditi ne samo sa SPI, već i sa I2S sučeljem, au dokumentaciji su njihovi opisi pomiješani, potrebno je pravovremeno odrezati višak. Naš zadatak je krajnje jednostavan: samo trebamo poslati podatke koristeći samo MOSI i SCK. Idemo na odjeljak 25.3.4 (half-duplex komunikacija, half-duplex komunikacija), gdje nalazimo 1 sat i 1 jednosmjerna podatkovna žica (1 signal sata i 1 jednosmjerni tok podataka):
U ovom načinu rada aplikacija koristi SPI u načinu rada samo za prijenos ili samo za prijem. / Način rada samo za prijenos sličan je dupleksnom načinu rada: podaci se prenose na pinu za prijenos (MOSI u glavnom načinu rada ili MISO u podređenom načinu rada), a prijemni pin (MISO ili MOSI respektivno) može se koristiti kao obični I/O pin . U ovom slučaju, aplikacija samo treba zanemariti Rx međuspremnik (ako je pročitan, tamo neće biti prenesenih podataka).
Super, MISO pin je slobodan, spojimo LAT signal na njega. Pogledajmo Slave Select, koji se na STM32 može programski kontrolirati, što je izuzetno zgodno. Čitamo istoimeni paragraf u odjeljku 25.3.1 SPI Opći opis:
Softverska kontrola NSS (SSM = 1) / Informacije o odabiru podređenog su sadržane u SSI bitu registra SPI_CR1. Vanjski NSS pin ostaje slobodan za potrebe drugih aplikacija.
Vrijeme je za upis u matične knjige. Odlučio sam koristiti SPI2, potražiti njegovu osnovnu adresu u podatkovnoj tablici - u odjeljku 3.3 Mapa memorije:
Otvorite odjeljak 25.3.3 s naslovom koji sam po sebi objašnjava "Konfiguriranje SPI-ja u glavnom načinu":
1. Postavite frekvenciju serijskog takta s bitovima BR[2:0] u registru SPI_CR1.
Registri su prikupljeni u istoimenom dijelu referentnog priručnika. Promjena adrese (Pomak adrese) za CR1 – 0x00, prema zadanim postavkama svi bitovi se brišu (Poništi vrijednost 0x0000):
BR bitovi postavljaju razdjelnik takta kontrolera, određujući tako frekvenciju na kojoj će SPI raditi. Naša frekvencija STM32 bit će 72 MHz, LED drajver, prema podatkovnoj tablici, radi na frekvenciji do 25 MHz, tako da trebamo podijeliti s četiri (BR[2:0] = 001).
2. Postavite CPOL i CPHA bitove za definiranje odnosa između prijenosa podataka i vremena serijskog sata (pogledajte dijagram na stranici 240)
Budući da ovdje čitamo podatkovnu tablicu, a ne gledamo sheme, pogledajmo pobliže tekstualni opis CPOL i CPHA bitova na stranici 704 (Opći opis SPI):
Faza sata i polaritet
Korištenjem CPOL i CPHA bitova SPI_CR1 registra, možete programski odabrati četiri vremenska odnosa. CPOL (polaritet sata) bit kontrolira stanje signala sata kada se podaci ne prenose. Ovaj bit kontrolira glavni i podređeni način rada. Ako je CPOL resetiran, SCK pin je nizak u načinu mirovanja. Ako je CPOL bit postavljen, SCK pin je visok tijekom načina mirovanja.
Kada je postavljen bit CPHA (faza takta), strob zamke visokog bita je drugi rub SCK signala (opadajući ako je CPOL čist, raste ako je CPOL postavljen). Podaci se bilježe drugom promjenom signala sata. Ako je CPHA bit prazan, strob zamke visokog bita je rastući rub SCK signala (padajući rub ako je postavljen CPOL, rastući rub ako je CPOL izbrisan). Podaci se bilježe pri prvoj promjeni signala sata.
Upijajući ovo znanje, dolazimo do zaključka da oba bita moraju ostati nule, jer Želimo da SCK signal ostane nizak kada se ne koristi i da se podaci prenose na uzlaznom rubu impulsa (vidi sl. Rising Edge u podatkovnoj tablici DM634).
Usput, ovdje smo prvi put naišli na značajku vokabulara u ST podatkovnim tablicama: u njima je napisana fraza "resetiraj bit na nulu" malo resetiratiI ne malo raščistiti, poput, na primjer, Atmege.
3. Postavite DFF bit da odredite je li blok podataka 8-bitni ili 16-bitni format
Posebno sam uzeo 16-bitni DM634 kako se ne bih mučio s prijenosom 12-bitnih PWM podataka, poput DM633. Ima smisla postaviti DFF na jedan:
4. Konfigurirajte bit LSBFIRST u registru SPI_CR1 da odredite format bloka
LSBFIRST, kao što mu ime sugerira, konfigurira prijenos s bitom najmanje važnosti prvi. Ali DM634 želi primati podatke počevši od najvažnijeg bita. Stoga ga ostavljamo resetiranim.
5. U hardverskom načinu rada, ako je potreban unos s NSS pina, primijenite visoki signal na NSS pin tijekom cijele sekvence prijenosa bajtova. U NSS softverskom načinu, postavite SSM i SSI bitove u SPI_CR1 registar. Ako se NSS pin koristi kao izlaz, potrebno je postaviti samo bit SSOE.
Instalirajte SSM i SSI da zaboravite na NSS hardverski način rada:
#define SSI 0x0100
#define SSM 0x0200
_SPI2_ (_SPI_CR1) |= SSM | SSI; //enable software control of SS, SS high
6. Bitovi MSTR i SPE moraju biti postavljeni (ostaju postavljeni samo ako je NSS signal visok)
Zapravo, ovim bitovima određujemo naš SPI kao glavni i uključujemo ga:
SPI je konfiguriran, idemo odmah napisati funkcije koje šalju bajtove u upravljački program. Nastavite čitati 25.3.3 “Konfiguriranje SPI u glavnom načinu rada”:
Nalog za prijenos podataka
Prijenos počinje kada se bajt upiše u Tx međuspremnik.
Bajt podataka se učitava u registar posmaka na paralelno načinu rada (s interne sabirnice) tijekom prijenosa prvog bita, nakon čega se prenosi na sekvencijalno MOSI pin mod, prvi ili zadnji bit naprijed ovisno o postavci bita LSBFIRST u registru CPI_CR1. Oznaka TXE postavlja se nakon prijenosa podataka iz Tx međuspremnika u registar posmaka, a također generira prekid ako je postavljen bit TXEIE u registru CPI_CR1.
Istaknuo sam nekoliko riječi u prijevodu kako bih skrenuo pozornost na jednu značajku implementacije SPI u STM kontrolere. Na Atmegi TXE zastavica (Tx Prazan, Tx je prazan i spreman za primanje podataka) postavlja se tek nakon što je cijeli bajt poslan van. I ovdje je ova zastavica postavljena nakon što je bajt umetnut u interni registar posmaka. Budući da se tamo gura sa svim bitovima u isto vrijeme (paralelno), a zatim se podaci prenose sekvencijalno, TXE se postavlja prije nego što se bajt u potpunosti pošalje. Ovo je važno jer u slučaju našeg LED drajvera, moramo povući LAT pin nakon slanja Sve podataka, tj. Sama TXE zastavica nam neće biti dovoljna.
To znači da nam treba još jedna zastava. Pogledajmo 25.3.7 - “Status Flags”:
<…>
ZAUZETO zastavica
Oznaku BSY postavlja i briše hardver (pisanje na nju nema učinka). Oznaka BSY označava stanje SPI komunikacijskog sloja.
Ponovno se postavlja:
kada je prijenos dovršen (osim u glavnom načinu rada ako je prijenos kontinuiran)
kada je SPI onemogućen
kada se pojavi pogreška glavnog načina (MODF=1)
Ako prijenos nije kontinuiran, BSY oznaka se briše između svakog prijenosa podataka
Dobro, ovo će mi dobro doći. Otkrijmo gdje se nalazi Tx međuspremnik. Da biste to učinili, pročitajte “Registar SPI podataka”:
Bitovi 15:0 DR[15:0] registar podataka
Podaci primljeni ili podaci koji se prenose.
Registar podataka podijeljen je u dva međuspremnika - jedan za upis (međuspremnik za prijenos) i jedan za čitanje (spremnik za prijem). Upisivanje u podatkovni registar upisuje u Tx međuspremnik, a čitanje iz podatkovnog registra vratit će vrijednost sadržanu u Rx međuspremniku.
Pa, i registar statusa, gdje se nalaze zastavice TXE i BSY:
Pa, budući da trebamo prenijeti 16 puta dva bajta, prema broju izlaza LED drajvera, nešto ovako:
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();
}
Ali još ne znamo kako povući LAT pin, pa ćemo se vratiti na I/O.
Dodjeljivanje igala
U STM32F1, registri odgovorni za stanje pinova prilično su neobični. Jasno je da ih ima više od Atmege, ali su i drugačiji od ostalih STM čipova. Odjeljak 9.1 Opći opis GPIO-a:
Svaki od I/O priključaka opće namjene (GPIO) ima dva 32-bitna konfiguracijska registra (GPIOx_CRL i GPIOx_CRH), dva 32-bitna podatkovna registra (GPIOx_IDR i GPIOx_ODR), 32-bitni set/reset registar (GPIOx_BSRR), 16-bitni reset registar (GPIOx_BRR) i 32-bitni registar za resetiranje registar za blokiranje bitova (GPIOx_LCKR).
Prva dva registra su neobična, a također i prilično nezgodna, jer je 16 port pinova razbacano po njima u formatu "četiri bita po bratu". Oni. pinovi od nula do sedam su u CRL, a ostali su u CRH. U isto vrijeme, preostali registri uspješno sadrže bitove svih pinova porta - često ostaju napola "rezervirani".
Radi jednostavnosti, krenimo od kraja popisa.
Ne treba nam registar blokada.
Registri za postavljanje i resetiranje prilično su smiješni jer se djelomično dupliraju: sve možete pisati samo u BSRR, gdje će viših 16 bitova resetirati pin na nulu, a nižih će biti postavljeno na 1, ili također možete koristite BRR, čijih nižih 16 bitova samo resetiraju pin. Sviđa mi se druga opcija. Ovi registri su važni jer daju atomski pristup pinovima:
Atomsko postavljanje ili resetiranje
Nema potrebe za onemogućavanjem prekida prilikom programiranja GPIOx_ODR na razini bita: jedan ili više bitova može se promijeniti jednom atomskom operacijom pisanja APB2. To se postiže upisivanjem "1" u registar za postavljanje/poništavanje (GPIOx_BSRR ili, samo za ponovno postavljanje, GPIOx_BRR) bita koji treba promijeniti. Ostali bitovi ostat će nepromijenjeni.
Registar podataka ima sasvim jasna imena - IDR = Ulazni Registar smjera, ulazni registar; ODR = Izlaz Registar smjera, izlazni registar. Nećemo ih trebati u trenutnom projektu.
I na kraju, kontrolni registri. Budući da nas zanimaju drugi SPI pinovi, naime PB13, PB14 i PB15, odmah pogledamo CRH:
I vidimo da ćemo morati napisati nešto u bitovima od 20 do 31.
Gore smo već shvatili što želimo od pinova, pa ću ovdje bez snimke zaslona, samo ću reći da MODE određuje smjer (unos ako su oba bita postavljena na 0) i brzinu pina (potrebno nam je 50MHz, tj. oba pina na "1"), a CNF postavlja način rada: regularni "push-pull" - 00, "alternativni" - 10. Prema zadanim postavkama, kao što vidimo gore, svi pinovi imaju treći bit odozdo (CNF0), postavlja ih na način rada plutajući unos.
Budući da planiram učiniti nešto drugo s ovim čipom, zbog jednostavnosti definirao sam sve moguće vrijednosti MODE i CNF za donji i gornji kontrolni registar.
(LAT_nisko samo po inerciji, uvijek je tako bilo, neka ostane)
Sada je sve super, ali ne ide. Budući da je ovo STM32, oni štede struju, što znači da morate omogućiti taktiranje potrebnih perifernih uređaja.
Uključite mjerenje vremena
Sat, također poznat kao sat, odgovoran je za mjerenje vremena. I već smo mogli primijetiti kraticu RCC. Tražimo ga u dokumentaciji: ovo je Reset and Clock Control.
Kao što je gore rečeno, srećom, najteži dio teme clockinga za nas su odradili ljudi iz STM-a, na čemu im veliko hvala (još jednom ću dati link na Di Haltova web stranica, da bude jasno koliko je zbunjujuće). Trebamo samo registre odgovorne za omogućavanje perifernog takta (Peripheral Clock Enable Registers). Prvo, pronađimo osnovnu adresu RCC-a, ona je na samom početku "Mape memorije":
Zatim ili kliknite na poveznicu na kojoj pokušavate pronaći nešto u ploči, ili, mnogo bolje, prođite kroz opise registara za omogućavanje iz odjeljaka o omogućiti registre. Gdje ćemo pronaći RCC_APB1ENR i RCC_APB2ENR:
I oni, sukladno tome, sadrže bitove koji uključuju taktiranje SPI2, IOPB (I/O port B) i alternativne funkcije (AFIO).
Ako imate priliku i želju za testiranjem, onda spojite DM634 ovako: DAI na PB15, DCK na PB13, LAT na PB14. Napajamo vozač iz 5 volti, ne zaboravite spojiti uzemljenje.
STM8 PWM
PWM na STM8
Kad sam tek planirao ovaj članak, odlučio sam, kao primjer, pokušati svladati neke funkcije nepoznatog čipa koristeći samo podatkovnu tablicu, kako ne bih završio s postolarom bez čizama. STM8 je bio idealan za ovu ulogu: prvo, imao sam nekoliko kineskih ploča sa STM8S103, a drugo, nije baš popularan, pa stoga iskušenje čitanja i pronalaska rješenja na Internetu počiva na nedostatku tih istih rješenja.
Prema zadanim postavkama, STM8 radi na frekvenciji od 2 MHz, to se mora odmah ispraviti.
HSI (High Speed Internal) sat
HSI taktni signal se izvodi iz unutarnjeg RC oscilatora od 16 MHz s programabilnim razdjelnikom (1 do 8). Postavlja se u registru djelitelja takta (CLK_CKDIVR).
Napomena: na početku je odabran HSI RC oscilator s razdjelnikom 8 kao vodeći izvor taktnog signala.
Pronalazimo adresu registra u podatkovnoj tablici, opis u refmanu i vidimo da registar treba obrisati:
Budući da ćemo pokrenuti PWM i spojiti LED diode, pogledajmo pinout:
Čip je malen, mnoge su funkcije obješene na iste pinove. Ono što je u uglatim zagradama je "alternativna funkcionalnost", prebacuje se "opcijskim bajtovima" (opcijski bajtovi) – nešto poput Atmega osigurača. Njihove vrijednosti možete promijeniti programski, ali to nije nužno, jer Nova funkcionalnost se aktivira tek nakon ponovnog pokretanja sustava. Lakše je koristiti ST Visual Programmer (preuzet s Visual Developom), koji može promijeniti ove bajtove. Pinout pokazuje da su pinovi CH1 i CH2 prvog timera skriveni u uglatim zagradama; potrebno je postaviti AFR1 i AFR0 bitove u STVP, a drugi će također prenijeti CH1 izlaz drugog timera sa PD4 na PC5.
Dakle, 6 pinova će kontrolirati LED diode: PC6, PC7 i PC3 za prvi timer, PC5, PD3 i PA3 za drugi.
Postavljanje samih I/O pinova na STM8 je jednostavnije i logičnije nego na STM32:
poznato iz Atmega DDR registra smjera podataka (Registar smjera podataka): 1 = izlaz;
prvi upravljački registar CR1, kada izlazi, postavlja push-pull mod (1) ili otvoreni odvod (0); budući da LED diode spajam na čip s katodama, ovdje ostavljam nule;
drugi kontrolni registar CR2, kada je na izlazu, postavlja brzinu takta: 1 = 10 MHz
Automatsko ponovno učitavanje, AR – autoloadable vrijednost do koje će tajmer brojati (period impulsa);
Događaj ažuriranja, UEV – događaj koji se dogodi kada mjerač vremena izbroji do AR;
PWM radni ciklus – PWM radni ciklus, koji se često naziva "faktor rada";
Hvatanje/usporedba vrijednosti – vrijednost za snimanje/usporedbu, do koje je mjerač brojao učinit će nešto (u slučaju PWM-a, invertira izlazni signal);
Vrijednost predučitavanja – unaprijed učitana vrijednost. Usporedite vrijednost ne može se mijenjati dok mjerač vremena otkucava, inače će se PWM ciklus prekinuti. Stoga se nove prenesene vrijednosti smještaju u međuspremnik i izvlače kada mjerač vremena dosegne kraj svog odbrojavanja i resetira se;
Poravnano po rubovima и Načini poravnanja u sredini – poravnanje duž obruba i u središtu, isto kao kod Atmela Brzi PWM и Fazno ispravan PWM.
OCiREF, referentni signal usporedbe izlaza – referentni izlazni signal, zapravo ono što se pojavljuje na odgovarajućem pinu u PWM modu.
Kao što je već jasno iz pinout-a, dva tajmera imaju PWM mogućnosti - prvi i drugi. Oba su 16-bitna, prvi ima puno dodatnih značajki (konkretno, može brojati i gore i dolje). Oba nam trebaju da rade jednako, pa sam odlučio krenuti s očito lošijim drugim, da slučajno ne koristim nešto čega nema. Neki problem je što se opis PWM funkcionalnosti svih mjerača vremena u referentnom priručniku nalazi u poglavlju o prvom mjeraču vremena (17.5.7 PWM način rada), tako da morate stalno skakati naprijed-natrag kroz dokument.
PWM na STM8 ima važnu prednost u odnosu na PWM na Atmegi:
PWM usklađen s granicama
Konfiguracija računa odozdo prema gore
Brojenje odozdo prema gore aktivno je ako je DIR bit u registru TIM_CR1 izbrisan
Primjer
Primjer koristi prvi PWM mod. PWM referentni signal OCiREF održava se visoko sve dok je TIM1_CNT < TIM1_CCRi. Inače je potrebna niska razina. Ako je usporedna vrijednost u registru TIM1_CCRi veća od vrijednosti automatskog učitavanja (registar TIM1_ARR), OCiREF signal se zadržava na 1. Ako je usporedna vrijednost 0, OCiREF se održava na nuli....
STM8 mjerač vremena tijekom događaj ažuriranja prvo provjerava usporediti vrijednost, i tek tada proizvodi referentni signal. Atmegin timer prvo zajebe, a zatim uspoređuje, što rezultira compare value == 0 izlaz je igla, s kojom se mora nekako pozabaviti (na primjer, programskim invertiranjem logike).
Dakle, ono što želimo učiniti: 8-bitni PWM (AR == 255), računajući odozdo prema gore, poravnanje uz rub. Budući da su žarulje spojene na čip pomoću katoda, PWM bi trebao izlaziti 0 (LED uključen) dok usporediti vrijednost i 1 poslije.
O nekima smo već čitali PWM način rada, tako da traženi registar drugog mjerača vremena pronalazimo pretraživanjem u referentnom priručniku ove fraze (18.6.8 - TIMx_CCMR1):
110: Prvi PWM mod – kada se broji odozdo prema gore, prvi kanal je aktivan dok je TIMx_CNT < TIMx_CCR1. Inače, prvi kanal je neaktivan. [dalje u dokumentu postoji pogrešan copy-paste iz mjerača vremena 1] 111: Drugi PWM mod – kada se broji odozdo prema gore, prvi kanal je neaktivan dok je TIMx_CNT < TIMx_CCR1. Inače, prvi kanal je aktivan.
Budući da su LED diode povezane s MK katodama, drugi način nam odgovara (i prvi, ali to još ne znamo).
Bit 3 OC1PE: Omogući predopterećenje pina 1
0: Predučitani registar na TIMx_CCR1 je onemogućen. TIMx_CCR1 možete pisati bilo kada. Nova vrijednost djeluje odmah.
1: Omogućen je registar predučitavanja na TIMx_CCR1. Operacije čitanja/pisanja pristupaju registru predučitavanja. Prethodno učitana vrijednost TIMx_CCR1 učitava se u registar u sjeni tijekom svakog događaja ažuriranja.
*Napomena: Da bi PWM način rada ispravno radio, predučitani registri moraju biti omogućeni. Ovo nije potrebno u načinu rada s jednim signalom (OPM bit je postavljen u registru TIMx_CR1).
U redu, uključimo sve što nam je potrebno za tri kanala drugog timera:
Drugi mjerač vremena može brojati samo odozdo prema gore, poravnanje uz rub, ne treba ništa mijenjati. Postavimo djelitelj frekvencije, na primjer, na 256. Za drugi mjerač vremena, djelitelj je postavljen u registru TIM2_PSCR i stepen je dvojke:
Ostaje samo uključiti zaključke i sam drugi mjerač vremena. Prvi problem rješavaju registri Snimi/Usporedi Omogućiti: na njima su asimetrično raštrkana dva, tri kanala. Ovdje također možemo naučiti da je moguće promijeniti polaritet signala, tj. u načelu je bilo moguće koristiti PWM način 1. Pišemo:
Napišimo jednostavan analog AnalogWrite(), koji će stvarne vrijednosti prenijeti na mjerač vremena za usporedbu. Registri su nazvani predvidljivo Hvatanje/usporedba registara, postoje dva od njih za svaki kanal: 8 bitova nižeg reda u TIM2_CCRxL i onih visokog reda u TIM2_CCRxH. Budući da smo napravili 8-bitni PWM, dovoljno je napisati samo najmanje bitne bitove:
Pažljivi čitatelj primijetit će da imamo malo neispravan PWM, nesposoban proizvesti 100% punjenje (pri maksimalnoj vrijednosti od 255, signal se invertira za jedan ciklus tajmera). Za LED diode to nije važno, a pažljivi čitatelj već može pogoditi kako to popraviti.
PWM na drugom timeru radi, prijeđimo na prvi.
Prvi timer ima potpuno iste bitove u istim registrima (samo što su oni bitovi koji su ostali "rezervirani" u drugom timeru aktivno korišteni u prvom za svakakve napredne stvari). Stoga je dovoljno pronaći adrese istih registara u podatkovnoj tablici i kopirati kod. Pa, promijenite vrijednost razdjelnika frekvencije, jer... prvi mjerač vremena ne želi primiti potenciju dvojke, već točnu 16-bitnu vrijednost u dva registra Prescaler High и Nizak. Radimo sve i... prvi mjerač vremena ne radi. Što je bilo?
Problem se može riješiti jedino pregledom cijelog odjeljka o upravljačkim registrima mjerača vremena 1, gdje tražimo onaj koji drugi mjerač vremena nema. Biti će 17.7.30 Registar prekida (TIM1_BKR), gdje je ovaj bit:
Treći mini-projekt je spojiti osam RGB LED dioda na drugi mjerač vremena u PWM modu i omogućiti im da prikazuju različite boje. Temelji se na konceptu LED multipleksiranja, a to je da ako palite i gasite LED diode vrlo, vrlo brzo, činit će nam se da su stalno upaljene (postojanost vida, inercija vizualne percepcije). jednom jesam ovako nešto na Arduinu.
Algoritam rada izgleda ovako:
spojio anodu prve RGB LED diode;
upalio, šaljući potrebne signale katodama;
čekao do kraja PWM ciklusa;
spojio anodu drugog RGB LED-a;
zapalio...
Pa itd. Naravno, za lijep rad potrebno je da anoda bude spojena i da se LED dioda "upali" u isto vrijeme. Pa, ili skoro. U svakom slučaju, trebamo napisati kod koji će ispisivati vrijednosti u tri kanala drugog timera, mijenjati ih kada se dostigne UEV, a istovremeno mijenjati trenutno aktivni RGB LED.
Budući da je prebacivanje LED dioda automatsko, moramo stvoriti "video memoriju" iz koje će rukovatelj prekida primati podatke. Ovo je jednostavan niz:
uint8_t colors[8][3];
Da biste promijenili boju određene LED diode, bit će dovoljno upisati potrebne vrijednosti u ovaj niz. A varijabla će biti odgovorna za broj aktivne LED diode
uint8_t cnt;
Demux
Za pravilno multipleksiranje potreban nam je, čudno, CD74HC238 demultipleksor. Demultipleksor - čip koji implementira operator u hardver <<. Preko tri ulazna pina (bitovi 0, 1 i 2) dovodimo mu trobitni broj X, a on kao odgovor aktivira izlazni broj (1<<X). Preostali ulazi čipa koriste se za skaliranje cijelog dizajna. Ovaj čip nam je potreban ne samo da smanjimo broj zauzetih pinova mikrokontrolera, već i za sigurnost - kako ne bismo slučajno uključili više LED dioda nego što je moguće i ne spalimo MK. Čip košta peni i uvijek ga treba držati u kućnom ormariću s lijekovima.
Naš CD74HC238 bit će odgovoran za dovod napona na anodu željene LED diode. U punopravnom multipleksu, on bi opskrbljivao napon stupcu preko P-MOSFET-a, ali u ovoj demonstraciji to je moguće izravno, jer troši 20 mA, prema apsolutne maksimalne ocjene u podatkovnoj tablici. Iz Podatkovna tablica CD74HC238 trebamo pinouts i ovu varalicu:
H = visoka razina napona, L = razina niskog napona, X – nije me briga
Spojimo E2 i E1 na masu, E3, A0, A1 i A3 na pinove PD5, PC3, PC4 i PC5 STM8. Budući da gornja tablica sadrži i niske i visoke razine, mi konfiguriramo ove pinove kao push-pull pinove.
PWM
PWM na drugom timeru je konfiguriran na isti način kao u prethodnoj priči, s dvije razlike:
Prvo, moramo omogućiti uključenje prekida Ažuriraj događaj (UEV) koji će pozvati funkciju koja uključuje i isključuje aktivni LED. To se postiže promjenom nastavka Ažuriraj Omogući prekid u registar znakovitog imena
Druga razlika je vezana uz fenomen multipleksiranja, kao npr ghosting – parazitski sjaj dioda. U našem slučaju, može se pojaviti zbog činjenice da mjerač vremena, nakon što je izazvao prekid na UEV-u, nastavlja otkucavati, a rukovatelj prekidima nema vremena za prebacivanje LED prije nego što mjerač vremena počne pisati nešto na pinove. Da biste se borili protiv toga, morat ćete preokrenuti logiku (0 = maksimalna svjetlina, 255 = ništa ne svijetli) i izbjegavati ekstremne vrijednosti radnog ciklusa. Oni. osigurajte da se nakon UEV LED diode potpuno ugase za jedan PWM ciklus.
Izbjegavajte postavljanje r, g i b na 255 i ne zaboravite ih obrnuti kada ih koristite.
Prekidi
Bit prekida je da pod određenim okolnostima čip prestane izvršavati glavni program i pozove neku vanjsku funkciju. Prekidi se javljaju zbog vanjskih ili unutarnjih utjecaja, uključujući mjerač vremena.
Kada smo prvi put izradili projekt u ST Visual Developu, pored toga main.c dobili smo prozor s misterioznom datotekom stm8_interrupt_vector.c, automatski uključen u projekt. U ovoj datoteci, funkcija je dodijeljena svakom prekidu NonHandledInterrupt. Moramo vezati našu funkciju na željeni prekid.
Podatkovna tablica ima tablicu vektora prekida, gdje nalazimo one koji su nam potrebni:
@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;
}
Ostaje samo omogućiti prekide. To se radi pomoću naredbe asemblera rim - morat ćete ga potražiti u Priručnik za programiranje:
//enable interrupts
_asm("rim");
Druga asemblerska naredba je sim – isključuje prekide. Moraju se isključiti dok se nove vrijednosti zapisuju u "video memoriju", tako da prekid uzrokovan u pogrešnom trenutku ne pokvari niz.
Ako barem netko smatra ovaj članak korisnim, onda ga nisam uzalud napisao. Bit će mi drago primiti komentare i primjedbe, pokušat ću odgovoriti na sve.