Orodha ya maudhui:

Mafunzo ya Mkutano wa AVR 3: 9 Hatua
Mafunzo ya Mkutano wa AVR 3: 9 Hatua

Video: Mafunzo ya Mkutano wa AVR 3: 9 Hatua

Video: Mafunzo ya Mkutano wa AVR 3: 9 Hatua
Video: MAIDS WAINGIA BILA VIATU UKUMBINI !! NA WANAVYOJUA KURINGA SASA! |GadsonAndSalome |MCKATOKISHA 2024, Julai
Anonim
Mafunzo ya Mkusanyiko wa AVR 3
Mafunzo ya Mkusanyiko wa AVR 3

Karibu kwenye mafunzo namba 3!

Kabla ya kuanza nataka kutoa hoja ya kifalsafa. Usiogope kujaribu mizunguko na nambari ambayo tunaunda kwenye mafunzo haya. Badilisha waya kuzunguka, ongeza vifaa vipya, toa vifaa nje, badilisha mistari ya nambari, ongeza laini mpya, futa mistari, na uone kinachotokea! Ni ngumu sana kuvunja chochote na ukifanya hivyo, ni nani anayejali? Hakuna tunachotumia, pamoja na mdhibiti mdogo, ni ghali sana na kila wakati inaelimisha kuona jinsi vitu vinaweza kushindwa. Sio tu utapata nini usifanye wakati ujao lakini, muhimu zaidi, utajua kwanini usifanye hivyo. Ikiwa wewe ni kitu kama mimi, wakati ulipokuwa mtoto na ulikuwa na toy mpya haikuchukua muda mrefu kabla ya kuwa nayo vipande vipande kuona nini kiliifanya iwe sawa? Wakati mwingine toy ilimalizika bila kuharibika lakini hakuna shida kubwa. Kuruhusu mtoto kugundua udadisi wake hata kufikia hatua ya kuchezewa vinyago ndio humgeuza kuwa mwanasayansi au mhandisi badala ya safisha.

Leo tutakuwa wiring mzunguko rahisi sana na kisha kupata kidogo nzito katika nadharia. Samahani kuhusu hili, lakini tunahitaji zana! Ninaahidi tutalipa hii katika mafunzo 4 ambapo tutakuwa tukifanya jengo kubwa zaidi la mzunguko na matokeo yake yatakuwa mazuri sana. Walakini, njia ambayo unahitaji kufanya mafunzo haya yote ni ya polepole sana, ya kutafakari. Ikiwa unalima tu, jenga mzunguko, unakili na ubandike nambari hiyo, na uiendeshe basi, hakika, itafanya kazi, lakini hautajifunza kitu. Unahitaji kufikiria juu ya kila mstari. Sitisha. Jaribio. Vumbua. Ikiwa utafanya hivyo kwa njia kisha mwisho wa mafunzo ya 5 utakuwa umeunda vitu vyema na hauitaji kufundisha tena. Vinginevyo wewe ni kuangalia tu badala ya kujifunza na kuunda.

Kwa hali yoyote, falsafa ya kutosha, wacha tuanze!

Katika mafunzo haya utahitaji:

  1. bodi yako ya prototyping
  2. LED
  3. kuunganisha waya
  4. kontena karibu 220 hadi 330 ohms
  5. Mwongozo wa Kuweka Maagizo: www.atmel.com/images/atmel-0856-avr-instruction-se…
  6. Hati ya data: www.atmel.com/images/Atmel-8271-8-bit-AVR-Microco …….
  7. oscillator tofauti ya kioo (hiari)

Hapa kuna kiunga cha mkusanyiko kamili wa mafunzo:

Hatua ya 1: Kuunda Mzunguko

Kuunda Mzunguko
Kuunda Mzunguko

Mzunguko katika mafunzo haya ni rahisi sana. Sisi ni kimsingi kwenda kuandika "blink" mpango hivyo wote tunahitaji ni yafuatayo.

Hook up LED kwa PD4, kisha kwa 330 ohm resistor, kisha kwa Ground. i.e.

PD4 - LED - R (330) - GND

na ndio hivyo!

Nadharia hiyo itakuwa ngumu sana wakati …

Hatua ya 2: Kwa nini Tunahitaji Maoni na Faili ya M328Pdef.inc?

Nadhani tunapaswa kuanza kwa kuonyesha ni kwa nini faili ni pamoja na maoni ni muhimu. Hakuna hata moja yao ni ya lazima na unaweza kuandika, kukusanyika, na kupakia nambari kwa njia ile ile bila wao na itaendesha vizuri kabisa (ingawa bila faili iliyojumuishwa unaweza kupata malalamiko kutoka kwa mkusanyaji - lakini hakuna makosa)

Hapa kuna nambari ambayo tutaandika leo, isipokuwa kwamba nimeondoa maoni na faili ni pamoja na:

. kifaa ATmega328P

org. cbi 0x0b, 0x04 rcall c rjmp bc: clr r17 d: cpi r17, 0x1e brne d ret e: inc r17 cpi r17, 0x3d brne PC + 2 clr r17 reti

sawa rahisi? Haha. Ikiwa umekusanyika na kupakia faili hii utasababisha LED kuangaza kwa kiwango cha blink 1 kwa sekunde na blink kudumu 1/2 sekunde na pause kati ya blinks inayodumu 1/2 sekunde.

Walakini, kuangalia nambari hii sio mwangaza. Ikiwa ungeandika nambari kama hii wewe na ungependa kuibadilisha au kuiweka tena katika siku zijazo ungekuwa na wakati mgumu.

Basi wacha tuweke maoni na tujumuishe faili tena ili tuweze kuielewa.

Hatua ya 3: Blink.asm

Hapa kuna nambari ambayo tutajadili leo:

;************************************

; iliyoandikwa na: 1o_o7; tarehe:; toleo: 1.0; faili imehifadhiwa kama: blink.asm; kwa AVR: atmega328p; mzunguko wa saa: 16MHz (hiari); ************************************ Furaha ya programu: ---------------------; huhesabu sekunde kwa kupepesa LED;; PD4 - LED - R (330 ohm) - GND;; ------------------------------ orodha; ==============; Azimio:.def temp = r16. Mwamba umefurika = r17.org 0x0000; kumbukumbu (PC) eneo la kushughulikia tena mpangilio wa rjmp Rudisha; jmp gharama 2 cpu mizunguko na rjmp gharama 1 tu; kwa hivyo isipokuwa unahitaji kuruka zaidi ya ka 8k; unahitaji rjmp tu. Watawala wengine wadogo kwa hivyo tu; kuwa na rjmp na sio jmp.org 0x0020; eneo la kumbukumbu la Timer0 inayofurika kishikaji rjmp kufurika_handler; nenda hapa ikiwa kukatika kwa timer0 kunatokea; ============ Rudisha: ldi temp, 0b00000101 nje TCCR0B, temp; weka Bits Selector Bits CS00, CS01, CS02 hadi 101; hii inaweka Timer Counter0, TCNT0 katika hali ya FCPU / 1024; kwa hivyo inaangazia CPU freq / 1024 ldi temp, 0b00000001 sts TIMSK0, temp; weka kitita cha Kufurika kwa Timer Wezesha (TOIE0); ya Sajili ya Kukatisha Timer Kukatiza (TIMSK0) sei; wezesha usumbufu wa ulimwengu - sawa na "sbi SREG, I" clr temp nje TCNT0, temp; Anzisha Timer / Counter hadi 0 sbi DDRD, 4; weka PD4 kutoa; ======================; Mwili kuu wa programu: blink: sbi PORTD, 4; washa LED kwenye PD4 kuchelewesha rcall; kuchelewa itakuwa 1/2 cbi pili PORTD, 4; zima LED juu ya ucheleweshaji wa rcall PD4; kuchelewesha itakuwa 1/2 ya pili rjmp blink; kitanzi kurudi kwa ucheleweshaji wa kuanza: clr hufurika; weka mafuriko kwa 0 sec_count: cpi mafuriko, 30; linganisha idadi ya mafuriko na brne 30 sec_count; tawi kurudi kwa sec_count ikiwa sio sawa; ikiwa mafuriko 30 yametokea kurudi blink kufurika_handler: inc kufurika; ongeza 1 kwa mafuriko ya cpi yanayofurika, 61; linganisha na brne PC + 2; Programu ya Kukabili + 2 (ruka mstari unaofuata) ikiwa sio sawa clr inafurika; ikiwa mafuriko 61 yalitokea weka upya kaunta hadi sifuri reti; kurudi kutoka usumbufu

Kama unavyoona, maoni yangu ni mafupi zaidi sasa. Mara tu tunapojua ni nini amri katika seti ya mafundisho hatuhitaji kuelezea hayo katika maoni. Tunahitaji tu kuelezea kinachoendelea kutoka kwa mtazamo wa programu.

Tutakuwa tukijadili nini haya yote hufanya vipande vipande, lakini kwanza wacha tujaribu kupata mtazamo wa ulimwengu. Chombo kikuu cha programu hufanya kazi kama ifuatavyo.

Kwanza tunaweka kidogo 4 ya PORTD na "sbi PORTD, 4" hii hutuma 1 kwa PD4 ambayo inaweka voltage kwa 5V kwenye pini hiyo. Hii itawasha LED. Kisha tunaruka kwa njia ya "kuchelewesha" ambayo inahesabu 1/2 kwa sekunde (tutaelezea jinsi inafanya hii baadaye). Kisha tunarudi kupepesa na kusafisha kidogo 4 kwenye PORTD ambayo huweka PD4 hadi 0V na kwa hivyo inazima LED. Tunachelewesha kwa sekunde nyingine 1/2, halafu ruka kurudi mwanzoni mwa kupepesa tena na "rjmp blink".

Unapaswa kuendesha nambari hii na uone kuwa inafanya nini inapaswa.

Na hapo unayo! Hiyo ni nambari hii yote hufanya kimwili. Mitambo ya ndani ya kile microcontroller inafanya inahusika zaidi na ndio sababu tunafanya mafunzo haya. Basi wacha tujadili kila sehemu kwa zamu.

Hatua ya 4:.org Maagizo ya Mkusanyiko

Tayari tunajua nini maagizo ya.nolist,.list,. Pamoja, na.fef kukusanya kutoka kwa mafunzo yetu ya awali, kwa hivyo wacha kwanza tuangalie mistari 4 ya nambari inayokuja baada ya hapo:

.org 0x0000

jmp Rudisha.org 0x0020 jmp overflow_handler

Taarifa ya.org inamwambia mkusanyaji katika "Programu ya Kumbukumbu" kuweka taarifa inayofuata. Wakati programu yako inafanya, "Programu ya Kukabili" (iliyofafanuliwa kama PC) ina anwani ya laini ya sasa inayotekelezwa. Kwa hivyo katika kesi hii wakati PC iko kwenye 0x0000 itaona amri "jmp Rudisha" inakaa katika eneo hilo la kumbukumbu. Sababu tunayotaka kuweka jmp Rudisha mahali hapo ni kwa sababu wakati mpango unapoanza, au chip inarekebishwa, PC inaanza kutekeleza nambari mahali hapa. Kwa hivyo, kama tunaweza kuona, tumeiambia tu mara moja "iruke" kwa sehemu iliyoitwa "Rudisha". Kwa nini tulifanya hivyo? Hiyo inamaanisha kuwa mistari miwili iliyopita hapo juu inarukwa tu! Kwa nini?

Kweli hapo ndipo vitu vinapendeza. Sasa utalazimika kufungua mtazamaji wa pdf na jarida kamili la ATmega328p ambalo nilionyesha kwenye ukurasa wa kwanza wa mafunzo haya (ndio sababu ni kipengee 4 katika sehemu ya "utahitaji"). Ikiwa skrini yako ni ndogo sana, au una madirisha mengi tayari yamefunguliwa (kama ilivyo kwangu) unaweza kufanya kile ninachofanya na kuiweka kwa Msomaji, au simu yako ya Android. Utatumia kila wakati ikiwa unapanga kuandika nambari ya kusanyiko. Jambo la kupendeza ni kwamba microcontollers zote zimepangwa kwa njia zinazofanana sana na kwa hivyo ukishazoea kusoma vichapo vya data na kuweka alama kutoka kwao utapata ni jambo dogo kufanya vivyo hivyo kwa mdhibiti mdogo tofauti. Kwa hivyo tunajifunza jinsi ya kutumia watawala wote kwa njia fulani na sio tu atmega328p.

Sawa, fungua ukurasa wa 18 kwenye data na uangalie Kielelezo 8-2.

Hivi ndivyo Kumbukumbu ya Programu katika microcontroller imewekwa. Unaweza kuona kuwa huanza na anwani 0x0000 na imegawanywa katika sehemu mbili; sehemu ya matumizi ya flash na sehemu ya boot flash. Ikiwa unarejelea kwa kifupi ukurasa wa 277 jedwali 27-14 utaona kuwa sehemu ya matumizi ya flash inachukua maeneo kutoka 0x0000 hadi 0x37FF na sehemu ya boot flash inachukua maeneo yaliyobaki kutoka 0x3800 hadi 0x3FFF.

Zoezi 1: Kuna maeneo ngapi katika kumbukumbu ya Programu? Yaani. badilisha 3FFF kuwa desimali na ongeza 1 tangu tuanze kuhesabu saa 0. Kwa kuwa kila eneo la kumbukumbu ni bits 16 (au ka 2) pana ni idadi ngapi ya kaiti za kumbukumbu? Sasa badilisha hii kuwa kilobytes, ukikumbuka kuwa kuna 2 ^ 10 = 1024 ka katika kilobyte. Sehemu ya boot flash huenda kutoka 0x3800 hadi 0x37FF, ni kilobytes ngapi hii? Ni kilobytes ngapi za kumbukumbu zinazobaki kwetu kutumia kuhifadhi programu yetu? Kwa maneno mengine, mpango wetu unaweza kuwa mkubwa kiasi gani? Mwishowe, tunaweza kuwa na mistari ngapi ya nambari?

Sawa, sasa kwa kuwa tunajua yote juu ya shirika la kumbukumbu ya mpango wa flash, wacha tuendelee na majadiliano yetu ya taarifa za.org. Tunaona kuwa eneo la kumbukumbu la kwanza 0x0000 lina maagizo yetu ya kuruka kwa sehemu yetu tuliyoiita Rudisha. Sasa tunaona nini taarifa ya ".org 0x0020" inavyofanya. Inasema kwamba tunataka maagizo kwenye mstari unaofuata kuwekwa mahali pa kumbukumbu 0x0020. Maagizo tuliyoyaweka huko ni kuruka kwa sehemu kwenye nambari yetu ambayo tumeandika "overflow_handler"… sasa kwanini heck tungeweza kudai kwamba kuruka uku kuwekwa mahali pa kumbukumbu 0x0020? Ili kujua, tunageuka kwenye ukurasa wa 65 kwenye data na tuangalie Jedwali 12-6.

Jedwali 12-6 ni jedwali la "Rudisha na Kukatiza Vectors" na inaonyesha haswa ni wapi PC itaenda wakati inapokea "usumbufu". Kwa mfano, ukiangalia nambari ya Vector 1. "Chanzo" cha usumbufu ni "Rudisha" ambayo hufafanuliwa kama "Siri ya nje, Rudisha Nguvu, Rudisha nje ya Kahawia, na kuweka upya mfumo wa Watazamaji" ikiwa na maana ya mambo hayo hufanyika kwa mdhibiti wetu mdogo, PC itaanza kutekeleza programu yetu kwenye eneo la kumbukumbu ya programu 0x0000. Je! Vipi kuhusu maagizo yetu ya.org basi? Kweli, tuliweka amri kwenye eneo la kumbukumbu 0x0020 na ikiwa utaangalia chini ya meza utaona kwamba ikiwa Timer / Counter0 itafurika ikitokea (kutoka TIMER0 OVF) itafanya chochote kilicho katika eneo 0x0020. Kwa hivyo wakati wowote hiyo itatokea, PC itaruka mahali ambapo tuliandika "overflow_handler". Baridi sawa? Utaona kwa dakika moja kwa nini tumefanya hivi, lakini kwanza wacha tumalize hatua hii ya mafunzo na kando.

Ikiwa tunataka kuifanya nambari yetu iwe nadhifu zaidi na nadhifu tunapaswa kuchukua nafasi ya mistari 4 tunayojadili kwa sasa na yafuatayo (tazama ukurasa wa 66):

.org 0x0000

Rjmp Rudisha; PC = 0x0000 reti; PC = 0x0002 reti; PC = 0x0004 reti; PC = 0x0006 reti; PC = 0x0008 reti; PC = 0x000A… reti; PC = 0x001E jmp overflow_handler: PC = 0x0020 reti: PC = 0x0022… reti; PC = 0x0030 reti; PC = 0x0032

Ili kwamba ikiwa usumbufu uliotolewa utatokea tu "reti" ambayo inamaanisha "kurudi kutoka usumbufu" na hakuna kitu kingine kinachotokea. Lakini ikiwa hatuwezi "Wezesha" usumbufu huu anuwai, basi hautatumika na tunaweza kuweka nambari ya mpango katika matangazo haya. Katika programu yetu ya sasa ya "blink.asm" tutawezesha tu kufurika kwa timer0 (na kwa kweli usumbufu wa kuweka upya ambao umewezeshwa kila wakati) na kwa hivyo hatutasumbua na wengine.

Je! Tunawezaje "kuwezesha" kufurika kwa timer0 kukatiza basi? … Hiyo ndio mada ya hatua yetu inayofuata katika mafunzo haya.

Hatua ya 5: Timer / Counter 0

Kipima muda / Kaunta 0
Kipima muda / Kaunta 0

Angalia picha hapo juu. Huu ndio mchakato wa kufanya uamuzi wa "PC" wakati ushawishi wa nje "unakatisha" mtiririko wa programu yetu. Jambo la kwanza inafanya wakati inapata ishara kutoka nje kwamba usumbufu umetokea ni kuangalia kuona ikiwa tumeweka "kukatiza kuwezesha" kidogo kwa aina hiyo ya usumbufu. Ikiwa hatujafanya hivyo, basi inaendelea tu kutekeleza safu yetu inayofuata ya nambari. Ikiwa tumeweka usumbufu fulani kuwezesha kidogo (ili kuwe na 1 katika eneo hilo kidogo badala ya 0) basi itaangalia ikiwa tumewezesha "usumbufu wa ulimwengu" au la, ikiwa sivyo itaenda tena kwenye mstari unaofuata. ya nambari na endelea. Ikiwa tumewezesha usumbufu wa ulimwengu pia, basi itaenda kwenye eneo la Kumbukumbu ya Programu ya aina hiyo ya usumbufu (kama inavyoonyeshwa kwenye Jedwali 12-6) na kutekeleza amri yoyote ambayo tumeweka hapo. Basi wacha tuone ni jinsi gani tumetekeleza haya yote katika nambari yetu.

Sehemu iliyowekwa lebo ya msimbo wetu huanza na mistari miwili ifuatayo:

Weka upya:

ldi temp, 0b00000101 nje TCCR0B, temp

Kama tunavyojua tayari, hii hupakia kwa muda (i.e. R16) nambari inayofuata mara moja, ambayo ni 0b00000101. Halafu inaandika nambari hii kwa rejista inayoitwa TCCR0B kwa kutumia amri ya "nje". Rejista hii ni nini? Naam, hebu tuelekeze kwenye ukurasa wa 614 wa data. Hii ni katikati ya meza kwa muhtasari wa sajili zote. Kwenye anwani 0x25 utapata TCCR0B. (Sasa unajua ni wapi mstari "nje 0x25, r16" ulitoka katika toleo langu lisilotoa maoni la nambari). Tunaona kwa sehemu ya nambari hapo juu kuwa tumeweka kidogo ya 0 na kidogo ya 2 na tukasafisha zingine zote. Kwa kutazama meza unaweza kuona kwamba hii inamaanisha tumeweka CS00 na CS02. Sasa hebu tuelekeze kwenye sura iliyo kwenye data iliyoitwa "8-bit Timer / Counter0 na PWM". Hasa, nenda kwenye ukurasa wa 107 wa sura hiyo. Utaona maelezo sawa ya rejista ya "Timer / Counter Control B" (TCCR0B) ambayo tumeona kwenye jedwali la muhtasari (kwa hivyo tungekuja moja kwa moja hapa, lakini nilitaka uone jinsi ya kutumia meza za muhtasari kwa kumbukumbu ya baadaye). Jedwali linaendelea kutoa maelezo ya kila bits kwenye sajili hiyo na kile wanachofanya. Tutaruka yote hayo kwa sasa na kugeuza ukurasa kuwa Jedwali 15-9. Jedwali hili linaonyesha "Saa Chagua Maelezo kidogo". Sasa angalia meza hiyo mpaka upate laini inayolingana na bits ambazo tumeweka tu kwenye daftari hilo. Mstari unasema "clk / 1024 (kutoka kwa daktari wa daktari)". Hii inamaanisha nini kwamba tunataka Timer / Counter0 (TCNT0) ikike alama kwa kiwango ambacho ni frequency ya CPU iliyogawanywa na 1024. Kwa kuwa tuna microcontroller wetu anayelishwa na oscillator ya kioo ya 16MHz inamaanisha kuwa kiwango ambacho CPU yetu hutumia maagizo ni Maagizo milioni 16 kwa sekunde. Kwa hivyo kiwango ambacho kaunta yetu ya TCNT0 itaangazia basi ni milioni 16/1024 = mara 15625 kwa sekunde (jaribu na biti tofauti za kuchagua saa na uone kinachotokea - kumbuka falsafa yetu?). Wacha tuweke nambari 15625 nyuma ya akili zetu kwa baadaye na tuende kwenye mistari miwili inayofuata ya nambari:

ldi temp, 0b00000001

sts TIMSK0, temp

Hii inaweka kidogo ya rejista inayoitwa TIMSK0 na inafuta zingine zote. Ukiangalia ukurasa wa 109 kwenye lahajedwali utaona kuwa TIMSK0 inasimama kwa "Sajili ya Kukata Timer / Kukabiliana na Sauti 0" na nambari yetu imeweka kidogo ya 0 ambayo inaitwa TOIE0 ambayo inasimama kwa "Kukatiza Timer / Counter0 Kufurika Wezesha" … Huko! Sasa unaona hii inahusu nini. Sasa tuna "kukatiza kuwezesha kuweka kidogo" kama tulivyotaka kutoka kwa uamuzi wa kwanza kwenye picha yetu juu. Kwa hivyo sasa tunachohitajika kufanya ni kuwezesha "kuingiliwa kwa ulimwengu" na programu yetu itaweza kujibu aina hizi za usumbufu. Tutawezesha kukatizwa kwa ulimwengu muda mfupi, lakini kabla ya kufanya hivyo unaweza kuwa umechanganyikiwa na kitu.. kwa nini heck nilitumia amri "sts" kunakili kwenye rejista ya TIMSK0 badala ya "nje" ya kawaida?

Wakati wowote unaniona nikitumia maagizo ambayo haujaona kabla ya jambo la kwanza unapaswa kufanya ni kugeukia ukurasa wa 616 kwenye data. Hii ndio "Muhtasari wa Kuweka Maagizo". Sasa pata maagizo "STS" ambayo ndiyo niliyotumia. Inasema inachukua nambari kutoka kwa rejista ya R (tulitumia R16) na "Hifadhi moja kwa moja kwa eneo la SRAM" k (kwa upande wetu iliyotolewa na TIMSK0). Kwa hivyo kwanini tulilazimika kutumia "sts" ambayo inachukua mizunguko 2 ya saa (tazama safu ya mwisho kwenye jedwali) kuhifadhi katika TIMSK0 na tulihitaji tu "nje", ambayo inachukua mzunguko wa saa moja tu, kuhifadhi katika TCCR0B hapo awali? Ili kujibu swali hili tunahitaji kurudi kwenye jedwali letu la muhtasari kwenye ukurasa wa 614. Unaona kuwa rejista ya TCCR0B iko kwenye anwani 0x25 lakini pia iko (0x45) sawa? Hii inamaanisha kuwa ni rejista katika SRAM, lakini pia ni aina fulani ya rejista inayoitwa "bandari" (au i / o rejista). Ukiangalia meza ya muhtasari wa mafundisho kando ya amri ya "nje" utaona kwamba inachukua maadili kutoka kwa "sajili za kufanya kazi" kama R16 na kuzipeleka kwa BANDARI. Kwa hivyo tunaweza kutumia "nje" tunapoandikia TCCR0B na kujiokoa mzunguko wa saa. Lakini sasa angalia TIMSK0 kwenye jedwali la usajili. Unaona kuwa ina anwani 0x6e. Hii iko nje ya anuwai ya bandari (ambayo ni maeneo ya kwanza ya 0x3F ya SRAM) na kwa hivyo lazima urudi kutumia amri ya sts na kuchukua mizunguko miwili ya saa ya CPU kuifanya. Tafadhali soma Kumbuka 4 mwishoni mwa jedwali la muhtasari wa maagizo kwenye ukurasa wa 615 hivi sasa. Pia angalia kuwa bandari zetu zote za kuingiza na kutoa, kama PORTD ziko chini ya meza. Kwa mfano, PD4 ni kidogo 4 kwenye anwani 0x0b (sasa unaona ni wapi vitu vyote vya 0x0b vilitoka kwenye nambari yangu isiyo na maoni!).. sawa, swali la haraka: je! Ulibadilisha "sts" kwenda "nje" na uone nini hutokea? Kumbuka falsafa yetu! vunja! usichukue tu neno langu kwa vitu.

Sawa, kabla ya kuendelea, fungua ukurasa wa 19 kwenye data kwa dakika. Unaona picha ya kumbukumbu ya data (SRAM). Rejista 32 za kwanza katika SRAM (kutoka 0x0000 hadi 0x001F) ni "madaftari ya jumla ya kufanya kazi" R0 hadi R31 ambayo tunatumia wakati wote kama vigeuzi katika nambari yetu. Rejista 64 zifuatazo ni bandari za I / O hadi 0x005f (yaani zile ambazo tulikuwa tukizungumzia ambazo zina anwani ambazo hazina mabano kando yao kwenye meza ya rejista ambayo tunaweza kutumia amri ya "nje" badala ya "sts") Mwishowe sehemu inayofuata ya SRAM ina rejista zingine zote kwenye jedwali la muhtasari hadi kushughulikia 0x00FF, na mwishowe iliyobaki ni SRAM ya ndani. Sasa haraka, wacha tugeukie ukurasa wa 12 kwa sekunde. Hapo unaona meza ya "daftari za jumla za kufanya kazi" ambazo tunatumia kila wakati kama vigeuzi vyetu. Unaona mstari mnene kati ya nambari R0 hadi R15 halafu R16 hadi R31? Mstari huo ndio sababu kila wakati tunatumia R16 kama ndogo zaidi na nitaingia ndani zaidi katika mafunzo yafuatayo ambapo pia tutahitaji rejista tatu za anwani zisizo za moja kwa moja za 16-bit, X, Y, na Z. ingia kwenye hiyo bado ingawa kwa kuwa hatuihitaji sasa na tunazidiwa hapa.

Flip nyuma ukurasa mmoja hadi ukurasa wa 11 wa data. Utaona mchoro wa rejista ya SREG kulia juu? Unaona hiyo kidogo 7 ya daftari hilo inaitwa "I". Sasa nenda chini kwenye ukurasa na usome maelezo ya Bit 7…. yay! Ni Wezesha Usumbufu Ulimwenguni. Hiyo ndio tunayohitaji kuweka ili kupitisha uamuzi wa pili kwenye mchoro wetu hapo juu na kuruhusu kukatika kwa timer / counter katika programu yetu. Kwa hivyo mstari unaofuata wa programu yetu unapaswa kusoma:

sbi SREG, mimi

ambayo huweka kidogo inayoitwa "I" katika rejista ya SREG. Walakini, badala ya hii tumetumia maagizo

jinsi

badala yake. Kidogo hiki huwekwa mara nyingi katika programu ambazo walifanya tu njia rahisi ya kuifanya.

Sawa! Sasa tumepata usumbufu wa kufurika tayari kwenda ili "jmp overflow_handler" yetu itekelezwe kila mtu anapotokea.

Kabla ya kuendelea, angalia haraka rejista ya SREG (Sajili ya Hali) kwa sababu ni muhimu sana. Soma kile bendera inawakilisha. Hasa, maagizo mengi ambayo tunatumia yataweka na kuangalia bendera hizi kila wakati. Kwa mfano, baadaye tutatumia amri "CPI" ambayo inamaanisha "linganisha mara moja". Angalia meza ya muhtasari wa maagizo kwa maagizo haya na angalia ni alama ngapi ambazo zinaweka kwenye safu ya "bendera". Hizi zote ni bendera katika SREG na nambari yetu itakuwa ikiiweka na kuzikagua kila wakati. Utaona mifano hivi karibuni. Mwishowe sehemu ndogo ya mwisho ya nambari hii ni:

clr muda

nje TCNT0, temp sbi DDRD, 4

Mstari wa mwisho hapa ni dhahiri kabisa. Inaweka tu 4 ya Daftari ya Uelekezaji wa Takwimu kwa PortD inayosababisha PD4 kuwa OUTPUT.

Ya kwanza huweka temp ya kutofautiana kuwa sifuri na kisha nakala hizo kwenye sajili ya TCNT0. TCNT0 ni kipima muda / Counter0 yetu. Hii inaiweka sifuri. Mara tu PC itakapotekeleza laini hii timer0 itaanza sifuri na kuhesabu kwa kiwango cha mara 15625 kila sekunde. Shida ni hii: TCNT0 ni sajili ya "8-bit" sawa? Kwa hivyo ni nambari gani kubwa ambayo sajili ya 8-bit inaweza kushikilia? Naam 0b11111111 ndio hiyo. Hii ndio nambari 0xFF. Ambayo ni 255. Kwa hivyo unaona kinachotokea? Kipima muda kinaendelea kuongezeka mara 15625 kwa sekunde na kila inapofikia 255 "hufurika" na kurudi kwa 0 tena. Wakati huo huo inarudi kwa sifuri hutuma ishara ya Kukatiza Timer Kufurika. PC inapata hii na unajua inafanya nini sasa hivi? Ndio. Inakwenda kwa eneo la Kumbukumbu ya Programu 0x0020 na kutekeleza maagizo yanayopatikana hapo.

Kubwa! Ikiwa bado uko nami basi wewe ni shujaa asiyechoka! Wacha tuendelee…

Hatua ya 6: Mshughulikiaji wa kufurika

Basi wacha tufikirie kwamba rejista ya saa / counter0 imejaa tu. Sasa tunajua kuwa programu inapokea ishara ya kukatiza na kutekeleza 0x0020 ambayo inaiambia Programu ya Kukabiliana, PC kuruka kwa lebo "overflow_handler" ifuatayo ni nambari tuliyoandika baada ya lebo hiyo:

kishikaji_za_kupitiliza:

inc kufurika cpi kufurika, 61 brne PC + 2 clr kufurika reti

Jambo la kwanza linafanya ni kuongeza "kufurika" (ambayo ni jina letu kwa daftari la jumla la kufanya kazi R17) kisha "inalinganisha" yaliyomo ya mafuriko na nambari 61. Njia ambayo maagizo ya cpi hufanya kazi ni kwamba inavutia tu nambari mbili na ikiwa matokeo ni sifuri huweka bendera ya Z kwenye sajili ya SREG (nilikuambia tutakuwa tunaona rejista hii kila wakati). Ikiwa nambari mbili ni sawa basi bendera ya Z itakuwa 1, ikiwa nambari mbili hazilingani basi itakuwa 0.

Mstari unaofuata unasema "brne PC + 2" ambayo inamaanisha "tawi ikiwa si sawa". Kwa kweli, inakagua bendera ya Z katika SREG na ikiwa sio moja (yaani nambari mbili hazilingani, ikiwa zingekuwa sawa, bendera ya sifuri ingewekwa) matawi ya PC kwa PC + 2, ikimaanisha inaruka ijayo. line na huenda moja kwa moja kwa "reti" ambayo inarudi kutoka kwa usumbufu kwenda mahali popote ilipokuwa kwenye nambari wakati usumbufu ulipofika. Ikiwa maagizo ya brne yangepata 1 kwenye bendera ya sifuri haingekuwa tawi na badala yake ingeendelea tu kwa laini inayofuata ambayo ingejaa kufurika kuiweka tena hadi 0.

Je! Ni nini matokeo kamili ya haya yote?

Vizuri tunaona kwamba kila wakati kuna kipima muda kinachosimamia mshughulikiaji huyu huongeza thamani ya "kufurika" kwa moja. Kwa hivyo "kufurika" kunahesabu idadi ya mafuriko yanapotokea. Wakati wowote nambari inafikia 61 tunaiweka upya kuwa sifuri.

Sasa kwanini ulimwenguni tungefanya hivyo?

Hebu tuone. Kumbuka kwamba kasi yetu ya saa kwa CPU yetu ni 16MHz na "tuliisimamisha" kwa kutumia TCCR0B ili kipima muda tu kihesabu kwa kiwango cha hesabu 15625 kwa sekunde moja? Na kila wakati kipima muda kinafikia hesabu ya 255 hufurika. Kwa hivyo hiyo inamaanisha inafurika 15625/256 = mara 61.04 kwa sekunde. Tunafuatilia idadi ya mafuriko na "mafuriko" yetu yanayobadilika na tunalinganisha idadi hiyo na 61. Kwa hivyo tunaona kwamba "kufurika" itakuwa sawa 61 mara moja kila sekunde! Kwa hivyo mshughulikiaji wetu ataweka upya "kufurika" hadi sifuri mara moja kila sekunde. Kwa hivyo ikiwa tungefuatilia tu "kufurika" na kutazama kila wakati inapoanza hadi sifuri tungekuwa tunahesabu sekunde-ya-pili kwa wakati halisi (Kumbuka kuwa katika mafunzo yanayofuata tutaonyesha jinsi ya kupata ukweli zaidi kuchelewesha kwa milliseconds kwa njia ile ile ambayo Arduino "kuchelewesha" kawaida hufanya kazi).

Sasa "tumeshughulikia" kufurika kwa timer kukatiza. Hakikisha unaelewa jinsi hii inafanya kazi na kisha nenda kwenye hatua inayofuata ambapo tunatumia ukweli huu.

Hatua ya 7: Kuchelewa

Sasa kwa kuwa tumeona kuwa kufurika kwa saa yetu kukatiza kishikaji "overflow_handler" kawaida kutaweka "kufurika" kwa sifuri mara moja kwa kila sekunde tunaweza kutumia ukweli huu kubuni njia ndogo ya "kuchelewesha".

Angalia nambari ifuatayo kutoka kwa kucheleweshwa kwetu: lebo

kuchelewesha:

clr kufurika sec_count: cpi kufurika, 30 brne sec_count ret

Tutayaita sheria hii kila wakati tunapohitaji kucheleweshwa kwa programu yetu. Njia inavyofanya kazi ndio kwanza inaweka "mafuriko" yanayobadilika kuwa sifuri. Halafu inaingia kwenye eneo lililoitwa "sec_count" na inalinganisha mafuriko na 30, ikiwa si sawa inarejea kwa lebo sec_count na inalinganisha tena, na tena, n.k. hadi hapo watakapokuwa sawa (kumbuka kuwa wakati wote huu unaenda kwenye kidhibiti chetu cha kukatiza timer inaendelea kuongeza mafuriko yanayobadilika na kwa hivyo inabadilika kila wakati tunapozunguka hapa. Wakati mafuriko mwishowe ni sawa na 30 hutoka kitanzi na kurudi popote tulipoita kuchelewesha: kutoka. Matokeo halisi ni kuchelewa kwa sekunde 1/2

Zoezi la 2: Badilisha utaratibu wa kufurika_kushikilia kuwa yafuatayo:

kishikaji_za_kupitiliza:

inc kufurika reti

na kuendesha programu. Je! Kuna chochote tofauti? Kwa nini au kwa nini?

Hatua ya 8: Blink

Mwishowe wacha tuangalie utaratibu wa kupepesa:

kupepesa:

sbi PORTD, 4 rcall kuchelewesha cbi PORTD, 4 rcall kuchelewesha rjmp blink

Kwanza tunawasha PD4, halafu tunaita subroutine yetu ya kuchelewesha. Tunatumia rcall ili wakati PC itafika kwenye taarifa ya "ret" itarudi kwenye laini ifuatayo rcall. Halafu ucheleweshaji wa kawaida wa kucheleweshwa kwa hesabu 30 katika ubadilishaji wa kufurika kama tulivyoona na hii ni karibu sekunde moja na mbili, kisha tunazima PD4, kuchelewesha sekunde nyingine ya pili, na kisha kurudi mwanzo tena.

Matokeo halisi ni mwangaza wa LED!

Nadhani sasa utakubali kwamba "blink" labda sio mpango bora wa "hello world" katika lugha ya mkutano.

Zoezi la 3: Badilisha vigezo anuwai kwenye programu ili taa iangaze kwa viwango tofauti kama sekunde au mara 4 kwa sekunde, nk Zoezi la 4: Badilisha ili taa iwe imewashwa na kuzimwa kwa muda tofauti. Kwa mfano kwa sekunde 1/4 kisha uzime kwa sekunde 2 au kitu kama hicho. Zoezi la 5: Badilisha saa ya TCCR0B chagua bits kuwa 100 kisha uendelee kupanda juu. Je! Ni wakati gani inaweza kutofautishwa na programu yetu ya "hello.asm" kutoka kwa mafunzo 1? Zoezi la 6 (hiari): Ikiwa una oscillator tofauti ya kioo, kama 4 MHz au 13.5 MHz au chochote, badilisha oscillator yako ya 16 MHz kwenye mkate wako mpya na uone jinsi hiyo inavyoathiri kiwango cha kupepesa cha LED. Unapaswa sasa kuweza kupitia hesabu sahihi na utabiri haswa jinsi itaathiri kiwango.

Hatua ya 9: Hitimisho

Kwa wale mliokufa kwa muda mrefu ambao mmefika mbali, Hongera!

Ninatambua kuwa ni ngumu sana wakati unasoma zaidi na unatafuta zaidi kuliko unavyotengeneza wiring na kujaribu lakini natumai umejifunza mambo yafuatayo muhimu:

  1. Jinsi Kumbukumbu ya Programu inavyofanya kazi
  2. Jinsi SRAM inavyofanya kazi
  3. Jinsi ya kutafuta rejista
  4. Jinsi ya kutafuta maagizo na kujua wanachofanya
  5. Jinsi ya kutekeleza usumbufu
  6. Jinsi CP inavyotekeleza nambari, jinsi SREG inavyofanya kazi, na kinachotokea wakati wa usumbufu
  7. Jinsi ya kufanya vitanzi na kuruka na kuzunguka kwenye kificho
  8. Ni muhimuje kusoma hati ya data!
  9. Jinsi unavyojua jinsi ya kufanya haya yote kwa Mdhibiti mdogo wa Atmega328p itakuwa mwendo wa keki ya jamaa kujifunza watawala wowote wapya unaovutiwa nao.
  10. Jinsi ya kubadilisha wakati wa CPU kuwa wakati halisi na uitumie katika mazoea ya kuchelewesha.

Sasa kwa kuwa tuna nadharia nyingi nje ya njia tunaweza kuandika nambari bora na kudhibiti vitu ngumu zaidi. Kwa hivyo mafunzo yanayofuata tutafanya hivyo tu. Tutaunda njia ngumu zaidi, ya kupendeza zaidi, na kuidhibiti kwa njia za kufurahisha.

Zoezi la 7: "Vunja" nambari kwa njia anuwai na uone kinachotokea! Udadisi wa kisayansi mtoto! Zoezi la 8: Unganisha nambari kwa kutumia chaguo la "-l" kutengeneza faili ya orodha. Yaani. "avra -l blink.lst blink.asm" na uangalie orodha ya faili. Mkopo wa ziada: Nambari isiyo na maoni ambayo nilitoa mwanzoni na nambari ya maoni ambayo tunajadili baadaye hutofautiana! Kuna mstari mmoja wa nambari ambao ni tofauti. Unaweza kuipata? Kwa nini tofauti hiyo haijalishi?

Natumahi ulikuwa na furaha! Tutaonana wakati mwingine…

Ilipendekeza: