Innholdsfortegnelse:

Lesebrytere med ATtiny2313: 9 trinn
Lesebrytere med ATtiny2313: 9 trinn

Video: Lesebrytere med ATtiny2313: 9 trinn

Video: Lesebrytere med ATtiny2313: 9 trinn
Video: Использование кнопки скорости шагового двигателя 28BYJ-48 с 8 проектами: Ultimate Video Tutorial, урок 107 2024, November
Anonim
Lesebrytere med ATtiny2313
Lesebrytere med ATtiny2313

Det har vært flere instrukser som omhandler utganger fra ATtiny2313 og lignende AVR -enheter. For eksempel https://www.instructables.com/id/Ghetto-Programming%3a-Getting-started-with-AVR-micro/, https://www.instructables.com/id/Drive-a-Stepper- Motor-med-en-AVR-mikroprosessor/. Ved å jobbe med den siste fra The Real Elliot, som viste hvordan du styrer stepper motorer, fant jeg ut at det ville være veldig nyttig å kunne kjøre alternative deler av koden i det samme programmet, så jeg slapp å omprogrammere ATtiny2313 hver gang jeg ønsket å prøve en liten kodevariasjon (for eksempel halv-trinn eller kjøre stepper i revers). Selv om det er lett å skrive kode ved hjelp av en bryter/saksuttalelse for å tillate valg av alternative varianter, er det nødvendig med en måte å velge saken på. Det betyr at en slags inndataenhet må leses for å kontrollere saken. Heldigvis har ATtiny2313 mange I/O-pinner og er godt designet for å lese innganger fra brytere. Denne instruksen vil vise hvordan du leser innspill og tar beslutninger basert på deres tilstand. Siden det alene ville gjøre en ganske kjedelig instruks, vil jeg forklare en enkel måte å bruke timer/teller -funksjonen til ATtiny2313 til å kjøre en liten høyttaler som en pipelyd. Det vil også være en liten digresjon på enkle feilsøkingsteknikker.

Trinn 1: Inndataenheten

Inndataenheten
Inndataenheten
Inndataenheten
Inndataenheten

Denne instruksen bygger på det utmerkede arbeidet til The Real Elliot og bruker ATtiny2313 Ghetto -utviklingssystemet han beskriver. ATtiny2313 -databladet fra Atmel er den ultimate referansen for alle funksjoner, men det er ikke nødvendigvis lett å lese. https://www.atmel.com/dyn/products/datasheets.asp?family_id=607 (Linken har alle AVR -databladene, finn 2313.) Figuren viser et enkelt sett med inngangsbrytere. Dette er ganske enkelt en pakke med fire av/på -brytere; også kjent som single pole, single throw switches (SPST). Vanligvis er en tilkobling eller pol for hver bryter knyttet til bakken mens den andre forbindelsen trekkes høyt gjennom en strømbegrensende motstand (10K eller så). En mikrokontrollerinngang er koblet til polen med motstanden. Hvis bryteren er åpen, vil mikrokontrolleren lese inngangen som HI. Hvis bryteren er lukket, vil mikrokontrolleren lese inngangen LO. Se skjematisk informasjon for detaljer. ATtiny2313 forenkler ting ved å gi programmerbare opptrekksmotstander på I/O-pinner når de er konfigurert som innganger. Dette betyr at bryterne ganske enkelt kan ha en pol knyttet til bakken (LO) og den andre polen koblet til en prosessorinngang. Det første eksemplet viser bare to brytere. Bryterne leses og konfigureres med følgende kode. Konfigurer bryterne som innganger: (Ingen kode nødvendig; dette er standard.) Slå på opptrekksmotstandene: PORTB = _BV (PB0) | _BV (PB1); Les inngangene: but1 = ~ PINB & 0x03; Legg merke til bruk av inversjon og maskering for å få riktig verdi.

Trinn 2: Blinkenlights for et signal

Vi bruker disse to bryterne til å blinke en LED et programmerbart antall ganger. Lysdiodene vi bruker vil være blinklysene som The Real Elliot gjorde berømt. Bryterne 1 og 2 vil bli behandlet som to binære sifre, slik at kombinasjonen kan representere tallene 0, 1, 2 og 3. Vårt program vil lese de to bryterne og blinke LED -en passende antall ganger, men bare hvis bryteren innstillingene er endret. Bryterne er frakoblet i 500 millisekunder (ikke optimalisert). Avbruddsalgoritmen er ganske enkel. Bryterne leses og avlesningen noteres. Hvis den er forskjellig fra oldBut -verdien (den siste lagrede verdien), blir programmet forsinket i 500 millisekunder og bryterne leses igjen. Hvis verdien er den samme som tidligere lest, oppdateres verdien av oldBut, og LED -en blinker så mange ganger den binære verdien til de to bryterne antyder. Legg merke til inversjonen av verdien siden en bryter som er "på" leser LO. Bryterne vil bli skannet kontinuerlig for ytterligere endringer. Se tidligere Instructables av The Real Elliot for å lære mer om blinkenlights. Ta en titt på denne https://www.ganssle.com/debouncing.pdf for å lære mer om debouncing switches. Her er ATtiny2313 -koden for dette eksemplet. I drift vil dette programmet blinke LED -en på PB4 (fysisk pin 8) to ganger for å vise at den er initialisert. Den vil deretter lese brytere en og to, og blinke en til tre ganger, avhengig av bryterinnstillingen når de endres. Når bryterne ikke endrer seg, vil LED -en blinke sakte. For å kjøre denne koden må du opprette en ny katalog (kall den "Basic" hvis du vil) og laste ned følgende C -kodefil og lage en fil til den. Gi nytt navn til Makefile1.txt til bare Makefile. Bruk WinAVR, kompiler programmet og last det inn i ATtiny2313.

Trinn 3: En mindre digresjon ved feilsøking

Hvis du er som meg (og alle andre programmerere i verden) har du sannsynligvis opplevd tider da den "feilfrie" koden du har skrevet inn og kompilert nøye ikke gjør det du forventer at den skal gjøre. Kanskje det rett og slett ikke gjør noe! Så hva er problemet? Hvordan skal du finne ut? Heldigvis er det flere måter å få ting til å fungere. (Få denne boken for en utmerket behandling av emnet debugging. Http://www.debuggingrules.com/) Jeg vil gjerne tilby noen enkle forslag angående emnet debugging microcontroller applikasjoner. Trinn ett er å bygge videre på hva du vet. Hvis du har fått en blinkenlight til å fungere en gang, kan du bruke den igjen for å se hvor du er i programmet. Jeg liker at LED -lampen blinker to ganger for å signalere starten på programmet. Du kan legge inn koden for å gjøre dette først ved starten av programmet. Når du vet at ingenting er galt med maskinvaren din, kan du lage en funksjon for å blinke. Her er funksjonen jeg bruker./*------------------------------------------ ------------------------------ ** blinkEm-funksjon for å blinke LED ved bruk av PD4 ** PD4 må konfigureres som en utgang. ** ------------------------------------------------ ---------------------*/void blinkEm (uint8_t count) {while (count> 0) {PORTD = _BV (PD4); _forsinkelse_ms (1000); PORTD = ~ _BV (PD4); _forsinkelse_ms (1000); telle--; }} Det er nå mulig å bruke denne funksjonen på forskjellige punkter i koden som et signal om at koden har utført så langt. Å vite at koden kjører betyr at du kan undersøke hver seksjon som har kjørt, men ikke gjort det du forventet, for å finne feil. Å endre én ting om gangen er også en sentral teknikk for feilsøking (beskrevet i referansen ovenfor). Denne klassiske metoden fungerer sammen med "dele og erobre": å ta babysteg for å legge til funksjonalitet trinnvis. Dette kan virke som en treg tilnærming, men det er ikke nær så sakte som å prøve å feilsøke en stor del av ikke-fungerende kode samtidig.

Trinn 4: Mer feilsøking

Det er mange ganger vi vil sjekke en del av koden ved å hoppe over de fleste linjene i den, og deretter aktivere dem en om gangen mens vi bekrefter at hver enkelt fungerer. Vanligvis gjør vi dette ved å "kommentere" linjer vi vil hoppe over. En forlengelse av denne teknikken er å klippe og lime inn en blokk med kode, kommentere originalen (så vi ikke mister den) og hacke unna kopien. C har fire enkle måter å kommentere linjer på. Hvis du setter "//" foran en linje, kommenteres den linjen. Hvis du lukker en eller flere linjer i "/*" og "*/", kommenteres en hel seksjon. For at denne metoden skal fungere effektivt, må det ikke være noen andre "*/" i kodeblokken (annet enn den som slutter). Så en effektiv disiplin er å bruke // for kommentarer i blokkblokker med kode, og reservere / * * / konstruksjonen for kommentarblokker og for å kommentere deler av koden. Plassere "#if 0" i starten av en blokk for å kommentere og avslutte delen med "#endif". Mer selektiv kontroll er mulig ved å bruke "#ifdef (identifier)" i starten av en blokk og "#endif" på slutten. Hvis du vil at blokken skal kompileres, bruker du "#define (identifier)" tidligere i programmet. Vær oppmerksom på at anførselstegnene bare er for vektlegging og ikke skal inkluderes. Kombinering av disse teknikkene bør være en nyttig måte å feilsøke ATtiny2313 -programmene dine på. Du kan finne disse verktøyene nyttige når vi går gjennom denne instruksjonsboken.

Trinn 5: Bruke timer/teller 0 for pip

Bruke timer/teller 0 for pip
Bruke timer/teller 0 for pip

ATtiny2313 har to kraftige timer/tellerressurser: en 8-bit og en 16-bit. Disse kan konfigureres som frekvensgeneratorer, modulerbare regulatorer for variabel pulsbredde og sammenligningsregistre for utganger. Den fulle funksjonaliteten til disse er beskrevet på 49 sider i databladet. Imidlertid bruker vi en enkel sak. Bare timer/teller 0 (8-bits) vil bli brukt, og den vil bare bli brukt som en frekvensgenerator. Frekvensen blir dirigert til en liten høyttaler for å avgi et pip. Timer/Counter 0 er fullstendig beskrevet på sidene 66 til 83 i ATtiny2313 -databladet. En grundig lesing av dette materialet vil gi en fullstendig forståelse av Time/Counter 0. Heldigvis er en ganske enkel modus, Clear Timer on Compare (CTC), alt som kreves for å generere pipetonen vi ønsker.

For modusen vi skal bruke, er timeren/telleren enkel å bruke. Når et klokkesignal velges, starter telleren på null og øker hver klokkepuls. Når tellerverdien når verdien i Output Compare Register (TOP), tilbakestilles telleren til null og tellingen starter igjen. Utgangsbiten assosiert med timeren/telleren veksles for å produsere en kvadratbølge -utgang. Dette driver en lydtransduser direkte til å lage en pipelyd. En liten TDK -lydtransduser gir pipetonen. En passende enhet er Digikey 445-2530-ND, TDK SD1209T3-A1 (jeg brukte en tidlig versjon av denne). Dette er en 3 volt versjon; 5 volts versjonen vil også fungere jeg forventer. Jeg kjører dette direkte fra utgangsporten til Attiny2313, og det ser ut til å fungere fint. Sparkfun har en lignende enhet.

Trinn 6: Konfigurering av timer/teller 0

CTC -modus kan brukes til å bytte utgang OC0A på Pin 2, Port B (fysisk pin 14). For å aktivere utgang på denne pinnen, må DDRB være riktig angitt. C -koden for dette er akkurat som å sette opp en utgang for et blinkenlight. DDRB = _BV (PB2); // Port B2 er en utgang. Det neste trinnet er å levere et klokkesignal og laste ut sammenligningsregisteret for å produsere en bølgeform som en frekvens. Ligningen for den resulterende frekvensen er gitt i databladet (side 72). Termer i ligningen vil bli beskrevet nedenfor. Her er ligningen: fOC0A = fclk_I/O/2*N*(1+OCR0A) Hvor fOC0A: = utgangsfrekvens fclk_I/O: = klokkefrekvensfrekvens N: = forhåndskalkningsfaktor for klokken OCR0A: = verdi i utgangssammenlign register for timer/ Teller 0A. Klokkildefrekvens, fclk_I/ODette er frekvensen til systemklokken. Standardverdien er 1MHz. Bitene CS00, CS01 og CS02 i TCCR0B styrer dette valget. Siden disse bitene også velger verdien av N, beskrives den neste. Precaler Value, NN er verdien som brukes til å dele, eller forhåndskala, systemklokken. Bitene CS00, CS01 og CS02 i TCCR0B styrer dette valget. Tabell 41 på side 81 i ATtiny2313 -databladet beskriver kombinasjonene. Siden en frekvens nær 1 kHz er ønsket, settes bitene CS00 og CS01 i TCCR0B. Vær oppmerksom på at hvis du setter alle tre bitene til 0, og dermed velger ingen klokkekilde, stopper utgangen effektivt. Dette er metoden som vil bli brukt til å starte og stoppe pipetonen. TOP -verdi, OCR0A Denne verdien er TOP -verdien for telleren som lastes inn i Output Compare Register for Timer/Counter 0A. Når denne verdien er nådd, blir telleren nullstilt og tellingen begynner igjen til TOPP er nådd og syklusen gjentas. TOP kan enkelt endres, så frekvensen på piperen er lett å endre. Siden en frekvens nær 1 kHz er ønsket, er TOP satt til 7. (Vær oppmerksom på at forkalkeren kunne ha blitt satt til 8, og TOP satt til 63. Samme resultat - ditt valg.) Utgangsfrekvens, fOC0ABruk ligningen for å beregne utgangsfrekvensresultatene in: fOC0A = 1, 000, 000 /2 * 64 * (1+7) fOC0A = 977HzLukk nok! Her er koden for å laste Output Compare Register og Timer Counter Control Register 0B. Se den faktiske programkoden for å forstå hvordan disse brukes. OCR0A = 7; // Tidsverdi TCCR0B = _BV (CS01) | _BV (CS00); // Velg intern klokke & prescale = 8 TCCR0B = 0; // ingen klokkekilde slår av tonen Innstilling av klokkeslett-/tellermodus Som en siste detalj vil vi spesifisere timer-/tellermodusen vi ønsker ved å sette passende biter i Timer/Counter Control Register 0A. CTC -modus velges ved å sette bit WGM01 som beskrevet i tabell 40, side 79 i databladet. Siden vi vil at utgangen skal veksle hver syklus, må også bit COM0A0 settes som beskrevet i tabell 34 på side 77. Her er koden: TCCR0A = _BV (COM0A0) | _BV (WGM01); // CTC Toggle Mode

Trinn 7: Bruke fire brytere

Når vi implementerer pipetonen, la oss utvide maskinvaren og programvaren til å håndtere fire brytere. Siden utgangen fra Timer Counter 0A er på Port B, pin 2, kan vi ikke bare koble flere brytere sekvensielt til Port B. En enkel løsning ville være å bruke Port D, men la oss beholde porten tilgjengelig for andre funksjoner (kanskje en trinnmotor). Så la oss koble til de ekstra bryterne til PB3 og PB4. Lesing av bryterne er stort sett uendret. Maskeverdien endres til 0x1B (00011011 binær) for å maskere bit 2 sammen med 5, 6 og 7. Et ytterligere triks brukes for å lage et 4-bits binært tall. Skift bit 3 og 4 til høyre en bit og kombiner dem med bitene 0 og 1 til et 4 -bits binært tall. Dette er standard C -syntaks for forskyvning og kombinering av biter, men er kanskje ikke godt kjent for nybegynnere. but1a = (but1 & 0x03) | ((but1 & 0x18) >> 1); // but1 har bryteravlesning I drift blinker programmet to ganger og piper to ganger for å signalisere initialisering. Hver gang bryterne endres, blir nummeret de representerer pipet. Når bryterne ikke endres, blinker LED -en. For å kjøre denne koden må du opprette en ny katalog (kall den pip hvis du vil) og laste ned følgende C -kodefil og lage en fil i den. Gi nytt navn til Makefile2.txt til bare Makefile. Bruk WinAVR, kompiler programmet og last det inn i Attiny2313.

Trinn 8: Bruke Switch/case Construct

Det siste trinnet er "bare programvare": Som lovet implementerer vi switch/case -konstruksjonen. Selv om dette eksemplet bare viser to alternative handlinger, bør det være veldig klart hvordan du bruker denne konstruksjonen til å velge en av flere alternative kodeseksjoner. I drift overvåker dette programmet bryterne, og hvis det er en endring, piper det passende nummeret hvis det er merkelig; det blinker hvis tallet er jevnt. Det gjør ingenting med mindre en bryter endres.

For å kjøre denne koden, opprett en ny katalog (kall den Switch hvis du vil) og last ned følgende C -kodefil og lagre den i den. Gi nytt navn til Makefile3.txt til bare Makefile. Bruk WinAVR, kompiler programmet og last det inn i Attiny2313.

Trinn 9: Konklusjon

Konklusjon
Konklusjon

Så det er det! Nå vet du hvordan du bruker brytere til å kontrollere utførelsen av programmet ditt ved å lese dem inn og velge en handling basert på bryterinnstillingen. Du vet også hvordan du lager en pipetone og har også lært noen feilsøkingsstrategi.

Hvis du vil teste din forståelse, kan du prøve å endre det siste programmet til å pipe på høy tonehøyde hvis det er pipet, pip et lavt notat hvis det er merkelig, og blink LED -en kontinuerlig hvis det ikke er noen endring i bryterne. Du vil kanskje se tilbake til delen om feilsøking for hjelp.

Anbefalt: