Soma hifadhidata 2: SPI kwenye STM32; PWM, vipima muda na kukatizwa kwenye STM8
Π sehemu ya kwanza Nilijaribu kuwaambia wahandisi wa vifaa vya elektroniki vya hobby ambao walikua kutoka kwa suruali ya Arduino jinsi na kwa nini wanapaswa kusoma hifadhidata na nyaraka zingine za vidhibiti vidogo. Maandishi yaligeuka kuwa makubwa, kwa hiyo niliahidi kuonyesha mifano ya vitendo katika makala tofauti. Kweli, alijiita uyoga wa maziwa ...
Leo nitakuonyesha jinsi ya kutumia hifadhidata kutatua rahisi sana, lakini muhimu kwa miradi mingi, kazi kwenye STM32 (Kidonge cha Bluu) na vidhibiti vya STM8. Miradi yote ya demo imejitolea kwa LED zangu zinazopenda, tutawaangazia kwa kiasi kikubwa, ambayo tutalazimika kutumia kila aina ya pembeni za kuvutia.
Maandishi tena yaligeuka kuwa makubwa, kwa hivyo kwa urahisi ninatayarisha yaliyomo:
Kanusho: Mimi si mhandisi, sijifanyi kuwa nina maarifa ya kina katika vifaa vya elektroniki, nakala hiyo imekusudiwa wafadhili kama mimi. Kwa kweli, nilijiona miaka miwili iliyopita kama walengwa. Ikiwa mtu angeniambia basi kwamba hifadhidata kwenye chip isiyojulikana hazikutisha kusoma, nisingetumia muda mwingi kutafuta vipande vya msimbo kwenye Mtandao na kuvumbua magongo yenye mkasi na mkanda wa wambiso.
Lengo la kifungu hiki ni kwenye hifadhidata, sio miradi, kwa hivyo msimbo unaweza kuwa sio safi sana na mara nyingi ni duni. Miradi yenyewe ni rahisi sana, ingawa inafaa kwa kufahamiana kwa kwanza na chip mpya.
Natumaini kwamba makala yangu itasaidia mtu katika hatua sawa ya kuzamishwa katika hobby.
ST32
LEDs 16 zenye DM634 na SPI
Mradi mdogo unaotumia Kidonge cha Bluu (STM32F103C8T6) na kiendeshi cha LED DM634. Kwa kutumia hifadhidata, tutagundua dereva, bandari za STM IO na kusanidi SPI.
DM634
Chip ya Taiwan yenye matokeo 16 ya 16-bit PWM, inaweza kuunganishwa kwa minyororo. Mfano wa chini wa 12-bit unajulikana kutoka kwa mradi wa ndani Lightpack. Wakati mmoja, kuchagua kati ya DM63x na TLC5940 inayojulikana, nilichagua DM kwa sababu kadhaa: 1) TLC kwenye Aliexpress ni dhahiri bandia, lakini hii sio; 2) DM ina PWM ya uhuru na jenereta yake ya mzunguko; 3) inaweza kununuliwa kwa gharama nafuu huko Moscow, badala ya kusubiri sehemu kutoka kwa Ali. Na, bila shaka, ilikuwa ya kuvutia kujifunza jinsi ya kudhibiti chip mwenyewe, badala ya kutumia maktaba iliyopangwa tayari. Chips sasa zinawasilishwa hasa katika kifurushi cha SSOP24; ni rahisi kuuzwa kwa adapta.
Kwa kuwa mtengenezaji ni wa Taiwan, karatasi ya data chip imeandikwa kwa Kiingereza cha Kichina, ambayo inamaanisha itakuwa ya kufurahisha. Kwanza tunaangalia pinout (Muunganisho wa Pini) kuelewa ni mguu gani wa kuunganisha nini, na maelezo ya pini (Maelezo ya Pini) 16 pini:
Vyanzo vya Kuzama vya DC (Mfereji wa maji wazi)
Punguza / Pato la mkondo wa wazi - kukimbia; chanzo cha mtiririko wa maji; pato ni kushikamana na ardhi katika hali ya kazi - LEDs ni kushikamana na dereva na cathodes. Kwa umeme, hii, kwa kweli, sio "mifereji ya maji wazi" (fungua bomba), lakini katika hifadhidata jina hili la pini katika hali ya kukimbia mara nyingi hupatikana.
Vipinga vya nje kati ya REXT na GND ili kuweka thamani ya sasa ya pato
Kipinga marejeleo kimewekwa kati ya pini ya REXT na ardhi, ambayo inadhibiti upinzani wa ndani wa matokeo, angalia grafu kwenye ukurasa wa 9 wa hifadhidata. Katika DM634, upinzani huu pia unaweza kudhibitiwa na programu, kuweka mwangaza wa jumla (mwangaza wa kimataifa); Sitaingia katika maelezo katika makala hii, nitaweka tu kupinga 2.2 - 3 kOhm hapa.
Ili kuelewa jinsi ya kudhibiti chip, hebu tuangalie maelezo ya kiolesura cha kifaa:
Ndio, hii hapa, Kiingereza cha Kichina katika utukufu wake wote. Kutafsiri hii ni shida, unaweza kuielewa ikiwa unataka, lakini kuna njia nyingine - angalia jinsi unganisho la TLC5940 inayofanya kazi inavyofafanuliwa kwenye hifadhidata:
... Pini tatu tu zinahitajika ili kuingiza data kwenye kifaa. Makali ya kuongezeka kwa ishara ya SCLK huhamisha data kutoka kwa pini ya SIN hadi rejista ya ndani. Baada ya data zote kupakiwa, ishara fupi ya juu ya XLAT hufunga data iliyohamishwa kwa mfuatano kwenye rejista za ndani. Daftari za ndani ni milango inayosababishwa na kiwango cha ishara cha XLAT. Data zote hupitishwa muhimu zaidi kwanza.
Latch β latch/latch/lock. Kupanda kwa makali - makali ya mbele ya mapigo MSB kwanza - muhimu zaidi (kushoto) mbele kidogo. kwa data ya saa - Sambaza data kwa mfuatano (kidogo kidogo).
Neno latch mara nyingi hupatikana katika nyaraka za chips na hutafsiriwa kwa njia mbalimbali, kwa hiyo kwa ajili ya kuelewa nitajiruhusu
programu ndogo ya elimuKiendeshaji cha LED kimsingi ni rejista ya mabadiliko. "Shift" (kuhama) kwa jina - mwendo wa data kwa busara ndani ya kifaa: kila biti mpya inayosukumwa ndani husukuma mnyororo mzima mbele yake. Kwa kuwa hakuna mtu anataka kuona kufumba kwa taabu kwa taa za LED wakati wa zamu, mchakato huo unafanyika katika rejista za bafa zilizotenganishwa na rejista za kufanya kazi na damper (latch) ni aina ya chumba cha kusubiri ambapo bits hupangwa katika mlolongo unaohitajika. Wakati kila kitu kiko tayari, shutter inafungua na bits kwenda kufanya kazi, kuchukua nafasi ya kundi la awali. Neno latch katika nyaraka za microcircuits karibu daima ina maana damper vile, bila kujali ni mchanganyiko gani hutumiwa.
Kwa hivyo, uhamishaji wa data kwa DM634 unafanywa kama hii: kuweka pembejeo ya DAI kwa thamani ya sehemu muhimu zaidi ya LED ya mbali, vuta DCK juu na chini; weka pembejeo ya DAI kwa thamani ya kidogo inayofuata, vuta DCK; na kadhalika hadi biti zote zimepitishwa (akaingia), baada ya hapo tunavuta LAT. Hii inaweza kufanywa kwa mikono (kidogo-bang), lakini ni bora kutumia interface ya SPI iliyoundwa mahsusi kwa hili, kwani imewasilishwa kwenye STM32 yetu katika nakala mbili.
Kidonge cha Bluu STM32F103
Utangulizi: Vidhibiti vya STM32 ni ngumu zaidi kuliko Atmega328 kuliko vinaweza kuonekana kuwa vya kutisha. Zaidi ya hayo, kwa sababu za kuokoa nishati, karibu vifaa vyote vya pembeni vimezimwa mwanzoni, na mzunguko wa saa ni 8 MHz kutoka kwa chanzo cha ndani. Kwa bahati nzuri, waandaaji wa programu za STM waliandika msimbo ambao huleta chip hadi "iliyohesabiwa" 72 MHz, na waandishi wa IDE zote ninazojua waliijumuisha katika utaratibu wa uanzishaji, kwa hivyo hatuitaji saa (lakini unaweza kama kweli unataka) Lakini itabidi uwashe vifaa vya pembeni.
Nyaraka: Kidonge cha Bluu kimewekwa na chip maarufu cha STM32F103C8T6, kuna hati mbili muhimu kwa hiyo:
Data Karatasi kwa microcontrollers STM32F103x8 na STM32F103xB;
Pinouts - chip pinouts - ikiwa tutaamua kutengeneza bodi wenyewe;
Ramani ya Kumbukumbu - ramani ya kumbukumbu kwa chip maalum. Mwongozo wa Marejeleo una ramani ya mstari mzima, na unataja rejista ambazo zetu hazina.
Jedwali la Ufafanuzi wa Pini - kuorodhesha kazi kuu na mbadala za pini; kwa "kidonge cha bluu" unaweza kupata picha zinazofaa zaidi kwenye mtandao na orodha ya pini na kazi zao. Kwa hivyo, mara moja tunatafuta kidonge cha Blue Pill na kuweka picha hii karibu:
NB: kulikuwa na hitilafu kwenye picha kutoka kwenye mtandao, ambayo ilibainishwa kwenye maoni, asante kwa hilo. Picha imebadilishwa, lakini hii ni somo - ni bora kuangalia habari sio kutoka kwa hifadhidata.
Tunaondoa hifadhidata, kufungua Mwongozo wa Marejeleo, na kuanzia sasa tunaitumia tu.
Utaratibu: tunashughulika na pembejeo / pato la kawaida, sanidi SPI, washa vifaa vya pembeni muhimu.
Ingizo
Kwenye Atmega328, I/O inatekelezwa kwa urahisi sana, ndiyo sababu wingi wa chaguzi za STM32 zinaweza kutatanisha. Sasa tunahitaji tu hitimisho, lakini hata hizi zina chaguzi nne:
fungua mifereji ya maji, sukuma-vuta, sukuma-vuta mbadala, bomba mbadala wazi
"Vuta-sukuma" (sukuma-vuta) ni pato la kawaida kutoka kwa Arduino, pini inaweza kuchukua thamani ama HIGH au LOW. Lakini kwa "kukimbia wazi" kuna matatizo, ingawa kwa kweli kila kitu ni rahisi hapa:
Usanidi wa pato / wakati bandari imepewa pato: / bafa ya pato imewezeshwa: / - fungua hali ya kukimbia: "0" kwenye rejista ya pato huwezesha N-MOS, "1" kwenye rejista ya pato huacha bandari katika hali ya Hi-Z ( P-MOS haijaamilishwa ) / β hali ya kusukuma-kuvuta: "0" kwenye rejista ya pato huwasha N-MOS, "1" kwenye rejista ya pato huwasha P-MOS.
Tofauti zote kati ya kukimbia wazi (fungua bomba) kutoka kwa βsukuma-vutaβ (sukuma-vuta) ni kwamba katika pini ya kwanza haiwezi kukubali hali ya HIGH: wakati wa kuandika moja kwa rejista ya pato, huenda kwenye hali ya juu ya upinzani (high impedance, Hi-Z) Wakati wa kuandika sifuri, pini hufanya sawa katika njia zote mbili, kwa mantiki na kwa umeme.
Katika hali ya kawaida ya pato, pini inatangaza tu yaliyomo kwenye rejista ya pato. Katika "mbadala" inadhibitiwa na vifaa vya pembeni vinavyolingana (ona 9.1.4):
Ikiwa biti la mlango litawekwa kama pini mbadala ya kukokotoa, rejista ya pini itazimwa na pini itaunganishwa kwenye pini ya pembeni.
Utendaji mbadala wa kila pini umeelezewa ndani Ufafanuzi wa Pini Hifadhidata iko kwenye picha iliyopakuliwa. Kwa swali la nini cha kufanya ikiwa pini ina kazi kadhaa mbadala, jibu linatolewa na maelezo ya chini kwenye hifadhidata:
Iwapo vifaa vingi vya pembeni vitatumia pini moja, ili kuepuka mgongano kati ya vitendakazi mbadala, ni kifaa kimoja tu cha pembeni kinachopaswa kutumika kwa wakati mmoja, kugeuzwa kwa kutumia saa ya pembeni kuwasha biti (katika rejista ifaayo ya RCC).
Hatimaye, pini katika hali ya pato pia zina kasi ya saa. Hiki ni kipengele kingine cha kuokoa nishati; kwa upande wetu, tunaiweka kwa kiwango cha juu na kuisahau.
Kwa hiyo: tunatumia SPI, ambayo ina maana kwamba pini mbili (zilizo na data na ishara ya saa) zinapaswa kuwa "kazi mbadala ya kusukuma-kuvuta", na nyingine (LAT) inapaswa kuwa "kusukuma-kuvuta mara kwa mara". Lakini kabla ya kuwakabidhi, wacha tushughulike na SPI.
SPI
Mpango mwingine mdogo wa elimu
SPI au Serial Peripheral Interface (kiolesura cha pembeni cha mfululizo) ni kiolesura rahisi na kizuri sana cha kuunganisha MK na MK zingine na ulimwengu wa nje kwa ujumla. Kanuni ya uendeshaji wake tayari imeelezwa hapo juu, ambapo kuhusu dereva wa Kichina wa LED (katika mwongozo wa kumbukumbu, angalia sehemu ya 25). SPI inaweza kufanya kazi katika hali ya bwana ("bwana") na mtumwa ("mtumwa"). SPI ina njia nne za kimsingi, ambazo sio zote zinaweza kutumika:
MOSI, Pato Kuu / Ingizo la Mtumwa: pini hii inasambaza data katika hali kuu, na kupokea data katika hali ya mtumwa;
MISO, Pembejeo ya Mwalimu / Pato la Mtumwa: kinyume chake, inapokea kwa bwana, na kupitisha mtumwa;
SCK, Saa ya Saa: huweka mzunguko wa maambukizi ya data kwa bwana au kupokea ishara ya saa katika mtumwa. Kimsingi kupiga beats;
SS, Slave Select: kwa msaada wa kituo hiki, mtumwa anajua kwamba kuna kitu kinachohitajika kutoka kwake. Kwenye STM32 inaitwa NSS, ambapo N = hasi, i.e. mtawala anakuwa mtumwa ikiwa kuna msingi katika kituo hiki. Inachanganya vyema na hali ya Open Drain Output, lakini hiyo ni hadithi nyingine.
Kama kila kitu kingine, SPI kwenye STM32 ina utendakazi mwingi, ambayo inafanya kuwa ngumu kuelewa. Kwa mfano, inaweza kufanya kazi si tu kwa SPI, lakini pia kwa interface ya I2S, na katika nyaraka maelezo yao yamechanganywa, ni muhimu kukata ziada kwa wakati unaofaa. Kazi yetu ni rahisi sana: tunahitaji tu kutuma data kwa kutumia MOSI na SCK pekee. Tunaenda kwenye sehemu ya 25.3.4 (mawasiliano ya nusu-duplex, mawasiliano ya nusu-duplex), ambapo tunapata Saa 1 na waya 1 ya data ya unidirectional (mawimbi ya saa 1 na mtiririko 1 wa data unidirectional):
Katika hali hii, programu hutumia SPI katika hali ya kusambaza pekee au ya kupokea pekee. / Hali ya kutuma pekee inafanana na hali ya duplex: data hupitishwa kwenye pini ya kupitisha (MOSI katika hali kuu au MISO katika hali ya mtumwa), na pini ya kupokea (MISO au MOSI mtawalia) inaweza kutumika kama pini ya kawaida ya I/O. . Katika kesi hii, programu inahitaji tu kupuuza bafa ya Rx (ikiwa inasomwa, hakutakuwa na data iliyohamishwa hapo).
Kubwa, pini ya MISO ni bure, wacha tuunganishe ishara ya LAT nayo. Wacha tuangalie Slave Select, ambayo kwenye STM32 inaweza kudhibitiwa kwa utaratibu, ambayo ni rahisi sana. Tunasoma aya ya jina moja katika sehemu ya 25.3.1 SPI Maelezo ya Jumla:
Udhibiti wa programu NSS (SSM = 1) / Maelezo ya uteuzi wa watumwa yamo katika sehemu ndogo ya SSI ya rejista ya SPI_CR1. Pini ya NSS ya nje inasalia bila malipo kwa mahitaji mengine ya programu.
Ni wakati wa kuandika kwa rejista. Niliamua kutumia SPI2, tafuta anwani yake ya msingi kwenye hifadhidata - katika sehemu ya 3.3 Ramani ya Kumbukumbu:
Fungua sehemu ya 25.3.3 yenye kichwa kinachojieleza "Kuweka SPI katika Hali Kuu":
1. Weka mzunguko wa saa wa mfululizo na biti BR[2:0] kwenye rejista ya SPI_CR1.
Rejesta hukusanywa katika sehemu ya mwongozo ya kumbukumbu ya jina moja. Kuhama kwa anwani (Urekebishaji wa anwani) kwa CR1 - 0x00, kwa chaguo-msingi bits zote zinafutwa (Weka upya thamani 0x0000):
Biti za BR huweka mgawanyiko wa saa ya mtawala, na hivyo kuamua mzunguko ambao SPI itafanya kazi. Frequency yetu ya STM32 itakuwa 72 MHz, dereva wa LED, kulingana na hifadhidata yake, inafanya kazi na mzunguko wa hadi 25 MHz, kwa hivyo tunahitaji kugawanya na nne (BR[2:0] = 001).
2. Weka biti za CPOL na CPHA ili kufafanua uhusiano kati ya uhamisho wa data na muda wa mfululizo wa saa (ona mchoro kwenye ukurasa wa 240)
Kwa kuwa tunasoma hifadhidata hapa na hatuangalii miundo, hebu tuangalie kwa karibu maelezo ya maandishi ya biti za CPOL na CPHA kwenye ukurasa wa 704 (Maelezo ya Jumla ya SPI):
Awamu ya saa na polarity
Kwa kutumia vipande vya CPOL na CPHA vya rejista ya SPI_CR1, unaweza kuchagua mahusiano manne ya muda kwa utaratibu. CPOL (mchanganyiko wa saa) hudhibiti hali ya mawimbi ya saa wakati hakuna data inayotumwa. Kidogo hiki kinadhibiti aina za bwana na mtumwa. CPOL ikiwekwa upya, pini ya SCK iko chini katika hali ya kupumzika. Biti ya CPOL ikiwekwa, pini ya SCK iko juu wakati wa hali ya kupumzika.
Biti ya CPHA (awamu ya saa) inapowekwa, kipigo cha juu cha mtego ni ukingo wa pili wa mawimbi ya SCK (inashuka ikiwa CPOL iko wazi, ikipanda CPOL ikiwa imewekwa). Data inachukuliwa na mabadiliko ya pili katika ishara ya saa. Ikiwa biti ya CPHA ni wazi, kipigo cha juu cha trap ni ukingo wa kupanda wa mawimbi ya SCK (makali yanayoanguka ikiwa CPOL imewekwa, ukingo wa kupanda ikiwa CPOL imeondolewa). Data inanaswa katika mabadiliko ya kwanza katika ishara ya saa.
Baada ya kunyonya ujuzi huu, tunafikia hitimisho kwamba bits zote mbili lazima zibaki zero, kwa sababu Tunataka mawimbi ya SCK ibaki ya chini wakati haitumiki, na data isambazwe kwenye ukingo unaoinuka wa mpigo (ona Mtini. Kupanda Edge Karatasi ya data ya DM634
Kwa njia, hapa tulikutana kwanza na kipengele cha msamiati katika hifadhidata za ST: ndani yao maneno "kuweka upya kidogo hadi sifuri" imeandikwa. kuweka upya kidogona sio kusafisha kidogo, kama, kwa mfano, Atmega.
3. Weka biti ya DFF ili kubaini ikiwa kizuizi cha data ni umbizo la biti 8 au 16
Nilichukua DM16 ya 634-bit ili nisijisumbue na kusambaza data ya 12-bit PWM, kama DM633. Inafahamika kuweka DFF kuwa moja:
4. Sanidi biti ya LSBFIRST katika sajili ya SPI_CR1 ili kubainisha umbizo la kuzuia
LSBFIRST, kama jina lake linavyopendekeza, husanidi utumaji kwa uchache muhimu kwanza. Lakini DM634 inataka kupokea data kuanzia muhimu zaidi. Kwa hiyo, tunaiacha upya.
5. Katika hali ya maunzi, ikiwa pembejeo kutoka kwa pini ya NSS inahitajika, tumia ishara ya juu kwenye pini ya NSS wakati wa mlolongo mzima wa uhamisho wa byte. Katika hali ya programu ya NSS, weka biti za SSM na SSI kwenye rejista ya SPI_CR1. Ikiwa pini ya NSS itatumika kama matokeo, biti ya SSOE pekee ndiyo inayohitaji kuwekwa.
Sakinisha SSM na SSI ili kusahau kuhusu hali ya maunzi ya NSS:
#define SSI 0x0100
#define SSM 0x0200
_SPI2_ (_SPI_CR1) |= SSM | SSI; //enable software control of SS, SS high
6. Biti za MSTR na SPE lazima ziwekwe (zinasalia zimewekwa ikiwa tu ishara ya NSS iko juu)
Kwa kweli, kwa biti hizi tunateua SPI yetu kama bwana na kuiwasha:
SPI imeundwa, hebu tuandike mara moja kazi zinazotuma byte kwa dereva. Endelea kusoma 25.3.3 "Kusanidi SPI katika hali kuu":
Agizo la kuhamisha data
Usambazaji huanza wakati baiti inapoandikwa kwa bafa ya Tx.
Baiti ya data imepakiwa kwenye rejista ya mabadiliko katika sambamba mode (kutoka kwa basi ya ndani) wakati wa uhamisho wa bit ya kwanza, baada ya hapo hupitishwa kwa mfululizo Modi ya pin ya MOSI, mbele kidogo ya kwanza au ya mwisho kulingana na mpangilio wa biti ya LSBFIRST kwenye rejista ya CPI_CR1. Bendera ya TXE imewekwa baada ya usambazaji wa data kutoka Tx bafa hadi kuhama rejista, na pia hutoa usumbufu ikiwa biti ya TXEIE kwenye rejista ya CPI_CR1 imewekwa.
Niliangazia maneno machache katika tafsiri ili kuvutia kipengele kimoja cha utekelezaji wa SPI katika vidhibiti vya STM. Kwenye Atmega bendera ya TXE (Tx Tupu, Tx ni tupu na iko tayari kupokea data) huwekwa tu baada ya baiti nzima kutumwa nje. Na hapa bendera hii imewekwa baada ya byte kuingizwa kwenye rejista ya mabadiliko ya ndani. Kwa kuwa inasukumwa huko na bits zote kwa wakati mmoja (sambamba), na kisha data inahamishwa kwa mlolongo, TXE imewekwa kabla ya kutumwa kabisa. Hii ni muhimu kwa sababu kwa upande wa dereva wetu wa LED, tunahitaji kuvuta pini ya LAT baada ya kutuma Kila data, i.e. Bendera ya TXE pekee haitatutosha.
Hii ina maana kwamba tunahitaji bendera nyingine. Wacha tuangalie 25.3.7 - "Bendera za Hali":
<β¦>
bendera ya BUSY
Bendera ya BSY imewekwa na kusafishwa na maunzi (kuiandikia haina athari). Bendera ya BSY inaonyesha hali ya safu ya mawasiliano ya SPI.
Inaweka upya:
uhamishaji unapokamilika (isipokuwa katika hali kuu ikiwa uhamishaji unaendelea)
wakati SPI imezimwa
wakati kosa la hali kuu linatokea (MODF=1)
Ikiwa uhamishaji hauendelezwi, alama ya BSY inafutwa kati ya kila uhamishaji wa data
Sawa, hii itakuja kwa manufaa. Hebu tujue ni wapi bafa ya Tx iko. Ili kufanya hivyo, soma "Daftari ya Data ya SPI":
Bits 15:0 DR[15:0] Sajili ya Data
Data iliyopokelewa au data ya kutumwa.
Rejesta ya data imegawanywa katika vihifadhi viwili - moja ya kuandika (kusambaza bafa) na moja ya kusoma (pokea bafa). Kuandikia rejista ya data huandika kwa bafa ya Tx, na kusoma kutoka kwa rejista ya data kutarudisha thamani iliyo kwenye bafa ya Rx.
Kweli, na rejista ya hali, ambapo bendera za TXE na BSY zinapatikana:
Kweli, kwa kuwa tunahitaji kupitisha mara 16 ka mbili, kulingana na idadi ya matokeo ya dereva wa LED, kitu kama hiki:
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();
}
Lakini bado hatujui jinsi ya kuvuta pini ya LAT, kwa hivyo tutarudi kwa I/O.
Kuweka pini
Katika STM32F1, rejista zinazohusika na hali ya pini ni za kawaida kabisa. Ni wazi kwamba kuna zaidi yao kuliko Atmega, lakini pia ni tofauti na chips nyingine za STM. Sehemu ya 9.1 Maelezo ya Jumla ya GPIO:
Kila moja ya bandari za madhumuni ya jumla ya I/O (GPIO) ina rejista mbili za usanidi wa biti 32 (GPIOx_CRL na GPIOx_CRH), rejista mbili za data za biti 32 (GPIOx_IDR na GPIOx_ODR), rejista ya kuweka/kuweka upya 32-bit (GPIOx_BSRR), rejista ya kuweka upya 16-bit (GPIOx_BRR) na 32- rejista ya kuzuia kidogo (GPIOx_LCKR).
Daftari mbili za kwanza si za kawaida, na pia hazifai kabisa, kwa sababu pini 16 za bandari zimetawanyika juu yao katika muundo wa "bits nne kwa ndugu". Wale. pini sifuri hadi saba ziko katika CRL, na zilizosalia ziko katika CRH. Wakati huo huo, rejista zilizobaki zina mafanikio ya vipande vya pini zote za bandari - mara nyingi hubaki nusu "imehifadhiwa".
Kwa unyenyekevu, hebu tuanze kutoka mwisho wa orodha.
Hatuhitaji rejista ya kuzuia.
Rejista zilizowekwa na kuweka upya ni za kuchekesha sana kwa kuwa zinarudia kila mmoja: unaweza kuandika kila kitu kwenye BSRR tu, ambapo bits 16 za juu zitaweka upya pini hadi sifuri, na zile za chini zitawekwa 1, au unaweza pia. tumia BRR, biti 16 za chini ambazo weka upya pini pekee . Ninapenda chaguo la pili. Rejesta hizi ni muhimu kwa sababu hutoa ufikiaji wa atomiki kwa pini:
Weka Atomiki au Weka Upya
Hakuna haja ya kuzima ukatizaji wakati wa kutayarisha GPIOx_ODR katika kiwango kidogo: biti moja au zaidi zinaweza kubadilishwa kwa operesheni moja ya uandishi wa atomiki APB2. Hii inafanikiwa kwa kuandika "1" kwa rejista ya kuweka/kuweka upya (GPIOx_BSRR au, kwa kuweka upya tu, GPIOx_BRR) ya biti inayohitaji kubadilishwa. Biti zingine zitabaki bila kubadilika.
Daftari za data zina majina ya kujieleza kabisa - IDR = Pembejeo Daftari la Mwelekeo, rejista ya pembejeo; ODR = pato Daftari la Mwelekeo, rejista ya pato. Hatutazihitaji katika mradi wa sasa.
Na hatimaye, rejista za udhibiti. Kwa kuwa tunavutiwa na pini za pili za SPI, ambazo ni PB13, PB14 na PB15, mara moja tunaangalia CRH:
Na tunaona kwamba tutahitaji kuandika kitu katika bits kutoka 20 hadi 31.
Tayari tumegundua juu ya kile tunachotaka kutoka kwa pini, kwa hiyo hapa nitafanya bila skrini, nitasema tu kwamba MODE inabainisha mwelekeo (pembejeo ikiwa bits zote mbili zimewekwa kwa 0) na kasi ya pini (tunahitaji 50MHz, i.e. pini zote mbili hadi "1"), na CNF inaweka hali: mara kwa mara "sukuma-vuta" - 00, "mbadala" - 10. Kwa chaguo-msingi, kama tunavyoona hapo juu, pini zote zina biti ya tatu kutoka chini (CNF0), inawaweka katika hali pembejeo inayoelea.
Kwa kuwa ninapanga kufanya kitu kingine na chip hii, kwa unyenyekevu nimefafanua maadili yote yanayowezekana ya MODE na CNF kwa rejista za udhibiti wa chini na wa juu.
(LAT_low kwa hali ya hewa, imekuwa hivyo kila wakati, iache ikae)
Sasa kila kitu ni nzuri, lakini haifanyi kazi. Kwa sababu hii ni STM32, huokoa umeme, ambayo inamaanisha unahitaji kuwezesha saa ya vifaa vya pembeni vinavyohitajika.
Washa saa
Saa, inayojulikana pia kama Saa, inawajibika kwa kuweka saa. Na tayari tunaweza kugundua kifupi cha RCC. Tunaitafuta katika nyaraka: hii ni Rudisha na Udhibiti wa Saa.
Kama ilivyosemwa hapo juu, kwa bahati nzuri, sehemu ngumu zaidi ya mada ya saa ilifanywa kwa ajili yetu na watu kutoka STM, ambayo tunawashukuru sana (kwa mara nyingine tena nitatoa kiungo kwa tovuti ya Di Halt, ili kuweka wazi jinsi inavyochanganya). Tunahitaji tu rejista zinazohusika na kuwezesha uwekaji saa wa pembeni (Rejista za Saa ya Pembeni Wezesha). Kwanza, wacha tupate anwani ya msingi ya RCC, iko mwanzoni kabisa mwa "Ramani ya Kumbukumbu":
Na kisha bonyeza kwenye kiunga ambacho unajaribu kupata kitu kwenye sahani, au, bora zaidi, pitia maelezo ya rejista za kuwezesha kutoka kwa sehemu kuhusu. wezesha rejista. Ambapo tutapata RCC_APB1ENR na RCC_APB2ENR:
Na wao, ipasavyo, vyenye bits ambayo ni pamoja na saa ya SPI2, IOPB (I/O Port B) na kazi mbadala (AFIO).
Ikiwa una fursa na hamu ya kufanya majaribio, basi unganisha DM634 kama hii: DAI hadi PB15, DCK hadi PB13, LAT hadi PB14. Tunawasha dereva kutoka kwa volts 5, usisahau kuunganisha misingi.
STM8 PWM
PWM kwenye STM8
Nilipokuwa nikipanga tu nakala hii, niliamua, kwa mfano, kujaribu kujua utendaji fulani wa chip isiyojulikana kwa kutumia hifadhidata tu, ili nisije nikapata fundi viatu bila buti. STM8 ilikuwa bora kwa jukumu hili: kwanza, nilikuwa na bodi kadhaa za Kichina na STM8S103, na pili, sio maarufu sana, na kwa hivyo jaribu la kusoma na kupata suluhisho kwenye mtandao linategemea ukosefu wa suluhisho hizi.
Kwa default, STM8 inafanya kazi kwa mzunguko wa 2 MHz, hii lazima irekebishwe mara moja.
Saa ya HSI (Kasi ya Juu ya Ndani).
Ishara ya saa ya HSI inatokana na oscillator ya ndani ya 16 MHz RC na kigawanyiko kinachoweza kupangwa (1 hadi 8). Imewekwa katika rejista ya kigawanyaji cha saa (CLK_CKDVR).
Kumbuka: mwanzoni, oscillator ya HSI RC yenye kigawanyiko cha 8 huchaguliwa kama chanzo kikuu cha ishara ya saa.
Tunapata anwani ya rejista kwenye hifadhidata, maelezo katika refman na kuona kwamba rejista inahitaji kufutwa:
Kwa kuwa tutaendesha PWM na kuunganisha LEDs, hebu tuangalie pinout:
Chip ni ndogo, kazi nyingi zimesimamishwa kwenye pini sawa. Kilicho kwenye mabano ya mraba ni "utendaji mbadala", inabadilishwa na "baiti chaguo" (chaguo ka) - kitu kama fuse za Atmega. Unaweza kubadilisha maadili yao kwa utaratibu, lakini sio lazima, kwa sababu Utendaji mpya huwashwa tu baada ya kuwasha upya. Ni rahisi kutumia ST Visual Programmer (iliyopakuliwa na Visual Develop), ambayo inaweza kubadilisha baiti hizi. Pinout inaonyesha kuwa pini za CH1 na CH2 za timer ya kwanza zimefichwa kwenye mabano ya mraba; ni muhimu kuweka bits AFR1 na AFR0 katika STVP, na ya pili pia itahamisha pato la CH1 la timer ya pili kutoka PD4 hadi PC5.
Kwa hivyo, pini 6 zitadhibiti LEDs: PC6, PC7 na PC3 kwa timer ya kwanza, PC5, PD3 na PA3 kwa pili.
Kuweka pini za I/O zenyewe kwenye STM8 ni rahisi na mantiki zaidi kuliko kwenye STM32:
inayojulikana kutoka kwa rejista ya mwelekeo wa data ya Atmega DDR (Daftari la Mielekeo ya Data): 1 = pato;
rejista ya kwanza ya udhibiti CR1, wakati pato, huweka hali ya kushinikiza-kuvuta (1) au kukimbia wazi (0); kwa kuwa ninaunganisha LED kwenye chip na cathodes, ninaacha zero hapa;
rejista ya pili ya udhibiti CR2, wakati pato, huweka kasi ya saa: 1 = 10 MHz
Mzunguko wa PWM - frequency ambayo kipima saa kinajibu;
Pakia upya kiotomatiki, AR - thamani ya kupakia kiotomatiki ambayo kipima saa kitahesabu (kipindi cha mapigo);
Sasisha Tukio, UEV - tukio ambalo hutokea wakati kipima muda kimehesabiwa hadi AR;
Mzunguko wa Wajibu wa PWM - Mzunguko wa wajibu wa PWM, mara nyingi huitwa "sababu ya wajibu";
Nasa/Linganisha Thamani - thamani ya kunasa/kulinganisha, ambayo kipima muda kimehesabiwa atafanya kitu (katika kesi ya PWM, inabadilisha ishara ya pato);
Thamani ya Kupakia mapema - thamani iliyopakiwa awali. Linganisha thamani haiwezi kubadilika wakati kipima saa kinaashiria, vinginevyo mzunguko wa PWM utavunjika. Kwa hivyo, maadili mapya yanayopitishwa huwekwa kwenye buffer na kutolewa nje wakati kipima saa kinafika mwisho wa siku iliyosalia na kuwekwa upya;
Imepangiliwa kingo ΠΈ Njia zilizopangwa katikati - alignment kando ya mpaka na katikati, sawa na Atmel PWM haraka ΠΈ Awamu-sahihi PWM.
OCiREF, Alama ya Marejeleo ya Pato la Kulinganisha - ishara ya pato la kumbukumbu, kwa kweli, kile kinachoonekana kwenye pini inayofanana katika hali ya PWM.
Kama inavyoonekana tayari kutoka kwa pinout, vipima muda viwili vina uwezo wa PWM - ya kwanza na ya pili. Zote mbili ni 16-bit, ya kwanza ina sifa nyingi za ziada (haswa, inaweza kuhesabu wote juu na chini). Tunahitaji wote wawili kufanya kazi kwa usawa, kwa hivyo niliamua kuanza na ile ya pili ambayo ni mbaya zaidi, ili nisitumie kwa bahati mbaya kitu ambacho hakipo. Shida fulani ni kwamba maelezo ya utendakazi wa PWM ya vipima muda katika mwongozo wa marejeleo yako katika sura kuhusu kipima saa cha kwanza (Njia ya PWM 17.5.7), kwa hivyo inabidi uruke huku na huko katika hati wakati wote.
PWM kwenye STM8 ina faida muhimu zaidi ya PWM kwenye Atmega:
PWM Iliyopangwa Mipaka
Usanidi wa akaunti kutoka chini hadi juu
Kuhesabu kutoka chini kwenda juu kunatumika ikiwa biti ya DIR katika sajili ya TIM_CR1 itafutwa
Mfano
Mfano hutumia hali ya kwanza ya PWM. OCiREF ya marejeleo ya mawimbi ya PWM imeshikiliwa juu kwa muda mrefu kama TIM1_CNT < TIM1_CCRi. Vinginevyo inachukua kiwango cha chini. Ikiwa thamani ya kulinganisha katika rejista ya TIM1_CCRi ni kubwa kuliko thamani ya upakiaji kiotomatiki (rejista ya TIM1_ARR), mawimbi ya OCiREF hushikiliwa saa 1. Ikiwa thamani ya kulinganisha ni 0, OCiREF inashikiliwa kwa sifuri....
Kipima muda cha STM8 wakati sasisha tukio hundi kwanza kulinganisha thamani, na kisha tu hutoa ishara ya kumbukumbu. Kipima saa cha Atmega kwanza husonga na kisha kulinganisha, na kusababisha compare value == 0 pato ni sindano, ambayo lazima ishughulikiwe kwa namna fulani (kwa mfano, kwa kugeuza mantiki kwa utaratibu).
Kwa hivyo kile tunachotaka kufanya: 8-bit PWM (AR == 255), kuhesabu kutoka chini hadi juu, alignment kando ya mpaka. Kwa kuwa balbu za mwanga zimeunganishwa kwenye chip na cathode, PWM inapaswa kutoa 0 (LED) hadi kulinganisha thamani na 1 baada.
Tayari tumesoma kuhusu baadhi Njia ya PWM, kwa hivyo tunapata rejista inayohitajika ya kipima saa cha pili kwa kutafuta katika mwongozo wa marejeleo kwa kifungu hiki (18.6.8 - TIMx_CCMR1):
110: Hali ya kwanza ya PWM β unapohesabu kutoka chini hadi juu, chaneli ya kwanza inafanya kazi huku TIMx_CNT <TIMx_CCR1. Vinginevyo, kituo cha kwanza hakitumiki. [zaidi katika hati kuna kunakili-ubandike kwa makosa kutoka kwa kipima muda 1] 111: Hali ya pili ya PWM - unapohesabu kutoka chini hadi juu, chaneli ya kwanza haitumiki huku TIMx_CNT < TIMx_CCR1. Vinginevyo, kituo cha kwanza kinatumika.
Kwa kuwa LED zimeunganishwa na MK na cathodes, hali ya pili inafaa kwetu (ya kwanza pia, lakini hatujui hilo bado).
Bit 3 OC1PE: Washa pini 1 ya upakiaji mapema
0: Sajili ya kupakia mapema kwenye TIMx_CCR1 imezimwa. Unaweza kuandika kwa TIMx_CCR1 wakati wowote. Thamani mpya inafanya kazi mara moja.
1: Rejista ya upakiaji mapema kwenye TIMx_CCR1 imewashwa. Shughuli za kusoma/kuandika fikia rejista ya upakiaji mapema. Thamani iliyopakiwa awali TIMx_CCR1 inapakiwa kwenye rejista ya kivuli wakati wa kila tukio la sasisho.
*Kumbuka: Ili hali ya PWM ifanye kazi vizuri, rejista za upakiaji mapema lazima ziwashwe. Hii si lazima katika hali ya mawimbi moja (biti ya OPM imewekwa kwenye rejista ya TIMx_CR1).
Sawa, wacha tuwashe kila kitu tunachohitaji kwa chaneli tatu za kipima saa cha pili:
Timer ya pili inaweza tu kuhesabu kutoka chini hadi juu, alignment kando ya mpaka, hakuna kitu kinachohitaji kubadilishwa. Hebu tuweke kigawanyiko cha mzunguko, kwa mfano, hadi 256. Kwa timer ya pili, mgawanyiko umewekwa kwenye rejista ya TIM2_PSCR na ni nguvu ya mbili:
Kinachobaki ni kuwasha hitimisho na timer ya pili yenyewe. Tatizo la kwanza linatatuliwa na rejista Nasa/Linganisha Kuwawezesha: kuna njia mbili, tatu zilizotawanyika kwa usawa. Hapa tunaweza pia kujifunza kwamba inawezekana kubadili polarity ya ishara, i.e. kimsingi, iliwezekana kutumia Njia ya PWM 1. Tunaandika:
Wacha tuandike analog rahisi ya AnalogWrite(), ambayo itahamisha maadili halisi kwa kipima saa kwa kulinganisha. Rejesta zimetajwa kwa kutabirika Nasa/Linganisha rejista, kuna mbili kati ya hizo kwa kila kituo: biti 8 za mpangilio wa chini katika TIM2_CCRxL na zile za mpangilio wa juu katika TIM2_CCRxH. Kwa kuwa tumeunda PWM ya 8-bit, inatosha kuandika sehemu ndogo tu muhimu:
Msomaji makini ataona kwamba tuna PWM yenye kasoro kidogo, haiwezi kuzalisha 100% ya kujaza (kwa thamani ya juu ya 255, ishara inageuzwa kwa mzunguko mmoja wa timer). Kwa LEDs hii haijalishi, na msomaji makini anaweza tayari nadhani jinsi ya kurekebisha.
PWM kwenye kipima saa cha pili inafanya kazi, wacha tuendelee hadi ya kwanza.
Timer ya kwanza ina bits sawa katika rejista sawa (ni kwamba bits hizo ambazo zilibaki "zimehifadhiwa" katika timer ya pili hutumiwa kikamilifu katika kwanza kwa kila aina ya mambo ya juu). Kwa hivyo, inatosha kupata anwani za rejista sawa kwenye daftari na kunakili nambari. Kweli, badilisha thamani ya kigawanyaji cha masafa, kwa sababu... kipima saa cha kwanza kinataka kupokea si nguvu ya mbili, lakini thamani halisi ya 16-bit katika rejista mbili Prescaler Juu ΠΈ Chini. Tunafanya kila kitu na ... timer ya kwanza haifanyi kazi. Kuna nini?
Tatizo linaweza kutatuliwa tu kwa kuangalia kupitia sehemu nzima kuhusu rejista za udhibiti wa timer 1, ambapo tunatafuta moja ambayo timer ya pili haina. Kutakuwa na 17.7.30 Rejesta ya mapumziko (TIM1_BKR), ambapo kuna sehemu hii:
Mradi wa tatu wa mini ni kuunganisha LED nane za RGB kwa kipima saa cha pili katika hali ya PWM na kuzifanya zionyeshe rangi tofauti. Inategemea wazo la kuzidisha kwa LED, ambayo ni kwamba ikiwa unawasha na kuzima LEDs haraka sana, itaonekana kwetu kuwa zinawashwa kila wakati (kuendelea kwa maono, hali ya mtazamo wa kuona). Niliwahi kufanya hivyo kitu kama hiki kwenye Arduino.
Algorithm ya kazi inaonekana kama hii:
iliunganisha anode ya LED ya kwanza ya RGB;
kuiwasha, kutuma ishara muhimu kwa cathodes;
kusubiri hadi mwisho wa mzunguko wa PWM;
iliunganisha anode ya LED ya pili ya RGB;
iwashe...
Naam, nk. Bila shaka, kwa operesheni nzuri inahitajika kwamba anode imeunganishwa na LED "inawaka" kwa wakati mmoja. Naam, au karibu. Kwa hali yoyote, tunahitaji kuandika msimbo ambao utatoa maadili katika njia tatu za timer ya pili, kuzibadilisha wakati UEV itafikiwa, na wakati huo huo ubadilishe RGB LED inayotumika sasa.
Kwa kuwa ubadilishaji wa LED ni otomatiki, tunahitaji kuunda "kumbukumbu ya video" ambayo kidhibiti cha kukatiza kitapokea data. Hii ni safu rahisi:
uint8_t colors[8][3];
Ili kubadilisha rangi ya LED maalum, itakuwa ya kutosha kuandika maadili yanayotakiwa katika safu hii. Na kutofautisha kutakuwa na jukumu la nambari ya LED inayofanya kazi
uint8_t cnt;
Demux
Kwa kuzidisha vizuri, tunahitaji, isiyo ya kawaida, CD74HC238 demultiplexer. Demultiplexer - chip inayotekelezea mwendeshaji katika maunzi <<. Kupitia pini tatu za pembejeo (bits 0, 1 na 2) tunalisha nambari ya bit-tatu X, na kwa kujibu inawasha nambari ya pato (1<<X) Pembejeo zilizobaki za chip hutumiwa kuongeza muundo mzima. Tunahitaji chip hii sio tu kupunguza idadi ya pini zilizochukuliwa za microcontroller, lakini pia kwa usalama - ili si kwa ajali kuwasha LED zaidi kuliko iwezekanavyo na si kuchoma MK. Chip inagharimu senti na inapaswa kuwekwa kila wakati kwenye baraza la mawaziri la dawa la nyumbani.
CD74HC238 yetu itakuwa na jukumu la kusambaza voltage kwenye anode ya LED inayotaka. Katika multiplex iliyojaa kamili, ingesambaza voltage kwenye safu kupitia P-MOSFET, lakini katika onyesho hili inawezekana moja kwa moja, kwa sababu. huchota 20 mA, kulingana na makadirio ya juu kabisa katika hifadhidata. Kutoka Karatasi ya data ya CD74HC238 tunahitaji pinouts na karatasi hii ya kudanganya:
H = kiwango cha juu cha voltage, L = kiwango cha chini cha voltage, X - usijali
Tunaunganisha E2 na E1 chini, E3, A0, A1 na A3 ili kubandika PD5, PC3, PC4 na PC5 ya STM8. Kwa kuwa jedwali lililo hapo juu lina viwango vya chini na vya juu, tunasanidi pini hizi kama pini za kusukuma-kuvuta.
PWM
PWM kwenye kipima saa cha pili imesanidiwa kwa njia sawa na katika hadithi iliyopita, na tofauti mbili:
Kwanza, tunahitaji kuwezesha usumbufu Sasisha Tukio (UEV) ambayo itaita kitendakazi ambacho hugeuza LED inayotumika. Hii inafanywa kwa kubadilisha kidogo Sasisha Ukatiza Wezesha katika rejista yenye jina la kuwaambia
Tofauti ya pili inahusiana na uzushi wa kuzidisha, kama vile ghosting - mwanga wa vimelea wa diode. Kwa upande wetu, inaweza kuonekana kutokana na ukweli kwamba timer, baada ya kusababisha usumbufu kwenye UEV, inaendelea kuashiria, na mtoaji wa usumbufu hana muda wa kubadili LED kabla ya timer kuanza kuandika kitu kwa pini. Ili kupambana na hili, itabidi ugeuze mantiki (0 = mwangaza wa juu zaidi, 255 = hakuna kitu kilichowashwa) na epuka maadili ya mzunguko wa wajibu uliokithiri. Wale. hakikisha kuwa baada ya UEV LED zinazima kabisa kwa mzunguko mmoja wa PWM.
Epuka kuweka r, g na b hadi 255 na kumbuka kuzigeuza unapozitumia.
Inakatiza
Kiini cha kukatiza ni kwamba chini ya hali fulani chip huacha kutekeleza programu kuu na kuita kazi fulani ya nje. Vikwazo hutokea kutokana na mvuto wa nje au wa ndani, ikiwa ni pamoja na kipima muda.
Tulipounda mradi kwa mara ya kwanza katika ST Visual Develop, pamoja na main.c tulipokea dirisha na faili ya ajabu stm8_interrupt_vector.c, imejumuishwa kiotomatiki kwenye mradi. Katika faili hii, chaguo la kukokotoa limepewa kila usumbufu NonHandledInterrupt. Tunahitaji kufunga utendaji wetu kwa ukatizaji unaotaka.
Hifadhidata ina jedwali la viveta vya kukatiza, ambapo tunapata zile tunazohitaji:
Tunahitaji kubadilisha LED kwenye UEV, kwa hivyo tunahitaji kukatiza #13.
Ipasavyo, kwanza, katika faili stm8_interrupt_vector.c badilisha jina chaguo-msingi la kitendakazi kinachohusika na kukatiza Nambari 13 (IRQ13) kuwa lako mwenyewe:
{0x82, TIM2_Overflow}, /* irq13 */
Pili, tutalazimika kuunda faili main.h na maudhui yafuatayo:
Kilichobaki ni kuwezesha kukatizwa. Hii inafanywa kwa kutumia amri ya mkusanyiko rim - itabidi utafute ndani Mwongozo wa Programu:
//enable interrupts
_asm("rim");
Amri nyingine ya mkusanyiko ni sim - huzima vikatizo. Lazima zizimwe wakati maadili mapya yanaandikwa kwa "kumbukumbu ya video", ili usumbufu unaosababishwa na wakati mbaya usiharibu safu.