Innehållsförteckning:

Läskontakter med ATtiny2313: 9 steg
Läskontakter med ATtiny2313: 9 steg

Video: Läskontakter med ATtiny2313: 9 steg

Video: Läskontakter med ATtiny2313: 9 steg
Video: Голубая стрела (1958) фильм 2024, Juli
Anonim
Läskontakter med ATtiny2313
Läskontakter med ATtiny2313

Det har funnits flera instruktioner som hanterar utdata från ATtiny2313 och liknande AVR -enheter. Till exempel 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-mikroprocessor/. När jag arbetade med den senaste från The Real Elliot, som visade hur man styr stegmotorer, fann jag att det skulle vara riktigt bra att kunna köra alternativa kodavsnitt i samma program så att jag inte behövde programmera om ATtiny2313 vardera gång ville jag prova en liten kodvariation (till exempel halvsteg eller att köra steget i omvänd riktning). Även om det är lätt att skriva kod med hjälp av en switch/case -sats för att möjliggöra val av alternativa varianter, behövs ett sätt att välja fallet. Det betyder att någon form av inmatningsenhet måste läsas för att styra fallet. Lyckligtvis har ATtiny2313 gott om I/O-stift och är väl utformad för att läsa ingångar från switchar. Denna instruktionsbok visar hur man läser inmatningar och fattar beslut baserat på deras tillstånd. Eftersom det ensam skulle göra en ganska tråkig instruerbar, förklarar jag ett enkelt sätt att använda timer/räknare förmågan hos ATtiny2313 för att köra en liten högtalare som en pipare. Det kommer också att finnas en liten avvikelse på enkla felsökningstekniker.

Steg 1: Inmatningsenheten

Inmatningsenheten
Inmatningsenheten
Inmatningsenheten
Inmatningsenheten

Denna instruktör bygger på det utmärkta arbetet med The Real Elliot och använder ATtiny2313 Ghetto -utvecklingssystem som han beskriver. ATtiny2313 -databladet från Atmel är den ultimata referensen för alla funktioner, men det är inte nödvändigtvis lättläst. https://www.atmel.com/dyn/products/datasheets.asp?family_id=607 (Länk har alla AVR -datablad, lokalisera 2313.) Figuren visar en enkel uppsättning ingångsbrytare. Detta är helt enkelt ett paket med fyra på/av -omkopplare; även känd som enpoliga, enkla kastbrytare (SPST). Normalt är en anslutning eller pol för varje strömbrytare bunden till marken medan den andra anslutningen dras högt genom ett strömbegränsande motstånd (10K eller så). En mikrokontrolleringång är ansluten till polen med motståndet. Om omkopplaren är öppen läser mikrokontrollern ingången som HI. Om omkopplaren är stängd läser mikrokontrollern ingången LO. Se schemat för detaljer. ATtiny2313 förenklar saker genom att tillhandahålla programmerbara pull-up-motstånd på I/O-stift när de konfigureras som ingångar. Detta innebär att omkopplarna helt enkelt kan ha en pol bunden till jord (LO) och den andra polen ansluten till en processoringång. Det första exemplet visar bara två omkopplare. Omkopplarna läses och konfigureras med följande kod. Konfigurera omkopplarna som ingångar: (Ingen kod krävs; detta är standard.) Slå på uppdragningsmotstånden: PORTB = _BV (PB0) | _BV (PB1); Läs inmatningarna: but1 = ~ PINB & 0x03; Notera användning av inversion och maskering för att få rätt värde.

Steg 2: Blinkenlights för en signal

