Innholdsfortegnelse:
- Trinn 1: Søk etter et tastatur 1
- Trinn 2: Søk etter et tastatur 2
- Trinn 3: Søk etter et tastatur 3
- Trinn 4: Koble til tastaturet
- Trinn 5: Koble tastaturet til analysatoren
- Trinn 6: Hvilke vippebrytere bør vi sette?
- Trinn 7: Skriv Interrupt Handler
- Trinn 8: Kartlegg tastaturverdiene
- Trinn 9: Kode og video for versjon 1
- Trinn 10: Kode for versjon 2
- Trinn 11: Hvordan bli kvitt knappen? Versjon 3
- Trinn 12: Kode og video for arbeidsversjonen
Video: AVR Assembler Opplæring 7: 12 trinn
2024 Forfatter: John Day | [email protected]. Sist endret: 2024-01-30 11:20
Velkommen til opplæring 7!
I dag skal vi først vise hvordan du kan rense et tastatur, og deretter vise hvordan du bruker de analoge inngangsportene til å kommunisere med tastaturet. Vi vil gjøre dette ved å bruke avbrudd og en enkelt ledning som inngang. Vi vil koble tastaturet slik at hvert tastetrykk sender en unik spenning til den analoge inngangen som lar oss skille med spenningen som tasten ble trykket på. Deretter sender vi ut nummeret som er trykket til vår registeranalysator for å vise at alt skjer som det skal. Det er en rekke fallgruver som du kan løpe inn i når du bruker Analog to Digital Converter (ADC) i ATmega328p, og så vil vi ta ting på noen få trinn på veien for å prøve å finne ut hvordan du kan unngå dem. Vi vil også se hvorfor bruk av den analoge til digitale omformeren ikke er den beste måten å kontrollere et tastatur på, selv om den bruker færre porter på mikrokontrolleren. I denne opplæringen trenger du:
- et tastatur. Du kan kjøpe en, eller du kan gjøre det jeg gjorde og finne en.
- 2 kvinnelige overskrifter for tastaturet (hvis du skal fjerne en)
- tilkobling av ledninger
- et brødbrett
- 4 1 Kohm motstander
- 1 15 Kohm motstand
- 1 3.3 Kohm motstand
- 1 180 ohm motstand
- 1680 ohm motstand
- et digitalt multimeter
- analysatoren din fra opplæring 5
Det kan være lurt å hoppe over de første trinnene hvis du allerede har et tastatur og ikke trenger å finne et.
Her er en lenke til den komplette samlingen av mine AVR assembler-opplæringsprogrammer:
Trinn 1: Søk etter et tastatur 1
For lenge siden, da selv besteforeldrene dine var barn, pleide folk å bruke disse merkelige enhetene, som hadde lange kabler koblet til veggen, for å kommunisere med hverandre. De ble kalt "telefoner" og var vanligvis billige plast ting som ga en irriterende lyd når noen ringte deg (ikke at dagens "Justin Bieber" ringetoner ikke er like irriterende). Uansett hadde disse enhetene tastaturer på dem som var ganske enkelt kablet og så er enkle å finne, og de har to ekstra taster på dem ("ring opp" og "blits") fra tastaturene du kan kjøpe som du kanskje vil bruke på nytt. som "piltaster", "menytaster" eller noe annet. Så vi skal begynne med å fjerne et tastatur fra en gammel telefon. Ta først telefonen (jeg bruker en GE som vist på bildene) og lir den fra hverandre for å avsløre ledningene. Ta deretter en meisel og klikk av de små plastknappene som holder tastaturet på, og fjern tastaturet.
Trinn 2: Søk etter et tastatur 2
Ta nå en PVC -sag og kutt plasten rundt nøkkelhullene, og skjær deretter rundt kanten for å få dybden riktig og etterlate et tynt tastatur.
Sett deretter på tastaturet igjen ved å bruke de små pinnene som er igjen etter at du klippet toppene av dem i det siste trinnet, og bruk et loddejern til å stikke det varme jernet i hvert pinnehull som vil smelte plasten og spre det ut over bunnen av tastaturet som danner nye "knotter" som holder tastaturet på plass som før.
Jeg liker å finne de tre høyttalerne og kanskje andre ting som brytere og hva som ikke er på tavlen. Denne gangen kommer jeg imidlertid ikke til å rense brytere og sånt fordi vi har andre mål for øyeblikket. Det er også en TA31002 lineær IC der inne, som er en ringesignal. Databladet er enkelt å finne og laste ned på nettet, noe som gir pinout og funksjoner. Så jeg kommer til å la det lodde til brettet for nå og deretter leke med det senere. Jeg vil gjerne koble den til et oscilloskop og se hvilke kule signaler jeg kan få ut av det. Kanskje til og med lage en dørklokke av det. Hvem vet.
Uansett, når du er ferdig med å ødelegge telefonen og rense delene, vil vi gjøre ferdig vårt tastatur.
Trinn 3: Søk etter et tastatur 3
Bruk en avlodingsvei og fjern båndkablene fra bunnen av tastaturet, og kontroller at hullene i kretskortet er klare, og fest deretter to hunnhoder på brettet der hullene er. Du må sannsynligvis klippe ned overskriftene dine slik at de er 4-pinners overskrifter.
Nå som overskriftene er festet, kan du koble den til et brødbrett, ta et multimeter og teste tastene ved å stikke multimeteret over tilfeldige pinner og måle motstanden. Dette lar deg kartlegge nøklene. Det er vanskelig å se hvordan tastene er koblet til utgangene ved å se på kretsen, men hvis du bruker et multimeter kan du koble den til to pins og deretter trykke på knappene til du ser et tall på skjermen i stedet for en åpen krets. Dette vil være pinout for den nøkkelen.
Kartlegg alle nøklene til utgangspinnene på denne måten.
Trinn 4: Koble til tastaturet
Følg nå koblingsskjemaet og koble tastaturet til brødbrettet.
Hvordan dette kommer til å fungere er at vi legger 5V på venstre side og høyre side går til GND. Den første pinnen til høyre i diagrammet går inn i den første av våre analoge pinner på Atmega328p mikrokontroller. Når det ikke er trykket på noen knapper, vil signalet være 0V, og når hver av de forskjellige knappene trykkes, vil inngangen til den analoge porten variere mellom 0V og 5V med en annen mengde avhengig av hvilken tast som ble trykket. Vi valgte motstandsverdiene slik at hver bane skulle inneholde en motstand som var forskjellig fra resten. Den analoge porten på mikrokontrolleren tar et analogt signal og deler det i 1024 forskjellige kanaler mellom 0V og 5V. Dette betyr at hver kanal har en bredde 5V/1024 = 0,005 V/kanal = 5 mV/kanal. Så den analoge porten kan skille inngangsspenninger så lenge de er mer enn 5 mV. I vårt tilfelle har vi valgt motstandsverdier slik at to tastetrykk sender et spenningssignal som er mer enn dette, slik at mikrokontrolleren enkelt kan bestemme hvilken tast som ble trykket. Det store problemet er at hele systemet er veldig bråkete, så vi må velge et spenningsområde for å kartlegge hvert knappetrykk - men vi kommer til det litt senere.
Legg merke til at vi er i stand til å styre et tastatur med 14 knapper ved hjelp av bare en enkelt inngangslinje til kontrolleren. Det er en av de nyttige aspektene ved analoge innganger.
Nå vil vårt første forsøk på å kontrollere tastaturet være å få et tastetrykk til å forårsake et avbrudd, avbruddsrutinen vil lese den analoge inngangsporten og bestemme hvilken tast som ble trykket, og deretter vil det sende det nummeret til vår registeranalysator -underprogram som vil vise nøkkelverdi i binær på våre 8 lysdioder som vi satte opp i opplæring 5.
Trinn 5: Koble tastaturet til analysatoren
Bildene viser hvordan vi vil koble tastaturet til mikrokontrolleren slik at vi kan se utgangen på analysatorens display. I hovedsak kobler vi utgangen fra tastaturet til PortC pin 0, som også kalles ADC0 på ATmega328P.
Imidlertid er det et par ting til. Vi kommer også til å koble en knapp til PD2. Dvs. ta en ledning fra din 5V -skinne til en knapp og fra den andre siden av knappen til PD2, og til slutt vil vi koble AREF -pinnen fra vår 5V -skinne og i stedet la den være frakoblet. Vi kan sette inn en 0,1 mikrofarad frakoblingskondensator hvis vi vil. Dette er en keramisk kondensator med 104 skrevet på. De to første sifrene er tallet og det siste sifferet er effekten til 10 vi multipliserer det med for å få svar i picofarads (pico betyr 10^-12), Så 104 betyr 10 x 10^4 picofarads, som er det samme som 100 nanofarader (nano betyr 10^-9), som er det samme som 0,1 mikrofarad (mikro betyr 10^-6). Uansett, alt dette gjør er å stabilisere AREF -pinnen når vi kan bruke den som referansepinne.
Vi ønsker også en 1 Mohm motstand mellom PD2 og bakken. Vi skal sette PD2 som en utgangspinne på 0V, og vi vil utløse på en positiv kant ved den pinnen. Vi vil at kanten skal forsvinne umiddelbart når vi slipper knappen, så vi setter inn denne "trekk ned" -motstanden.
Grunnen til at vi vil ha knappen er fordi vi ønsker å utløse vår Analog-til-Digital-omformer av pin INT0 på brikken, som også er PD2. Til slutt vil vi at tastetrykket både skal utløse ADC og også gi inngangen som skal konverteres uten å ha en egen knapp, men på grunn av måten timingen fungerer på, begynner vi med å ha en egen knapp for å utløse ADC og når vi stryker alle feilene ut og er sikre på at alt fungerer som det skal, så tar vi tak i problemene med støy og timing som følger med utløsningen fra det samme knappetrykket som vi vil lese.
Så for øyeblikket fungerer det slik at vi holder nede en tast, deretter trykker du på knappen for å utløse ADC, og deretter slipper vi og forhåpentligvis vil den binære verdien til knappen vi trykket dukke opp på analysatoren.
Så la oss skrive noen kode som vil oppnå det.
Trinn 6: Hvilke vippebrytere bør vi sette?
La oss først tenke på hvordan vi skal kode dette, slik at kontrolleren kan lese inngangen fra tastaturet og gjøre den til en numerisk verdi som tilsvarer knappen som ble trykket på. Vi skal bruke Analog to Digital Converter (ADC) som er innebygd i Atmega328p. Vi bruker AREF som referansespenning, og tastaturutgangen blir koblet til PortC0 eller PC0. Vær oppmerksom på at denne pinnen også kalles ADC0 for Analog-to-Digital Converter 0. Det kan være en god idé for deg å lese gjennom avsnitt 12.4 om interrupts for ATmega328P og også kapittel 24 om Analog-to-Digital Converter før vi får startet eller i det minste ha disse delene klare for referanse. For å sette opp mikrokontrolleren slik at den vet hva han skal gjøre med et analogt inngangssignal og hvordan den skal samhandle med programmet vårt, må vi først angi noen av de forskjellige ADC -ene relaterte registerbiter. Disse tilsvarer i hovedsak de gamle vippebryterne på de første datamaskinene. Du slår enten en bryter PÅ eller AV, eller enda lenger tilbake kobler du til kabler mellom en stikkontakt og en annen slik at elektroner som kommer til den gaffelen i veien, finner en port lukket og en annen åpen og tvinger den ned en annen vei i labyrinten av kretsløp og dermed utføre en annen logisk oppgave. Når vi koder på samlingsspråk, har vi nær tilgang til disse funksjonene til mikrokontrolleren, noe som er en av de attraktive tingene ved å gjøre det i utgangspunktet. Det er mer "hands on" og langt mindre skjer "bak kulissene" så å si. Så ikke tenk på å sette disse registrene som en kjedelig oppgave. Dette er det som gjør monteringsspråk interessant! Vi får et veldig personlig forhold til chipens indre virkemåte og logikk og får den til å gjøre akkurat det vi vil - ikke mer og ikke mindre. Ingen bortkastede klokkesykluser. Så her er en liste over bryterne vi må sette:
- Slå av strømreduksjon ADC -bit, PRADC, som er bit 0 i PRR -registeret, siden hvis denne biten er på, vil den slå av ADC. Effektreduksjonsregisteret er i hovedsak en måte å slå av forskjellige ting som bruker strøm når du ikke trenger dem. Siden vi bruker ADC, vil vi sørge for at den ikke er deaktivert på denne måten. (Se PRADC på side 46)
- Velg den analoge inngangskanalen som skal være ADC0 ved å slå av MUX3… 0 i ADC Multiplexer Selection (ADMUX) -registeret (se tabell 24-4 side 249) disse er allerede av som standard, så vi trenger egentlig ikke gjøre dette. Imidlertid inkluderer jeg det, siden hvis du noen gang bruker en annen port enn ADC0, må du bytte disse bryterne tilsvarende. Ulike kombinasjoner av MUX3, MUX2, MUX1, MUX0 lar deg bruke hvilken som helst av de analoge portene som inngang, og du kan også endre disse på farten hvis du vil se på en haug med forskjellige analoge signaler samtidig.
- Slå av REFS0 og REFS1 biter i ADMUX -registeret slik at vi skal bruke AREF som referansespenning i stedet for en intern referanse (se side 248).
- Slå på ADLAR -biten i ADMUX, så resultatet blir "venstrejustert". Vi diskuterer dette valget i neste trinn.
- Sett ADC0D -biten i Digital Input Disable Register (DIDR0) for å slå av digital inngang til PC0. Vi bruker den porten for analog inngang, så vi kan like godt deaktivere den digitale inngangen for den.
- Sett ISC0 og ISC1 i eksternt avbruddskontrollregister A (EICRA) for å indikere at vi ønsker å utløse på den stigende kanten av et spenningssignal til INT0 -pinnen (PD2), se side 71.
- Fjern bits INT0 og INT1 i External Interrupt Mask Register (EIMSK) for å indikere at vi ikke bruker avbrudd på denne pinnen. Hvis vi skulle aktivere avbrudd på denne pinnen, ville vi trenge en avbruddshåndterer på adresse 0x0002, men i stedet setter vi den opp slik at et signal på denne pinnen utløser ADC -konverteringen, hvis fullføring håndteres av ADC -konverteringen fullstendig avbrudd kl. adresse 0x002A. Se side 72.
- Sett ADC Enable (ADEN) -biten (bit 7) i ADC -kontrollen og statusregisteret A (ADCSRA) for å aktivere ADC. Se side 249.
- Vi kunne starte en enkelt konvertering ved å sette ADC start -konverteringsbiten (ADSC) hver gang vi ønsket å lese det analoge signalet, men foreløpig vil vi heller ha det lest automatisk når noen trykker på knappen, så i stedet vil vi aktivere ADC Autotrigger Aktiver (ADATE) bit i ADCSRA -registeret slik at utløsningen utføres automatisk.
- Vi satte også ADPS2..0 -bitene (AD Prescalar -bitene) til 111 slik at ADC -klokken er CPU -klokken delt på en faktor 128.
- Vi vil velge kilden for ADC -utløseren til å være PD2, som også kalles INT0 (ekstern avbruddsforespørsel 0). Vi gjør dette ved å veksle mellom de forskjellige bitene i ADCSRB-registeret (se tabell 24-6 på side 251). Vi ser ved tabellen at vi vil ha ADTS0 av, ADTS1 på og ADTS2 av slik at ADC vil utløse den pinnen. Vær oppmerksom på at hvis vi ønsket å prøve den analoge porten kontinuerlig, som om vi leste et kontinuerlig analogt signal (som lydsampling eller noe), ville vi sette dette til Free Running Mode. Metoden vi bruker for å sette triggering på PD2 utløser en ADC -lesning av den analoge porten PC0 uten å forårsake et avbrudd. Avbruddet kommer når konverteringen er fullført.
- Aktiver ADC Interrupt Enable (ADIE) -biten i ADCSRA -registeret, slik at når den analoge til digitale konverteringen er fullført, vil den generere et avbrudd som vi kan skrive en avbruddshåndterer for og sette på.org 0x002A.
- Sett I -biten i SREG for å aktivere avbrudd.
Oppgave 1: Sørg for å lese de relevante avsnittene i databladet for hver av innstillingene ovenfor, slik at du forstår hva som skjer og hva som ville skje hvis vi endret dem til alternative innstillinger.
Trinn 7: Skriv Interrupt Handler
I det siste trinnet så vi at vi har satt det opp slik at en stigende kant som oppdages på PD2 vil utløse en analog til digital konvertering på PC0, og når denne konverteringen er fullført, vil den kaste et ADC Conversion Complete -interrupt. Nå vil vi gjøre noe med dette avbruddet. Hvis du undersøker tabell 12-6 på side 65, vil du se en liste over mulige avbrudd. Vi har allerede sett RESET -avbruddet på adressen 0x0000 og Timer/Counter0 Overflow -avbruddet på adressen 0x0020 i tidligere opplæringsprogrammer. Nå vil vi se på ADC -avbruddet som vi ser ved tabellen på adressen 0x002A. Så i begynnelsen av forsamlingens språkkode trenger vi en linje som lyder:
.org 0x002Arjmp ADC_int
som vil hoppe til avbryterbehandleren vår merket ADC_int når ADC har fullført en konvertering. Så hvordan skal vi skrive avbryterbehandleren? Måten ADC fungerer på er ved å utføre følgende beregning:
ADC = Vin x 1024 / Vref
Så la oss se hva som skjer hvis jeg trykker på "gjenoppringing" -knappen på tastaturet. I så fall vil spenningen på PC0 endres til en viss verdi, si 1,52V, og siden Vref er på 5V vil vi ha:
ADC = (1,52V) x 1024 / 5V = 311,296
og så ville det vise seg som en 311. Hvis vi ønsket å konvertere dette tilbake til en spenning, ville vi bare reversere beregningen. Vi trenger imidlertid ikke å gjøre dette siden vi ikke er interessert i de faktiske spenningene bare for å skille mellom dem. Når konverteringen er fullført, lagres resultatet i et 10-bits tall plassert i ADCH- og ADCL-registre, og vi har forårsaket at det er "venstrejustert", noe som betyr at 10-bitene starter på bit 7 i ADCH og går ned til bit 6 i ADCL (det er totalt 16 biter i disse to registrene, og vi bruker bare 10 av dem, dvs. 1024 kanaler). Vi kan få resultatet "høyre justert" hvis vi vil ved å fjerne ADLAR -biten i ADMUX -registeret. Grunnen til at vi velger venstrejustert er fordi signalene våre er langt nok fra hverandre til at de to siste sifrene i kanalnummeret ikke er relevante og er sannsynligvis bare støy, så vi vil skille tastetrykkene bare med de 8 øverste sifrene, med andre ord trenger vi bare å se på ADCH for å finne ut hvilken knapp som ble trykket på. Så vår avbryterbehandler burde ganske enkelt lese nummeret ut av ADCH registrer, konverter dette tallet til et tastaturverdi, og send deretter verdien til våre registeranalysatorlysdioder slik at vi kan bekrefte at ved å trykke på et "9" -signal, vil lysdiodene som tilsvarer "00001001" lyse. Før vi går langt selv om vi først må se hva som dukker opp i ADCH når vi trykker på de forskjellige knappene. Så la oss bare skrive en enkel avbruddshåndterer som bare sender innholdet i ADCH til analysatorskjermen. Så her er det vi trenger:
ADC_int: lds analysator, ADCH; last verdien av ADCH inn i vår analysatorbi EIFR, 0; fjerne det eksterne avbruddsflagget slik at det er klart til å gå på nytt
Nå bør du bare kunne kopiere koden fra analysatoren vår i opplæring 5 og legge til denne avbrytelsen og veksleinnstillingene og kjøre den. Oppgave 2: Skriv koden og kjør den. Se at ADCH vises på analysatorens display. Prøv å trykke på det samme tastetrykket flere ganger. Får du alltid samme verdi i ADCH?
Trinn 8: Kartlegg tastaturverdiene
Det vi må gjøre nå er å konvertere verdiene i ADCH til tall som tilsvarer tasten som ble trykket. Vi gjør dette ved å skrive ut innholdet i ADCH for hvert tastetrykk og deretter konvertere det til et desimalnummer som jeg gjorde på bildet. I rutinen for avbruddshåndtering vil vi vurdere et helt spekter av verdier som tilsvarer hvert tastetrykk, slik at ADC vil kartlegge alt i dette området til et gitt tastetrykk.
Øvelse 3: Gjør denne mappngen, og skriv deretter ADC-avbruddsrutinen på nytt.
Her er hva jeg fikk for min (din vil sannsynligvis være annerledes). Legg merke til at jeg har satt det opp med en rekke verdier for hvert tastetrykk.
ADC_int:; Ekstern interrupt handlerclr analysator; forberede seg på nye tallknapp H, ADCH; ADC oppdateres når ADCH leses clccpi -knapp H, 240brlo PC+3; hvis ADCH er større så er det en 1ldi analysator, 1; så last analysator med en 1rjmp retur; og retur clccpi -knapp H, 230; hvis ADCH er større enn en 2brlo PC+3ldi analysator, 2rjmp retur clccpi knapp H, 217brlo PC+3ldi analysator, 3rjmp retur clccpi knapp H, 203brlo PC+3ldi analysator, 4rjmp retur clccpi knapp H, 187brlo PC+3ldi analysator, 5rjmp retur clccpi knapp, 155brlo PC+3ldi analysator, 6rjmp retur clccpi knapp H, 127brlo PC+3ldi analysator, 255; vi vil angi blits som alle onrjmp retur clccpi knapp H, 115brlo PC+3ldi analysator, 7rjmp retur clccpi knapp H, 94brlo PC+3ldi analysator, 8rjmp retur clccpi knapp H, 62brlo PC+3ldi analysator, 9rjmp retur clccpi knapp H, 37brlo PC+3ldi analysator, 0b11110000; stjerne er øverste halvdel onrjmp retur clccpi -knapp H, 28brlo PC+3ldi -analysator, 0rjmp retur -clccpi -knappH, 17brlo PC+3ldi -analysator, 0b00001111; hash -tegn er nederste halvdel onrjmp retur clccpi -knapp H, 5brlo PC+3ldi analysator, 0b11000011; gjenoppringing er topp 2 bunn 2rjmp return ldi analysator, 0b11011011; ellers oppstod feil retur: reti
Trinn 9: Kode og video for versjon 1
Jeg har lagt ved koden min for denne første versjonen av tastaturdriveren. I denne må du trykke på tasten og deretter trykke på knappen for å få ADC til å lese inngangen fra tastaturet. Det vi helst vil ha er ingen knapp, men signalet om å gjøre konverteringen kommer fra selve tastetrykket. Øvelse 3: Sett sammen og last opp denne koden og prøv den. Du må kanskje endre de forskjellige konverteringstersklene for å svare til tastetrykkspenningene dine siden de sannsynligvis er forskjellige fra mine. Hva skjer hvis du prøver å bruke en inngang fra tastaturet både for ADC0 og for den eksterne avbryterpinnen i stedet for gjennom en knapp? Jeg vil også legge ved en video av driften av denne første versjonen av tastaturdriveren. Du vil legge merke til at i koden min er det en seksjon som initialiserer Stack Pointer. Det er forskjellige registre som vi kanskje vil skyve og poppe fra stabelen når vi manipulerer variabler og hva-ikke, og det er også registre som vi kanskje vil lagre og gjenopprette senere. For eksempel er SREG et register som ikke er bevart på tvers av avbrudd, så de forskjellige flaggene som settes og slettes som et resultat av operasjoner, kan endres hvis et avbrudd oppstår midt i noe. Så det er best hvis du skyver SREG til stabelen i begynnelsen av en avbruddshåndterer og deretter slår den av igjen på slutten av avbryterbehandleren. Jeg har plassert den i koden for å vise hvordan den initialiseres og for å forutse hvordan vi kommer til å trenge den senere, men siden vi ikke bryr oss om hva som skjer med SREG under avbrudd i koden vår, brukte jeg ikke stakken til dette. at jeg har brukt skiftoperasjonen til å sette forskjellige biter i registre ved initialisering. For eksempel i linjen:
ldi temp, (1 <
Kommandoen "<<" i den første linjen med kode ovenfor er en skiftoperasjon. Det tar i hovedsak det binære tallet 1, som er 0b00000001 og flytter det igjen med mengden av tallet ISC01. Dette er posisjonen til biten ISC01 i EICRA -registeret. Siden ISC01 er bit 1, flyttes tallet 1 til venstre 1 -posisjon for å bli 0b00000010. På samme måte er den andre, ISC00, bit 0 av EICRA, og derfor er skiftet til tallet 1 null posisjoner til venstre. Hvis du tar en titt på filen m328Pdef.inc som du lastet ned i den første opplæringen og har brukt evrr siden, vil du se at det bare er en lang liste med ".equ" -uttalelser. Du vil finne at ISC01 er lik 1. Montøren erstatter hver forekomst av den med 1 før den begynner å montere noe. De er bare navn på registerbiter for å hjelpe oss mennesker med å lese og skrive kode. Nå er den vertikale linjen mellom de to skiftoperasjonene ovenfor en logisk "eller" operasjon. Her er ligningen:
0b00000010 | 0b00000001 = 0b00000011
og dette er det vi laster (bruker "ldi") til temp. Grunnen til at folk bruker denne metoden til å laste inn verdier i et register er at den lar en bruke navnet på biten i stedet for bare et tall, og dette gjør at koden er mye lettere å lese. Det er også to andre teknikker vi har brukt. Vi bruker instruksjonene "ori" og "andi". Disse lar oss henholdsvis SET og CLEAR bits uten å endre noen av de andre bitene i et register. For eksempel da jeg brukte
ori temp, (1
denne "eller" s temp med 0b00000001 som setter en 1 i nullbiten og lar resten forbli uendret. Også da vi skrev
andi temp, 0b11111110
dette endrer nullbiten temp til 0 og lar resten forbli uendret.
Oppgave 4: Du bør gå gjennom koden og sørge for at du forstår hver linje. Det kan være interessant å finne bedre metoder for å gjøre ting og skrive et bedre program. Det er hundre måter å kode ting på, og jeg er ganske sikker på at du kan finne en mye bedre måte enn min. Du kan også finne (himmelen forby!) Feil og mangler. I så fall vil jeg gjerne høre om dem slik at de kan fikses.
Ok, nå får vi se om vi kan bli kvitt den overflødige knappen …
Trinn 10: Kode for versjon 2
Den enkleste måten å bli kvitt knappen er bare å fjerne den helt, glemme inngangen til PB2 og bare bytte ADC til "Free Running Mode".
Med andre ord, bare endre ADCSRB -registeret slik at ADTS2, ADTS1 og ADTS0 alle er null.
Sett deretter ADSC -biten i ADCSRA til 1 som starter den første konverteringen.
Last den opp til mikrokontrolleren din, og du vil oppdage at det riktige nummeret vises på displayet mens du trykker på knappen og bare mens du trykker på knappen. Dette er fordi ADC kontinuerlig prøver ADC0 -porten og viser verdien. Når du tar fingeren av knappen, vil "knappestoppet" få noen tilfeldige verdier til å skje veldig raskt, og deretter vil det sette seg tilbake til 0V -inngang. I koden vår har vi denne 0V som vises som 0b11011011 (fordi tastetrykket '0' allerede bruker visningsverdien 0b00000000)
Dette er imidlertid ikke løsningen vi ønsker av to grunner. Først vil vi ikke beholde knappen. Vi vil trykke på den en gang og få nummeret vist (eller brukt i en ny kode i en senere opplæring). For det andre vil vi ikke kontinuerlig prøve ADC0. Vi vil at den skal ta en enkelt avlesning, konvertere den og deretter sove til et nytt tastetrykk utløser en ny konvertering. Gratis løpemodus er best hvis det eneste du vil at mikrokontrolleren skal gjøre, er å kontinuerlig lese noen analoge innganger - som om du ønsket å vise sanntidstemperaturer eller noe.
Så la oss finne enda en løsning …
Trinn 11: Hvordan bli kvitt knappen? Versjon 3
Det er mange måter vi kan fortsette på. Først kunne vi legge til maskinvare for å bli kvitt knappen. For eksempel kan vi prøve å sette en transistor i kretsen ved utgangslinjen til tastetrykket, slik at det ville ta en liten strøm av strømmen fra utgangen og sende en 5V puls til avbryterpinnen PD2.
Imidlertid ville det sannsynligvis være for mye støy i det minste, og i verste fall ville det ikke gi nok tid til en nøyaktig tastetrykkavlesning siden spenningsutgangen til tastaturet ikke ville ha tid til å stabilisere seg før ADC -avlesningen ble registrert.
Så vi vil heller komme med en programvareløsning. Det vi ønsker å gjøre er å legge til et avbrudd på PD2 -pinnen og skrive en avbruddshåndterer for det som kaller en enkelt avlesning av tastaturet. Med andre ord blir vi kvitt autotrigger -avbruddet fra ADC, og legger til et eksternt avbrudd som kaller ADC inne i det. På den måten kommer signalet for å lese ADC etter at PD2 -signalet allerede har oppstått, og dette kan gi ting nok tid til å stabilisere seg til en nøyaktig spenning før PC0 -pinnen blir lest og konvertert. Vi vil fortsatt ha et ADC -fullføringsavbrudd som sender resultatet til analysatorens display på slutten.
Gir mening? Vel, la oss gjøre det …
Ta en titt på den nye koden som er vedlagt.
Du ser følgende endringer:
- Vi la til en rjmp på adressen.org 0x0002 for å håndtere INT0 ekstern avbrudd
- Vi endret EIMSK -registeret for å indikere at vi vil avbryte INT0 -pinnen
- Vi endret ADATE -pinnen i ADCSRA -registeret for å deaktivere autotriggering
- Vi ble kvitt ADCSRB -innstillingene siden de er irrelevante når ADATE er slått av
- Vi trenger ikke lenger å tilbakestille det eksterne triggerflagget siden INT0 -avbruddsrutinen gjør dette automatisk når den er fullført - tidligere hadde vi ikke en avbruddsrutine, vi bare utløste ADC av et signal på den pinnen, så vi måtte fjern det flagget for hånd.
Nå i avbryterbehandleren kaller vi ganske enkelt en enkelt konvertering fra ADC.
Oppgave 5: Kjør denne versjonen og se hva som skjer.
Trinn 12: Kode og video for arbeidsversjonen
Som vi så i den siste versjonen, fungerer ikke knappavbrudd veldig bra fordi avbruddet utløses på en stigende kant for å feste PD2 og deretter ringer avbryterbehandleren til ADC -konverteringen. ADC får imidlertid spenningsavlesningen før den har stabilisert seg, og den leser tull.
Det vi trenger er å innføre en forsinkelse mellom avbruddet på PD2 og ADC -avlesningen på PC0. Vi vil gjøre dette ved å legge til en tidtaker/teller, et telleroverløpsavbrudd og en forsinkelsesrutine. Heldigvis vet vi allerede hvordan vi gjør dette fra opplæring 3! Så vi vil bare kopiere og lime inn den relevante koden derfra.
Jeg har gitt den resulterende koden og en video som viser den i drift.
Du vil legge merke til at avlesningene ikke er så nøyaktige som man skulle håpe. Dette er sannsynligvis på grunn av en rekke kilder:
- vi tapper fra spenningsutgangen til tastaturet for å utløse på PD2 som påvirker lesingen i PC0.
- vi vet egentlig ikke hvor lenge vi skal utsette etter utløseren for å få den beste lesningen.
- det tar noen sykluser før ADC -konverteringen er fullført, noe som betyr at vi ikke kan skyte raskt på tastaturet.
- det er sannsynligvis støy i selve tastaturet.
- etc…
Så selv om vi klarte å få tastaturet til å fungere, og vi nå kunne bruke det i applikasjoner ved å bruke tastetrykkverdiene på en annen måte i stedet for bare å sende dem til analysatorens display, er det ikke veldig nøyaktig og det er veldig irriterende. Det er derfor jeg tror at den beste måten å koble tastaturer er ganske enkelt å stikke hver utgang fra tastaturet inn i en annen port og bestemme hvilken tast som trykkes av hvilke porter som ser en spenning. Det er enkelt, veldig raskt og veldig nøyaktig.
Faktisk er det bare to grunner til at man vil kjøre et tastatur slik vi har gjort her:
- Den bruker bare 2 av pinnene på mikrokontrolleren vår i stedet for 8.
- Det er et flott prosjekt å vise forskjellige aspekter av ADC på mikrokontrolleren som er forskjellig fra standard tingene du kan finne der ute som temperaturavlesninger, dreie potensiometre, etc. Jeg ønsket et eksempel på utløste enkeltavlesninger og ekstern utløsing av ekstern pin. i stedet for bare å kjøre CPU-gobbling-modus.
Uansett, her er et par siste øvelser for deg:
Oppgave 6: Skriv avbryterbehandleren for fullstendig ADC-konvertering på nytt for å bruke en oppslagstabell. Dvs. Slik at den tester den analoge verdien med det første elementet i tabellen, og hvis den er større, returnerer den fra interrupten, hvis den ikke er det, øker den Z til neste element i tabellen og grener tilbake til testen igjen. Dette vil forkorte koden og rydde opp i avbruddsrutinen og få den til å se penere ut. (Jeg vil gi en mulig løsning som neste trinn) Øvelse 7: Koble tastaturet til 8 pinner på mikrokontrolleren og skriv den enkle driveren for det, og opplev hvor mye hyggeligere det er. Kan du tenke på noen få måter å få metoden vår til å fungere bedre?
Det er alt for denne opplæringen. Jeg har lagt ved den endelige versjonen med tips. Når vi nærmer oss vårt endelige mål, vil vi bruke tastaturet igjen i opplæring 9 for å vise hvordan du kan kontrollere syv segmentdisplayer med det (og bygge noe interessant som bruker de ekstra tastene på telefonens tastatur), og så vil vi bytt til å kontrollere ting med knappetrykk i stedet (siden den metoden passer bedre med sluttproduktet vi bygger mot med disse opplæringsprogrammene), og vi vil bare skrinlegge tastaturet.
Ser deg neste gang!
Anbefalt:
AVR Assembler Tutorial 2: 4 Steps
AVR Assembler Tutorial 2: Denne opplæringen er en fortsettelse av " AVR Assembler Tutorial 1 " Hvis du ikke har gått gjennom veiledning 1, bør du stoppe nå og gjøre det først. I denne opplæringen vil vi fortsette vår studie av samlingsspråkprogrammering av atmega328p u
AVR Assembler Opplæring 1: 5 trinn
AVR Assembler Tutorial 1: Jeg har bestemt meg for å skrive en serie opplæringsprogrammer om hvordan du skriver samlingsspråklige programmer for Atmega328p som er mikrokontrolleren som brukes i Arduino. Hvis folk forblir interessert, vil jeg fortsette å legge ut en i uken eller så til jeg går tom for
AVR Assembler Opplæring 6: 3 trinn
AVR Assembler -opplæring 6: Velkommen til opplæring 6! Dagens opplæring blir kort, hvor vi skal utvikle en enkel metode for å kommunisere data mellom en atmega328p og en annen ved å bruke to porter som forbinder dem. Vi tar deretter terningrullen fra opplæring 4 og registeret
AVR Assembler Opplæring 8: 4 trinn
AVR Assembler Tutorial 8: Velkommen til Tutorial 8! I denne korte opplæringen skal vi ta litt avvik fra å introdusere nye aspekter ved montering av språkprogrammering for å vise hvordan vi flytter våre prototypekomponenter til en egen " trykt " kretskort. Den
Tre høyttalerkretser -- Trinn-for-trinn opplæring: 3 trinn
Tre høyttalerkretser || Trinn-for-trinn opplæring: Høyttalerkretsen styrker lydsignalene som mottas fra miljøet til MIC og sender den til høyttaleren der forsterket lyd produseres. Her vil jeg vise deg tre forskjellige måter å lage denne høyttalerkretsen på: