Π Lehenengo zatia Arduino praketatik hazitako zaletasun elektronikoko ingeniariei nola eta zergatik irakurri behar zituzten mikrokontrolagailuentzako fitxa teknikoak eta bestelako dokumentazioa esaten saiatu nintzen. Testua handia izan zen, beraz, artikulu praktiko batean adibide praktikoak erakusteko agindu nion. Tira, bere buruari esne-perretxiko deitzen zion...
Gaur datu-orriak nola erabili erakutsiko dizut STM32 (Blue Pill) eta STM8 kontrolagailuetako zereginak nahiko sinpleak, baina beharrezkoak, ebazteko. Demo proiektu guztiak nire gogoko LEDei eskainita daude, kantitate handietan argiztatuko ditugu, horretarako era guztietako periferiko interesgarriak erabili beharko ditugu.
Testua berriro ere izugarria izan zen, beraz, erosotasunerako edukia egiten ari naiz:
Lege-oharra: ez naiz ingeniaria, ez dut elektronikan ezagutza sakona dudanik ematen, artikulua ni bezalako afizionatuentzat dago pentsatuta. Izan ere, duela bi urte xede-publikotzat hartu nuen nire burua. Norbaitek orduan esan izan balu txip ezezagun batean fitxak irakurtzeko beldurrik ez dutela irakurtzeko, ez nuke denbora asko emango Interneten kode zati batzuen bila eta guraizeekin eta zinta itsasgarriekin makuluak asmatzen.
Artikulu honen ardatza datu-orrietan dago, ez proiektuetan; beraz, baliteke kodea ez izatea oso txukuna eta askotan estua izatea. Proiektuak berez oso sinpleak dira, txip berria lehen ezagutzeko egokiak diren arren.
Espero dut nire artikuluak zaletasunean murgiltzeko antzeko fasean dagoen norbait laguntzea.
STM32
DM16 eta SPI duten 634 LED
Blue Pill (STM32F103C8T6) eta DM634 LED kontrolatzailea erabiliz proiektu txiki bat. Fitxategiak erabiliz, kontrolatzailea, STM IO atakak eta SPI konfiguratuko ditugu.
DM634
Taiwango txipa 16 16 biteko PWM irteerarekin, kateetan konekta daiteke. Behe-end 12 biteko eredua etxeko proiektu batetik ezagutzen da Lightpack. Garai batean, DM63x eta TLC5940 ezagunaren artean aukeratuz, DM aukeratu nuen hainbat arrazoirengatik: 1) Aliexpress-en TLC faltsua da zalantzarik gabe, baina hau ez; 2) DM-k PWM autonomo bat du bere maiztasun-sorgailuarekin; 3) Moskun merke eros liteke, Aliren pakete baten zain egon beharrean. Eta, noski, interesgarria izan zen txipa zuk zeuk kontrolatzen ikastea, prest egindako liburutegi bat erabili beharrean. Gaur egun txipak SSOP24 paketean aurkezten dira batez ere; egokitzaile batera soldatzeko errazak dira.
Fabrikatzailea taiwandarra denez, fitxa teknikoa txipa ingelesez txinatar idatzita dago, hau da, dibertigarria izango da. Lehenik pinout-a ikusten dugu (Pin konexioa) zein hanka zertara konektatu ulertzeko eta pinen deskribapena (Pinaren deskribapena). 16 pin:
DC konketa-iturriak (isurketa irekia)
Putzuak / Irteera irekia β drainatzea; sarrerako korronte iturria; irteera lurrera konektatzen da egoera aktiboan - LEDak katodoen bidez kontrolatzaileari konektatzen dira. Elektrikoki, hau ez da, noski, "hustubide irekia" (hustubide irekia), baina datu-orrietan drainatzeko moduan dauden pinen izendapen hori sarritan aurkitzen da.
REXT eta GND arteko kanpoko erresistentziak irteerako korrontearen balioa ezartzeko
Erreferentzia-erresistentzia bat instalatzen da REXT pinaren eta lurraren artean, irteeren barne-erresistentzia kontrolatzen duena, ikusi fitxa teknikoaren 9. orrialdeko grafikoa. DM634-n, erresistentzia hori softwarearen bidez ere kontrola daiteke, distira orokorra ezarriz (distira globala); Artikulu honetan ez naiz xehetasunetan sartuko, 2.2 - 3 kOhm-ko erresistentzia bat jarriko dut hemen.
Txipa nola kontrolatu ulertzeko, ikus dezagun gailuaren interfazearen deskribapena:
Bai, hemen dago, txinera ingelesa bere aintza osoan. Hau itzultzea arazotsua da, nahi izanez gero uler dezakezu, baina beste modu bat dago - begiratu nola funtzionalki antzeko TLC5940 konexioa deskribatzen den datu-orrian:
... Hiru pin bakarrik behar dira datuak gailuan sartzeko. SCLK seinalearen goranzko ertzak SIN pinetik barne erregistrora aldatzen ditu datuak. Datu guztiak kargatu ondoren, XLAT seinale altu labur batek sekuentzialki transferitutako datuak barne-erregistroetara atxikitzen ditu. Barne-erregistroak XLAT seinale-mailak abiarazitako ateak dira. Datu guztiak bit esanguratsuena transmititzen dira lehenik.
latch β giltza/giltza/giltza. Goranzko ertza β Pultsuaren lehen ertza MSB lehenik β bit esanguratsuena (ezkerrekoena) aurrera. datuak erlojupatzeko β datuak sekuentzialki transmititzea (bitz bit).
Word latch txipetarako dokumentazioan aurkitu ohi da eta hainbat modutara itzultzen da, beraz, ulertzearren, baimenduko dut
hezkuntza programa txiki batLED kontrolatzailea, funtsean, aldaketa-erregistro bat da. "Shift" (mugitzeko) izenean - gailuaren barruan datuen mugimendua bit-bitan: barruan sartzen den bit berri bakoitzak kate osoa aurrera eramaten du aurrean. Inork ez duenez LEDen keinuka kaotikorik ikusi nahi txandan zehar, prozesua motelgailu batek laneko erregistroetatik bereizita dagoen buffer-erregistroetan gertatzen da (latch) itxarongela moduko bat da, non bitak nahi den sekuentzian antolatuta dauden. Dena prest dagoenean, pertsiana irekitzen da eta bitsak lanera joaten dira, aurreko lotea ordezkatuz. Hitza latch mikrozirkuituetarako dokumentazioan ia beti dakar halako motelgailu bat, edozein konbinaziotan erabiltzen den.
Beraz, datu-transferentzia DM634ra honela egiten da: ezarri DAI sarrera urruneko LEDaren bit esanguratsuenaren balioa, tira DCK gora eta behera; ezarri DAI sarrera hurrengo bitaren balioarekin, tira DCK; eta abar bit guztiak transmititu arte (erlojua sartuta), ondoren LAT tiratzen dugu. Hau eskuz egin daiteke (bit-bang), baina hobe da horretarako bereziki egokitutako SPI interfaze bat erabiltzea, gure STM32n bi kopiatan aurkezten baita.
Pilula Urdina STM32F103
Sarrera: STM32 kontrolagailuak Atmega328 baino askoz konplexuagoak dira beldurgarriak diruditen baino. Gainera, energia aurrezteko arrazoiengatik, ia periferiko guztiak itzaltzen dira hasieran, eta erlojuaren maiztasuna barne iturritik 8 MHz-ra dago. Zorionez, STM programatzaileek txipa "kalkulatutako" 72 MHz-ra eramaten duen kodea idatzi zuten, eta ezagutzen ditudan IDE guztien egileek hasierako prozeduran sartu zuten, beraz, ez dugu erlojua egin behar (baina dezakezu benetan nahi baduzu). Baina periferikoak piztu beharko dituzu.
Dokumentazioa: Blue Pill STM32F103C8T6 txip ezagunarekin hornituta dago, horretarako bi dokumentu erabilgarria daude:
Fitxa STM32F103x8 eta STM32F103xB mikrokontrolagailuetarako;
Memoria-mapa: txip jakin baterako memoria-mapa. Erreferentzia Eskuliburuak lerro osorako mapa bat du, eta gureak ez dituen erregistroak aipatzen ditu.
Pin definizioen taula - pinen funtzio nagusiak eta alternatiboak zerrendatzen ditu; "pilula urdinerako" irudi erosoagoak aurki ditzakezu Interneten pin zerrenda batekin eta haien funtzioekin. Hori dela eta, berehala Blue Pill pinout-a Googlen bilatzen dugu eta argazki hau eskura izango dugu:
NB: Interneteko argazkian akats bat egon da, iruzkinetan adierazitakoa, eskerrik asko. Irudia ordezkatu da, baina hau ikasgai bat da; hobe da datu-orrietatik ez dagoen informazioa egiaztatzea.
Fitxa teknikoa kentzen dugu, Erreferentzia Eskuliburua irekitzen dugu eta hemendik aurrera hura bakarrik erabiltzen dugu.
Prozedura: sarrera/irteera estandarra lantzen dugu, SPI konfiguratzen dugu, beharrezko periferikoak pizten ditugu.
Sarrera Irteera
Atmega328-n, I/O oso sinplea da inplementatzen, horregatik STM32 aukeren ugaritasuna nahasia izan daiteke. Orain ondorioak baino ez ditugu behar, baina hauek ere lau aukera dituzte:
hustubide ireki, push-pull, push-pull alternatibo, drain ireki alternatibo
"Tira-bultza" (bultza-tira) Arduinoren ohiko irteera da, pinak ALTU edo BAXU balioa har dezake. Baina "hustubide irekiarekin" badaude zailtasunak, nahiz eta egia esan dena erraza den hemen:
Irteerako konfigurazioa / ataka irteerari esleitzen zaionean: / irteerako buffera gaituta: / β drainatzeko modua irekita: "0" irteerako erregistroan N-MOS gaitzen da, "1" irteerako erregistroan ataka Hi-Z moduan uzten du ( P-MOS ez dago aktibatuta ) / β push-pull modua: irteerako erregistroan β0β N-MOS aktibatzen du, irteerako erregistroan β1β P-MOS aktibatzen du.
Hustubide irekiaren arteko alde guztiak (hustubide irekia) "bultza-tira"-tik (bultza-tira) lehen pinean ezin duela ALTA egoera onartu: irteerako erregistroan bat idaztean, erresistentzia handiko moduan sartzen da (handiko inpedantzia, Kaixo-Z). Zero idaztean, pinak berdin jokatzen du bi moduetan, bai logikoki eta bai elektrikoki.
Irteera-modu arruntean, pinak irteera-erregistroaren edukia besterik ez du igortzen. "Alternatiboa" dagozkion periferikoek kontrolatzen dute (ikus 9.1.4):
Portu-bit bat ordezko funtzio-pin gisa konfiguratuta badago, pin-erregistroa desgaitu egingo da eta pin-a pin periferikora konektatuta dago.
Pin bakoitzaren funtzionaltasun alternatiboak deskribatzen dira Pin definizioak Fitxa teknikoa deskargatutako irudian dago. Pin batek funtzio alternatibo batzuk baditu zer egin behar den galderari, erantzuna datu-orrian oin-ohar batek ematen du:
Hainbat periferikok pin bera erabiltzen badute, funtzio alternatiboen arteko gatazkak saihesteko, periferiko bakarra erabili behar da aldi berean, erloju periferikoa gaitzeko bit erabiliz (RCC erregistro egokian).
Azkenik, irteera moduan dauden pinek erlojuaren abiadura ere badute. Hau energia aurrezteko beste ezaugarri bat da; gure kasuan, gehienezko mailan ezarri eta ahaztu egiten dugu.
Beraz: SPI erabiltzen ari gara, hau da, bi pin (datuekin eta erloju-seinalearekin) "push-pull funtzio alternatiboa" izan behar dute, eta beste batek (LAT) "push-pull erregularra". Baina horiek esleitu aurretik, jor diezaiogun SPIri.
SPI
Beste hezkuntza programa txiki bat
SPI edo Serial Peripheral Interface (interfaze periferiko seriea) MK bat beste MK batzuekin eta, oro har, kanpoko munduarekin konektatzeko interfaze sinple eta oso eraginkorra da. Bere funtzionamenduaren printzipioa goian deskribatu da, non Txinako LED kontrolatzaileari buruz (erreferentzia eskuliburuan, ikusi 25. atala). SPI-k maisu ("master") eta esklabo ("esklabo") moduan funtziona dezake. SPI-k oinarrizko lau kanal ditu, eta horietatik guztiak ezin dira erabili:
MOSI, Master Output / Slave Input: pin honek datuak maisu moduan transmititzen ditu eta datuak esklabo moduan jasotzen ditu;
MISO, Master Input / Slave Output: aitzitik, maisuan jasotzen du, eta esklaboan transmititzen du;
SCK, Serial Clock: datu-transmisioaren maiztasuna ezartzen du maisuan edo erloju-seinalea jasotzen du esklaboan. Funtsean beats jotzea;
SS, Slave Select: kanal honen laguntzaz, esklaboak badaki berarengandik zerbait nahi duela. STM32n NSS deitzen da, non N = negatiboa, hau da. kontrolagailua esklabo bihurtzen da kanal honetan lurra badago. Ondo konbinatzen da Open Drain Output moduarekin, baina hori beste istorio bat da.
Beste guztia bezala, SPI-n STM32 funtzionalitate aberatsa da, eta horrek ulertzea zaila egiten du. Esate baterako, SPIrekin ez ezik, I2S interfaze batekin ere lan egin dezake, eta dokumentazioan haien deskribapenak nahasten dira, beharrezkoa da soberan moztea garaiz. Gure zeregina oso erraza da: datuak MOSI eta SCK erabiliz soilik bidali behar ditugu. 25.3.4 atalera joango gara (half-duplex komunikazioa, half-duplex komunikazioa), non aurkituko dugun Erloju 1 eta noranzko bakarreko datu-hari bat (erloju-seinale 1 eta noranzko bakarreko datu-korronte 1):
Modu honetan, aplikazioak SPI erabiltzen du transmisiorako edo jasotzeko soilik moduan. / Transmititzeko soilik modua duplex moduaren antzekoa da: datuak transmisioko pinean transmititzen dira (MOSI master moduan edo MISO esklabo moduan), eta jasotzeko pina (MISO edo MOSI hurrenez hurren) I/O pin arrunt gisa erabil daiteke. . Kasu honetan, aplikazioak Rx buffer-a alde batera utzi behar du (irakurtzen bada, ez da bertan transferituko daturik egongo).
Bikaina, MISO pina doakoa da, konekta dezagun LAT seinalea. Ikus dezagun Slave Select, STM32n programatikoki kontrola daitekeena, oso erosoa dena. Izen bereko paragrafoa irakurri dugu 25.3.1 SPIren Deskribapen Orokorra atalean:
Software-kontrola NSS (SSM = 1) / Esklaboen hautaketaren informazioa SPI_CR1 erregistroko SSI bit-ean dago. Kanpoko NSS pinak aske izaten jarraitzen du beste aplikazioen beharretarako.
Erregistroetara idazteko ordua da. SPI2 erabiltzea erabaki nuen, bere oinarrizko helbidea bilatu datu-orrian - 3.3 Memoria-mapa atalean:
Ireki 25.3.3 atala "SPI modu nagusian konfiguratzea" izenburua duen auto-azalpenarekin:
1. Ezarri serieko erlojuaren maiztasuna BR[2:0] bitekin SPI_CR1 erregistroan.
Erregistroak izen bereko erreferentziazko eskuliburuaren atalean biltzen dira. Helbide aldaketa (Helbide-desplazamendua) CR1 - 0x00-rako, lehenespenez bit guztiak garbitzen dira (Berrezarri balioa 0x0000):
BR bitek kontroladorearen erlojuaren zatitzailea ezartzen dute, horrela SPIak funtzionatuko duen maiztasuna zehazten du. Gure STM32 maiztasuna 72 MHz izango da, LED kontrolatzaileak, bere datu-orriaren arabera, 25 MHz arteko maiztasunarekin funtzionatzen du, beraz, lautan banatu behar dugu (BR[2:0] = 001).
2. Ezarri CPOL eta CPHA bitak datu-transferentziaren eta serieko erlojuaren denboraren arteko erlazioa definitzeko (ikus 240. orrialdeko diagrama)
Hemen datu-orri bat irakurtzen ari garenez eta eskemak aztertzen ez ditugunez, ikus ditzagun CPOL eta CPHA biten testu-deskribapena 704. orrialdean (SPIren Deskribapen Orokorra):
Erlojuaren fasea eta polaritatea
SPI_CR1 erregistroko CPOL eta CPHA bitak erabiliz, programatikoki lau denbora-erlazio hauta ditzakezu. CPOL (erlojuaren polaritatea) bitak erlojuaren seinalearen egoera kontrolatzen du daturik transmititzen ez denean. Bit honek maisu eta esklabo moduak kontrolatzen ditu. CPOL berrezartzen bada, SCK pina baxua da atseden moduan. CPOL bit ezarrita badago, SCK pina altua da atseden moduan.
CPHA (erloju-fasea) bit ezarrita dagoenean, bit handiko tranpa estrobokoa SCK seinalearen bigarren ertza da (jaisten da CPOL garbi badago, igotzen da CPOL ezarrita badago). Erlojuaren seinalearen bigarren aldaketak jasotzen ditu datuak. CPHA bit garbia bada, bit handiko tranpa estrobokoa SCK seinalearen goranzko ertza da (jaitsiera ertza CPOL ezarrita badago, goranzko ertza CPOL garbitzen bada). Datuak erlojuaren seinalearen lehen aldaketan jasotzen dira.
Ezagutza hori bereganatu ondoren, bi bitek zero geratu behar dutela ondorioztatuko dugu, zeren SCK seinalea baxua izatea nahi dugu erabiltzen ez denean, eta datuak pultsuaren goranzko ertzean transmititzea (ikus. Goranzko ertza DM634 fitxan).
Bide batez, hemen lehen aldiz topatu dugu hiztegiaren ezaugarri bat ST datu-orrietan: horietan "berrezarri bit zerora" esaldia idazten da. pixka bat berrezartzekoEta ez pixka bat garbitzeko, adibidez, Atmega.
3. Ezarri DFF bit-a datu-blokea 8 biteko edo 16 biteko formatua den zehazteko
Zehazki, 16 biteko DM634 bat hartu nuen, 12 biteko PWM datuak transmititzeko trabarik ez izateko, DM633 bezala. Zentzuzkoa da DFF bat ezartzea:
4. Konfiguratu LSBFIRST bit SPI_CR1 erregistroan bloke-formatua zehazteko
LSBFIRST-ek, bere izenak dioen bezala, bit esanguratsu gutxien duen transmisioa konfiguratzen du lehenik. Baina DM634-k datuak jaso nahi ditu bit esanguratsuenetik hasita. Hori dela eta, berrezarri uzten dugu.
5. Hardware moduan, NSS pinaren sarrera behar bada, aplikatu seinale altua NSS pinari byte-transferentzia-sekuentzia osoan zehar. NSS software moduan, ezarri SSM eta SSI bitak SPI_CR1 erregistroan. NSS pina irteera gisa erabili behar bada, SSOE bit bakarra ezarri behar da.
Instalatu SSM eta SSI NSS hardware modua ahazteko:
#define SSI 0x0100
#define SSM 0x0200
_SPI2_ (_SPI_CR1) |= SSM | SSI; //enable software control of SS, SS high
6. MSTR eta SPE bitak ezarri behar dira (NSS seinalea altua bada soilik ezarrita geratzen dira)
Egia esan, bit hauekin gure SPI maisu izendatzen dugu eta aktibatu egiten dugu:
SPI konfiguratuta dago, idatz ditzagun berehala kontrolatzaileari byteak bidaltzen dituzten funtzioak. Jarraitu irakurtzen 25.3.3 "SPI modu nagusian konfiguratzea":
Datuak transferitzeko agindua
Transmisioa Tx bufferean byte bat idazten denean hasten da.
Datu-bytea desplazamendu-erregistroan kargatzen da paraleloa modua (barneko busetik) lehenengo bitaren transmisioan zehar, eta gerora igortzen da sekuentziala MOSI pin modua, lehen edo azken bit aurreratzea CPI_CR1 erregistroko LSBFIRST bitaren ezarpenaren arabera. TXE bandera datuak transmititu ondoren ezartzen da Tx buffer-etik desplazamendu-erregistrora, eta eten bat ere sortzen du CPI_CR1 erregistroko TXEIE bita ezartzen bada.
Itzulpenean hitz batzuk nabarmendu ditut STM kontrolagailuetan SPI ezarpenaren ezaugarri bati arreta erakartzeko. Atmegan TXE bandera (Tx Hutsik, Tx hutsik dago eta datuak jasotzeko prest) byte osoa bidali ondoren bakarrik ezartzen da kanpora. Eta hemen bandera hau ezartzen da bytea barneko desplazamendu-erregistroan sartu ondoren. Bit guztiekin batera bultzatzen denez (paraleloan), eta gero datuak sekuentzialki transferitzen direnez, TXE ezartzen da bytea guztiz bidali aurretik. Hau garrantzitsua delako gure LED kontrolatzailearen kasuan, LAT pin-a atera behar dugu bidali ondoren guztiak datuak, alegia. TXE bandera bakarrik ez zaigu nahikoa izango.
Horrek esan nahi du beste bandera bat behar dugula. Ikus dezagun 25.3.7 - "Egoera banderak":
<...>
BUSY bandera
BSY bandera hardwareak ezarri eta garbitzen du (bertan idazteak ez du eraginik). BSY banderak SPI komunikazio-geruzaren egoera adierazten du.
Berrezarri egiten da:
transferentzia amaitzen denean (modu nagusian izan ezik, transferentzia etengabea bada)
SPI desgaituta dagoenean
Master mode errore bat gertatzen denean (MODF=1)
Transferentzia etengabea ez bada, BSY bandera garbituko da datu-transferentzia bakoitzaren artean
Ados, hau ondo etorriko zaizu. Ea non dagoen Tx buffera. Horretarako, irakurri "SPI Data Register":
Bits 15:0 DR[15:0] Datu-erregistroa
Jasotako datuak edo transmititu beharreko datuak.
Datu-erregistroa bi bufferetan banatzen da: bat idazteko (igortzeko buffer) eta bestea irakurtzeko (jasotzeko buffer). Datu-erregistroan idazteak Tx bufferean idazten du, eta datu-erregistrotik irakurtzeak Rx bufferean jasotako balioa itzuliko du.
Beno, eta egoera erregistroa, non TXE eta BSY banderak aurkitzen diren:
Tira, 16 aldiz bi byte transmititu behar ditugunez, LED kontrolatzaileen irteera kopuruaren arabera, honelako zerbait:
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();
}
Baina oraindik ez dakigu LAT pina nola atera, beraz I/Ora itzuliko gara.
Pinak esleitzea
STM32F1-n, pinen egoeraz arduratzen diren erregistroak nahiko ezohikoak dira. Argi dago Atmega baino gehiago daudela, baina beste STM txipetatik ere desberdinak dira. 9.1 Atala GPIOren Deskribapen Orokorra:
Helburu orokorreko I/O ataka bakoitza (GPIO) 32 biteko konfigurazio-erregistro bi ditu (GPIOx_CRL eta GPIOx_CRH), 32 biteko datu-erregistro bi (GPIOx_IDR eta GPIOx_ODR), 32 biteko ezarri/berrezartzeko erregistroa (GPIOx_BSRR), 16 biteko berrezartzeko erregistroa (GPIOx_BRR) eta 32 biteko. bit blokeatzeko erregistroa (GPIOx_LCKR).
Lehenengo bi erregistroak ezohikoak dira, eta, gainera, nahiko deserosoak, 16 ataka-pinak "anaia bakoitzeko lau bit" formatuan sakabanatuta daudelako. Horiek. zerotik zazpira arteko pinak CRLn daude, eta gainerakoak CRHn. Aldi berean, gainerako erregistroek portuko pin guztien bitak dituzte arrakastaz, askotan erdia "erreserbatuta" geratzen da.
Sinpletasuna lortzeko, has gaitezen zerrendaren amaieratik.
Ez dugu blokeatzeko erregistrorik behar.
Ezarri eta berrezarri erregistroak nahiko dibertigarriak dira, partzialki bikoiztu egiten direlako: dena BSRRn bakarrik idatz dezakezu, non 16 bit altuenak pina zerora berrezartuko baitute, eta behekoak 1ean ezarriko diren edo, gainera erabili BRR, beheko 16 bitak pina berrezarri baino ez dutenak. Bigarren aukera gustatzen zait. Erregistro hauek garrantzitsuak dira pinetarako sarbidea atomikoa ematen dutelako:
Atomic Set edo Berrezarri
Ez dago etenak desgaitu beharrik GPIOx_ODR bit mailan programatzean: bit bat edo gehiago alda daitezke APB2 idazketa atomikoko eragiketa bakarrarekin. Hau aldatu behar den bitaren "1" bat idatziz lortzen da ezarri/berrezarri erregistroan (GPIOx_BSRR edo, berrezarri soilik, GPIOx_BRR). Beste bitak aldatu gabe geratuko dira.
Datu-erregistroek izen nahiko argiak dituzte - IDR = Sarrerako Norabide-erregistroa, sarrera-erregistroa; ODR = Output Norabide-erregistroa, irteera-erregistroa. Oraingo proiektuan ez ditugu beharko.
Eta azkenik, kontrol-erregistroak. Bigarren SPI pinak, hots, PB13, PB14 eta PB15, interesatzen zaizkigunez, berehala begiratzen diogu CRHri:
Eta ikusten dugu 20tik 31ra bitetan zerbait idatzi beharko dugula.
Dagoeneko irudikatu dugu zer nahi dugun pinetatik goian, beraz, hemen pantaila-argazkirik gabe egingo dut, esango dut MODE-k norabidea (sarrera bi bitak 0-an ezarrita badaude) eta pin abiadura (50MHz behar ditugu, hau da, zehazten dituela). biak "1"), eta CNF-k modua ezartzen du: ohiko "push-pull" - 00, "alternatiboa" - 10. Lehenespenez, goian ikusten dugun bezala, pin guztiek dute behetik hirugarren bita (CNF0), moduan jartzen ditu sarrera flotagarria.
Txip honekin beste zerbait egiteko asmoa dudanez, sinpletasunerako MODE eta CNF balio posible guztiak definitu ditut beheko zein goiko kontrol-erregistroetarako.
(LAT_baxua inertziagatik, beti izan da horrela, egon dadila)
Orain dena bikaina da, baina ez du funtzionatzen. Hau STM32 denez, elektrizitatea aurrezten dute, hau da, beharrezkoak diren periferikoen erlojua gaitu behar duzu.
Aktibatu erlojua
Erlojua, Erlojua izenez ere ezaguna, erlojuaren arduraduna da. Eta dagoeneko RCC laburdura nabaritu genezake. Dokumentazioan bilatzen dugu: Berrezarri eta Erlojuaren Kontrola da.
Goian esan bezala, zorionez, erlojupekoaren gaiaren zatirik zailena STMko jendeak egin zigun, eta horregatik asko eskertzen dugu (beste behin ere esteka bat emango dizuet Di Halten webgunea, zein nahasia den argi uzteko). Erloju periferikoa gaitzeaz arduratzen diren erregistroak baino ez ditugu behar (Erloju Periferikoa Gaitu Erregistroak). Lehenik eta behin, aurki dezagun RCC-ren oinarrizko helbidea, "Memoriaren mapa"ren hasieran dago:
Eta gero, egin klik plakan zerbait aurkitzen saiatzen zaren estekan, edo, askoz hobeto, joan gaikuntza-erregistroen deskribapenei buruzko ataletan. erregistroak gaitu. Non aurkituko ditugu RCC_APB1ENR eta RCC_APB2ENR:
Eta, horren arabera, SPI2, IOPB (I/O Port B) eta funtzio alternatiboak (AFIO) erlojua barne hartzen duten bitak dituzte.
Proba egiteko aukera eta gogoa baduzu, konektatu DM634 honela: DAI PB15-ra, DCK-ra PB13ra, LAT-ra PB14ra. Gidaria 5 voltiotik elikatzen dugu, ez ahaztu lurrak konektatzea.
STM8 PWM
PWM STM8-n
Artikulu hau planifikatzen ari nintzela, erabaki nuen, adibide gisa, txip ezezagun baten funtzionalitate batzuk menperatzen saiatzea datu-orri bat soilik erabiliz, botarik gabeko zapatari batekin bukatzeko. STM8 aproposa zen rol honetarako: lehenik eta behin, STM8S103-rekin txinatar plaka pare bat neukan, eta, bigarrenik, ez da oso ezaguna, eta, beraz, Interneten irakurtzeko eta irtenbide bat bilatzeko tentazioa irtenbide horien faltan oinarritzen da.
Berez, STM8-k 2 MHz-ko maiztasunean funtzionatzen du, hau berehala zuzendu behar da.
HSI (Abiadura Handiko Barne) Erlojua
HSI erloju-seinalea 16 MHz-ko barneko RC osziladore batetik ateratzen da, banatzaile programagarri batekin (1etik 8ra). Erlojuaren zatitzailearen erregistroan ezartzen da (CLK_CKDIVR).
Oharra: hasieran, 8ko zatitzailea duen HSI RC osziladore bat hautatzen da erloju-seinalearen iturri nagusi gisa.
Erregistroaren helbidea datu-orrian aurkitzen dugu, refman-en deskribapena eta erregistroa garbitu behar dela ikusten dugu:
PWM exekutatu eta LEDak konektatuko ditugunez, ikus dezagun pinout-a:
Txipa txikia da, funtzio asko pin berdinetan esekita daude. Kortxete artean dagoena "funtzionalitate alternatiboa" da, "aukera byteen bidez" aldatzen da (aukera byteak) - Atmega fusibleak bezalako zerbait. Beren balioak programatikoki alda ditzakezu, baina ez da beharrezkoa Funtzio berria berrabiarazi ondoren bakarrik aktibatzen da. Errazagoa da ST Visual Programmer erabiltzea (Visual Develop-ekin deskargatua), byte hauek alda ditzake. Pinoutak erakusten du lehen tenporizadorearen CH1 eta CH2 pinak kortxete artean ezkutatuta daudela; beharrezkoa da AFR1 eta AFR0 bitak STVPn ezartzea, eta bigarrenak bigarren tenporizadorearen CH1 irteera ere transferituko du PD4tik PC5era.
Horrela, 6 pinek kontrolatuko dituzte LEDak: PC6, PC7 eta PC3 lehen tenporizadorerako, PC5, PD3 eta PA3 bigarrenerako.
STM8n I/O pinak konfiguratzea STM32n baino sinpleagoa eta logikoagoa da:
Atmega DDR datuen norabide erregistrotik ezaguna (Datuen Zuzendaritza Erregistroa): 1 = irteera;
lehen kontrol-erregistroak CR1, irteeran, push-pull modua (1) edo draina irekia (0) ezartzen du; LEDak txiparekin katodoekin konektatzen ditudanez, zeroak uzten ditut hemen;
bigarren kontrol-erregistroak CR2, irteeran, erlojuaren abiadura ezartzen du: 1 = 10 MHz
PWM maiztasuna β tenporizadoreak markatzen duen maiztasuna;
Birkargatu automatikoa, AR β Autokargatu daitekeen balioa zenbatu arte tenporizadoreak (pultsu-aldia);
Eguneratzeko gertaera, UEV β tenporizadoreak AR zenbatu duenean gertatzen den gertaera bat;
PWM Duty Cycle β PWM betebehar-zikloa, askotan "betebehar-faktorea" deitua;
Harrapatu/Konparatu Balioa β Harrapatzeko/konparatzeko balioa, zeinari zenbatu zaion tenporizadoreak zerbait egingo du (PWM-ren kasuan, irteerako seinalea alderantzikatzen du);
Aurrekargatu balioa β aurrez kargatutako balioa. Konparatu balioa ezin da aldatu tenporizadorea martxan dagoen bitartean, bestela PWM zikloa hautsiko da. Hori dela eta, transmititutako balio berriak buffer batean jartzen dira eta tenporizadorea atzerako kontaketa amaierara iristen denean eta berrezartzen denean ateratzen dira;
Ertz lerrokatuta ΠΈ Zentroan lerrokatuta dauden moduak β lerrokadura mugan zehar eta erdialdean, Atmel-en berdina PWM azkarra ΠΈ Fase zuzeneko PWM.
OCiREF, Irteera Konparatu Erreferentzia Seinalea β erreferentzia irteerako seinalea, hain zuzen ere, dagokion pinean PWM moduan agertzen dena.
Pinoutetik argi ikusten denez, bi tenporizadorek PWM gaitasunak dituzte: lehenengoa eta bigarrena. Biak 16 bitekokoak dira, lehenengoak ezaugarri gehigarri asko ditu (bereziki, gora eta behera zenbatu ditzake). Biek berdin lan egin behar dugu, beraz, bistan denez pobreagoa den bigarrenarekin hastea erabaki nuen, ez dagoen zerbait ustekabean ez erabiltzeko. Arazoren bat da erreferentzia eskuliburuko tenporizadore guztien PWM funtzionalitatearen deskribapena lehen tenporizadoreari buruzko kapituluan dagoela (17.5.7 PWM modua), beraz, dokumentuan aurrera eta atzera egin behar duzu denbora guztian.
STM8-n PWM-k abantaila garrantzitsua du Atmega-n PWM-ren aldean:
Muga lerrokatuta PWM
Kontuaren konfigurazioa behetik gora
Behetik gorako zenbaketa aktiboa da TIM_CR1 erregistroko DIR bita garbitzen bada
Adibidea
Adibideak lehen PWM modua erabiltzen du. PWM erreferentzia-seinalea OCiREF altu mantentzen da TIM1_CNT < TIM1_CCRi bitartean. Bestela maila baxua behar da. TIM1_CCRi erregistroko konparazio-balioa autokarga-balioa baino handiagoa bada (TIM1_ARR erregistroa), OCiREF seinalea 1ean mantentzen da. Konparazio balioa 0 bada, OCiREF zeroan mantentzen da....
STM8 tenporizadorea zehar eguneratu gertaera egiaztapenak lehenik alderatu balioa, eta orduan soilik erreferentzia-seinalea sortzen du. Atmegaren tenporizadoreak lehenik eta behin izorratzen du eta gero konparatzen du, ondorioz compare value == 0 irteera orratz bat da, nolabait landu behar dena (adibidez, logika programatikoki alderantziz).
Beraz, zer egin nahi dugu: 8 biteko PWM (AR == 255), behetik gora kontatuta, ertzean zehar lerrokatzea. Bonbillak katodoen bidez txiparekin konektatuta daudenez, PWM-ak 0 atera beharko luke (LED piztuta) arte. alderatu balioa eta 1 ondoren.
Dagoeneko irakurri dugu batzuei buruz PWM modua, beraz, bigarren tenporizadorearen beharrezko erregistroa aurkituko dugu erreferentziazko eskuliburuan esaldi honen bilaketan (18.6.8 - TIMx_CCMR1):
110: Lehen PWM modua - behetik gora zenbatzen denean, lehen kanala aktibo dago TIMx_CNT < TIMx_CCR1 bitartean. Bestela, lehen kanala inaktibo dago. [Dokumentuan aurrerago 1. tenporizadoretik kopiatu-itsatsi oker bat dago] 111: Bigarren PWM modua β behetik gora zenbatzen denean, lehen kanala inaktibo dago TIMx_CNT < TIMx_CCR1 bitartean. Bestela, lehen kanala aktibo dago.
LEDak MK-ra katodoen bidez konektatzen direnez, bigarren modua egokitzen zaigu (lehena ere, baina oraindik ez dakigu).
3. bit OC1PE: Gaitu pin 1 aurrekarga
0: TIMx_CCR1-en aurrekargatzeko erregistroa desgaituta dago. TIMx_CCR1 helbidera idatz dezakezu edozein unetan. Balio berriak berehala funtzionatzen du.
1: TIMx_CCR1-en aurrekargatzeko erregistroa gaituta dago. Irakurketa/idazketa eragiketak aurrekarga-erregistrora sartzen dira. Aurrekargatutako TIMx_CCR1 balioa itzalen erregistroan kargatzen da eguneratze-gertaera bakoitzean.
*Oharra: PWM moduak behar bezala funtziona dezan, aurrekarga-erregistroak gaituta egon behar dira. Hau ez da beharrezkoa seinale bakarreko moduan (OPM bita TIMx_CR1 erregistroan ezartzen da).
Ados, aktibatu dezagun bigarren tenporizadorearen hiru kanaletarako behar dugun guztia:
Bigarren tenporizadoreak behetik gora bakarrik zenbatu dezake, ertzean lerrokatuta, ez da ezer aldatu behar. Ezar dezagun maiztasun zatitzailea, adibidez, 256. Bigarren tenporizadorerako, zatitzailea TIM2_PSCR erregistroan ezartzen da eta biko potentzia da:
Ondorioak eta bigarren tenporizadorea bera piztea besterik ez da geratzen. Lehenengo arazoa erregistroen bidez konpontzen da Harrapatu/Konparatu Gaitu: bi, hiru kanal daude asimetrikoki sakabanatuta. Hemen ere jakin dezakegu posible dela seinalearen polaritatea aldatzea, hau da. printzipioz, posible zen PWM 1. modua erabiltzea. Guk idazten dugu:
Idatz dezagun AnalogWrite(ren) analogo sinple bat, benetako balioak tenporizadorera transferituko dituena alderatzeko. Erregistroak aurreikusteko izendatzen dira Harrapatu/Konparatu erregistroak, kanal bakoitzerako bi daude: orden baxuko 8 bitak TIM2_CCRxL-n eta goi mailakoak TIM2_CCRxH-n. 8 biteko PWM bat sortu dugunez, nahikoa da bit esanguratsuenak bakarrik idaztea:
Irakurle adiak PWM apur bat akastuna dugula ohartuko da, ezin du % 100eko betetzerik sortu (255eko gehienezko balioarekin, seinalea tenporizadore-ziklo baterako alderantzikatu egiten da). LEDentzat ez du axola, eta irakurle adiak dagoeneko asma dezake nola konpondu.
Bigarren tenporizadorean PWM funtzionatzen du, joan gaitezen lehenengora.
Lehenengo tenporizadoreak bit berdinak ditu erregistro berdinetan (bigarren tenporizadorean "erreserbatuta" geratu ziren bit horiek lehengoan aktiboki erabiltzen direla gauza aurreratu guztietarako). Beraz, nahikoa da erregistro bereko helbideak datu-orrian aurkitzea eta kodea kopiatzea. Tira, aldatu maiztasun zatitzailearen balioa, zeren... lehen tenporizadoreak ez du biko potentzia jaso nahi, baizik eta 16 biteko balio zehatza bi erregistrotan Aurreskaler altua ΠΈ Behe-. Denetarik egiten dugu eta... lehen tenporizadoreak ez du funtzionatzen. Zein da ba arazoa?
Arazoa 1. tenporizadorearen kontrol-erregistroei buruzko atal osoa begiratuz bakarrik konpondu daiteke, non bigarren tenporizadoreak ez duena bilatzen dugun. Egongo dira 17.7.30 Eten erregistroa (TIM1_BKR), non dagoen bit hau:
Hirugarren mini-proiektua zortzi RGB LED bigarren tenporizadorearekin konektatzea da PWM moduan eta kolore desberdinak erakustea. LED multiplexaren kontzeptuan oinarritzen da, hau da, LEDak oso-oso azkar pizten eta itzaltzen badituzu, etengabe piztuta daudela irudituko zaigu (ikusmenaren iraunkortasuna, ikusmen-pertzepzioaren inertzia). Behin egin nuen horrelako zerbait Arduino-n.
Lan algoritmoa honelakoa da:
lehen RGB LEDaren anodoa konektatu;
piztu zuen, beharrezko seinaleak katodoetara bidaliz;
PWM zikloaren amaiera arte itxaron;
bigarren RGB LEDaren anodoa konektatu;
piztu zuen...
Bueno, etab. Jakina, funtzionamendu eder bat egiteko beharrezkoa da anodoa konektatuta egotea eta LEDa "piztea" aldi berean. Tira, edo ia. Nolanahi ere, bigarren tenporizadorearen hiru kanaletan balioak aterako dituen kode bat idatzi behar dugu, UEVra iristen denean aldatu eta aldi berean aktibo dagoen RGB LEDa aldatu.
LED aldatzea automatikoa denez, "bideo memoria" bat sortu behar dugu, non eten kudeatzaileak datuak jasoko dituen. Hau array sinple bat da:
uint8_t colors[8][3];
LED zehatz baten kolorea aldatzeko, nahikoa izango da behar diren balioak matrize honetan idaztea. Eta aldagaia LED aktiboaren kopuruaz arduratuko da
uint8_t cnt;
Demux
Multiplexatze egokia egiteko, bitxia bada ere, CD74HC238 demultiplexadorea behar dugu. Demultiplexer - operadorea hardwarean inplementatzen duen txipa <<. Sarrerako hiru pin bidez (0, 1 eta 2 bitak) hiru biteko X zenbaki bat elikatzen dugu, eta erantzun gisa irteera zenbakia aktibatzen du (1<<X). Txiparen gainerako sarrerak diseinu osoa eskalatzeko erabiltzen dira. Txip hau mikrokontrolagailuaren okupatutako pin kopurua murrizteko ez ezik, segurtasunerako ere behar dugu, nahi baino LED gehiago pizteko eta MK ez erretzeko. Txipa zentimo bat kostatzen da eta beti zure etxeko botikinean gorde behar da.
Gure CD74HC238 nahi den LEDaren anodoari tentsioa hornitzeaz arduratuko da. Multiplex osoa batean, zutabeari tentsioa emango lioke P-MOSFET baten bidez, baina demo honetan zuzenean posible da, izan ere 20 mA ateratzen du, arabera balorazio maximo absolutuak fitxan. Bertatik CD74HC238 fitxa teknikoa pinouts eta iruzur orri hau behar ditugu:
H = tentsio handiko maila, L = tentsio baxuko maila, X - berdin dio
E2 eta E1 lurrera konektatzen ditugu, E3, A0, A1 eta A3 STM5ko PD3, PC4, PC5 eta PC8 pinetara. Goiko taulak maila baxua eta altua dituenez, pin hauek push-pull pin gisa konfiguratzen ditugu.
PWM
Bigarren tenporizadorean PWM aurreko istorioan bezala konfiguratuta dago, bi desberdintasunekin:
Lehenik eta behin, etenaldia gaitu behar dugu Eguneratu gertaera (UEV) LED aktiboa txandakatzen duen funtzio bat deituko duena. Hau bit aldatuz egiten da Eguneratu Eten Gaitu izen adierazgarria duen erregistro batean
Bigarren aldea multiplexazioaren fenomenoari dago lotuta, esaterako ghosting β Diodoen distira parasitoa. Gure kasuan, baliteke tenporizadoreak, UEVn eten bat eragin duelako, markatzen jarraitzen duelako eta eten-kudeatzaileak ez duela denborarik LEDa pizteko tenporizadorea pinetan zerbait idazten hasi baino lehen. Honi aurre egiteko, logika alderantzikatu beharko duzu (0 = distira maximoa, 255 = ez dago ezer pizten) eta muturreko funtzio-zikloaren balioak saihestu beharko dituzu. Horiek. ziurtatu UEV ondoren LEDak guztiz itzaltzen direla PWM ziklo baterako.
Saihestu r, g eta b 255ean ezartzea eta gogoratu horiek erabiltzean alderantzikatu behar dituzula.
Etenaldiak
Eten baten funtsa da egoera jakin batzuetan txipak programa nagusia exekutatzen uzten duela eta kanpoko funtzioren bat deitzen duela. Etenaldiak kanpoko edo barneko eraginengatik gertatzen dira, tenporizadorea barne.
ST Visual Develop-en proiektu bat sortu genuenean, gainera main.c fitxategi misteriotsu batekin leiho bat jaso genuen stm8_interrupt_vector.c, proiektuan automatikoki sartuta. Fitxategi honetan, funtzio bat esleitzen zaio eten bakoitzari NonHandledInterrupt. Gure funtzioa nahi den etenarekin lotu behar dugu.
Fitxategiak eten bektoreen taula bat du, non behar ditugunak aurkituko ditugu:
Etenaldiak gaitzea besterik ez da geratzen. Hau muntatzaile komandoa erabiliz egiten da rim - bilatu beharko duzu Programazio Eskuliburua:
//enable interrupts
_asm("rim");
Mihiztatzaileen beste komando bat da sim - etenaldiak itzaltzen ditu. "Bideo memorian" balio berriak idazten ari diren bitartean itzali behar dira, momentu okerrean eragindako eten batek array-a honda ez dezan.
Gutxienez norbaitek artikulu hau erabilgarria ikusten badu, ez dut alferrik idatzi. Pozik jasoko ditut iruzkinak eta oharrak, guztia erantzuten saiatuko naiz.