Vi kommer att använda dessa två omkopplare för att blinka en lysdiod ett programmerbart antal gånger. Lysdioderna som vi kommer att använda kommer att bli blinklamporna som The Real Elliot gjorde känd. Brytare 1 och 2 behandlas som två binära siffror, så kombinationen kan representera siffrorna 0, 1, 2 och 3. Vårt program läser de två omkopplarna och blinkar LED -lampan rätt antal gånger, men bara om omkopplaren inställningarna har ändrats. Växlarna är avstängda i 500 millisekunder (inte optimerade). Avstängningsalgoritmen är ganska enkel. Brytarna läses och avläsningen noteras. Om det skiljer sig från oldBut -värdet (det senast sparade värdet), fördröjs programmet i 500 millisekunder och omkopplarna läses igen. Om värdet är detsamma som tidigare läst, uppdateras värdet på oldBut och lysdioden blinkar det antal gånger som de två switcharnas binära värde antyder. Notera inversionen av värdet eftersom en omkopplare som är "på" läser LO. Växlarna kommer att skannas kontinuerligt för ytterligare ändringar. Se tidigare instruktioner från The Real Elliot för att lära dig mer om blinkenlights. Ta en titt på denna https://www.ganssle.com/debouncing.pdf för att lära dig mer om avbrytande switchar. Här är ATtiny2313 -koden för detta exempel. I drift kommer detta program att blinka lysdioden på PB4 (fysisk stift 8) två gånger för att visa att den är initierad. Den läser sedan omkopplare en och två och blinkar en till tre gånger beroende på omkopplarinställningen när de ändras. När omkopplarna inte ändras blinkar lysdioden långsamt. För att köra den här koden, skapa en ny katalog (kalla den "Basic" om du vill) och ladda ner följande C -kodfil och göra en fil till den. Byt namn på Makefile1.txt till bara Makefile. Använd WinAVR, kompilera programmet och ladda det i din ATtiny2313.

Steg 3: En mindre nedbrytning vid felsökning

Om du är som jag (och alla andra programmerare i världen) har du förmodligen upplevt tider då den "felfria" koden du noggrant har skrivit in och sammanställt inte gör vad du förväntar dig att den ska göra. Kanske gör det helt enkelt ingenting! Så vad är problemet? Hur ska du ta reda på det? Lyckligtvis finns det flera sätt att få saker att fungera. (Skaffa den här boken för en utmärkt behandling av ämnet felsökning. Http://www.debuggingrules.com/) Jag skulle vilja ge några enkla förslag som rör ämnet felsökning av mikrokontroller. Steg ett är att bygga vidare på vad du vet. Om du har fått en blinkenlight att fungera en gång, använd den igen för att se var du är i ditt program. Jag gillar att lysdioden blinkar två gånger för att signalera att programmet startar. Du kan sätta in koden för att göra detta initialt i början av ditt program. När du vet att inget är fel med din hårdvara, skapa en funktion för att blinka. Här är funktionen jag använder./*------------------------------------------ ------------------------------ ** blinkEm-funktion för att blinka LED med PD4 ** PD4 måste konfigureras som en utgång. ** ------------------------------------------------ ---------------------*/void blinkEm (uint8_t count) {while (count> 0) {PORTD = _BV (PD4); _fördröjning_ms (1000); PORTD = ~ _BV (PD4); _fördröjning_ms (1000); räkna--; }} Det är nu möjligt att använda den här funktionen på olika punkter i din kod som en signal om att koden har körts så långt. Att veta att koden kör betyder att du noggrant kan granska varje avsnitt som har körts, men inte gjort vad du förväntat dig, för att hitta fel. Att ändra en sak i taget är också en nyckelteknik för felsökning (beskrivs i referensen ovan). Denna klassiska metod fungerar tillsammans med "dela och erövra": ta babysteg för att lägga till funktionalitet stegvis. Det här kan verka som ett långsamt tillvägagångssätt, men det är inte så långsamt som att försöka felsöka en stor del av icke-fungerande kod på en gång.

Steg 4: Mer felsökning

Det finns många gånger när vi vill kontrollera en koddel genom att hoppa över de flesta raderna i den och sedan aktivera dem en i taget när vi kontrollerar att alla fungerar. Normalt gör vi detta genom att "kommentera" rader som vi vill hoppa över. En förlängning av denna teknik är att klippa och klistra in ett kodblock, kommentera originalet (så att vi inte tappar det) och hacka bort kopian. C har fyra enkla sätt att kommentera rader. Att sätta "//" framför en rad kommenterar den raden. Om du stänger en eller flera rader i "/*" och "*/" kommer du att kommentera ett helt avsnitt. För att denna metod ska fungera effektivt måste det inte finnas något annat "*/" i kodblocket (annat än det slutande). Så en effektiv disciplin är att använda // för kommentarer inom block av kod, och reservera / * * / konstruktionen för kommentarsblock och för att kommentera delar av koden. Placera "#if 0" i början av ett block för att kommentera och avsluta avsnittet med "#endif". Mer selektiv kontroll är möjlig med "#ifdef (identifierare)" i början av ett block och "#endif" i slutet. Om du vill att blocket ska kompileras, använd "#define (identifier)" tidigare i programmet. Observera att citattecknen endast är för betoning och ska inte inkluderas. Att kombinera dessa tekniker bör vara ett användbart sätt att felsöka dina ATtiny2313 -program. Du kan tycka att dessa verktyg är användbara när vi går igenom denna instruktionsbok.

Steg 5: Använda timer/räknare 0 för pip

Använda timer/räknare 0 för pip
Använda timer/räknare 0 för pip

ATtiny2313 har två kraftfulla timer/räknare resurser: en 8-bitars och en 16-bitars. Dessa kan konfigureras som frekvensgeneratorer, modulerbara variabler för pulsbredd och utgångsjämförelseregister. Den fullständiga funktionaliteten för dessa beskrivs på 49 sidor i databladet. Vi använder dock ett enkelt fall. Endast Timer/Counter 0 (8-bitars) kommer att användas och den kommer att användas helt enkelt som en frekvensgenerator. Frekvensen dirigeras till en liten högtalare för att avge ett pip. Timer/Counter 0 beskrivs fullständigt på sidorna 66 till 83 i ATtiny2313 -databladet. En noggrann läsning av detta material ger en fullständig förståelse för Time/Counter 0. Lyckligtvis är ett ganska enkelt läge, Clear Timer on Compare (CTC) allt som krävs för att generera den pipton vi vill ha.

För det läge vi ska använda är timern/räknaren enkel att använda. När en klocksignal väljs startar räknaren på noll och ökar varje klockpuls. När räknarvärdet når värdet i Output Compare Register (TOP), återställs räknaren till noll och räkningen börjar igen. Utmatningsbiten associerad med timern/räknaren växlas för att producera en fyrkantvågsutmatning. Detta driver direkt en ljudomvandlare för att göra ett pipljud. En liten TDK -ljudomvandlare ger pip. En lämplig enhet är Digikey 445-2530-ND, TDK SD1209T3-A1 (jag använde en tidig version av detta). Detta är en 3 volt version; 5 volt -versionen kommer också att fungera förväntar jag mig. Jag kör detta direkt från utgångsporten på Attiny2313 och det verkar fungera bra. Sparkfun har en liknande enhet.

Steg 6: Konfigurera timer/räknare 0

CTC -läge kan användas för att växla utgången OC0A på stift 2, port B (fysisk stift 14). För att aktivera utmatning på denna pin måste DDRB vara korrekt inställd. C -koden för detta är precis som att ställa in en utgång för en blinkenlight. DDRB = _BV (PB2); // Port B2 är en utsignal. Nästa steg är att leverera en klocksignal och ladda utgångsjämförelsesregistret för att producera en vågform som en frekvens. Ekvationen för den resulterande frekvensen anges i databladet (sidan 72). Termer i ekvationen kommer att beskrivas nedan. Här är ekvationen: fOC0A = fclk_I/O/2*N*(1+OCR0A) Där fOC0A: = utgångsfrekvens fclk_I/O: = klockans källfrekvens N: = klockans förskalningsfaktor OCR0A: = värde i utgången jämför register för timer/ Counter 0A. Clock Source Frequency, fclk_I/ODetta är systemklockans frekvens. Standardvärdet är 1 MHz. Bitarna CS00, CS01 och CS02 i TCCR0B styr detta val. Eftersom dessa bitar också väljer värdet på N, beskrivs det nästa. Förkalkningsvärde, NN är det värde som används för att dela eller förskala systemklockan. Bitarna CS00, CS01 och CS02 i TCCR0B styr detta val. Tabell 41 på sidan 81 i ATtiny2313 -databladet beskriver kombinationerna. Eftersom en frekvens nära 1 kHz önskas kommer bitarna CS00 och CS01 i TCCR0B att ställas in. Observera att inställningen av alla tre bitarna till 0, vilket innebär att ingen klockkälla väljs, effektivt stoppar utmatningen. Detta är metoden som kommer att användas för att starta och stoppa pipet. TOP -värde, OCR0A Detta värde är TOP -värdet för räknaren som laddas in i Output Compare Register för Timer/Counter 0A. När detta värde har uppnåtts kommer räknaren att återställas till noll och räkningen börjar igen tills TOP har uppnåtts och cykeln upprepas. TOP kan enkelt ändras så att piparens frekvens är lätt att ändra. Eftersom en frekvens nära 1 kHz önskas, är TOP inställd på 7. (Observera att förkalkningsanordningen kunde ha ställts in på 8 och TOP inställd på 63. Samma resultat - ditt val.) Utmatningsfrekvens, fOC0AAnvändning av ekvationen för att beräkna utgångsfrekvensresultaten in: fOC0A = 1, 000, 000 /2 * 64 * (1+7) fOC0A = 977HzNära nog! Här är koden för att ladda Output Compare Register och Timer Counter Control Register 0B. Se den faktiska programkoden för att förstå hur dessa används. OCR0A = 7; // Tidsvärde TCCR0B = _BV (CS01) | _BV (CS00); // Välj intern klocka & prescale = 8 TCCR0B = 0; // ingen klockkälla stänger av tonen Ställer in tid/räknarläget Som en sista detalj kommer vi att specificera det timer-/räknarläge vi önskar genom att ställa in lämpliga bitar i timer-/räknarkontrollregistret 0A. CTC -läge väljs genom att ställa in bit WGM01 enligt beskrivningen i tabell 40, sidan 79 i databladet. Eftersom vi vill att utgången ska växla varje cykel måste bit COM0A0 också ställas in enligt beskrivningen i tabell 34 på sidan 77. Här är koden: TCCR0A = _BV (COM0A0) | _BV (WGM01); // CTC -växlingsläge

Steg 7: Använda fyra switchar

När vi implementerar pipet, låt oss utöka vår hårdvara och programvara för att hantera fyra switchar. Eftersom utmatningen från Timer Counter 0A finns på port B, stift 2, kan vi inte helt enkelt ansluta fler omkopplare sekventiellt till Port B. En enkel lösning skulle vara att använda Port D, men låt oss ha den porten tillgänglig för andra funktioner (kanske en stegmotor). Så låt oss ansluta de extra omkopplarna till PB3 och PB4. Att läsa omkopplarna är för det mesta oförändrat. Maskvärdet ändras till 0x1B (00011011 binärt) till maskbit 2 tillsammans med 5, 6 och 7. Ett ytterligare trick används för att skapa ett 4-bitars binärt tal. Skift bit 3 och 4 åt höger en bit och kombinera dem med bitarna 0 och 1 till ett 4 -bitars binärt tal. Detta är standard C -syntax för att skifta och kombinera bitar, men är kanske inte välkänt för nybörjaren. but1a = (but1 & 0x03) | ((but1 & 0x18) >> 1); // but1 har switchläsning I drift blinkar programmet två gånger och pip två gånger för att signalera initialisering. Varje gång omkopplarna ändras kommer det nummer som de representerar att pipas. När omkopplarna inte ändras blinkar lysdioden. För att köra den här koden skapar du en ny katalog (kalla den pip om du vill) och laddar ner följande C -kodfil och gör en fil i den. Byt namn på Makefile2.txt till bara Makefile. Använd WinAVR, kompilera programmet och ladda det i din Attiny2313.

Steg 8: Använda Switch/case Construct

Det sista steget är "bara programvara": Som utlovat implementerar vi switch/case -konstruktionen. Även om detta exempel bara visar två alternativa åtgärder, bör det vara mycket tydligt hur man använder denna konstruktion för att välja en av flera alternativa kodavsnitt. I drift övervakar detta program omkopplarna och om det blir en förändring kommer det att pipa rätt nummer om det är udda; det blinkar om talet är jämnt. Det gör ingenting om inte en switch ändras.

För att köra den här koden, skapa en ny katalog (kalla den Switch om du vill) och ladda ner följande C -kodfil och gör filen till den. Byt namn på Makefile3.txt till bara Makefile. Använd WinAVR, kompilera programmet och ladda det i din Attiny2313.

Steg 9: Slutsats

Slutsats
Slutsats

Så det är det! Nu vet du hur du använder switchar för att styra körningen av ditt program genom att läsa in dem och välja en åtgärd baserat på switchinställningen. Du vet också hur du skapar en pipton och har också lärt dig en del felsökningsstrategi.

Om du vill testa din förståelse kan du prova att ändra det sista programmet för att pipa vid en hög tonhöjd om det är jämnt, pipa en låg ton om det är udda och blinka lysdioden kontinuerligt om det inte är någon förändring i omkopplarna. Du kanske vill titta tillbaka till avsnittet om felsökning för hjälp.

Rekommenderad: