Taula de continguts:
- Pas 1: escanejar un teclat 1
- Pas 2: descarregueu un teclat 2
- Pas 3: descarregueu un teclat 3
- Pas 4: connecteu el teclat
- Pas 5: connecteu el teclat al vostre analitzador
- Pas 6: quins commutadors de commutació hauríem de configurar?
- Pas 7: escriviu el Gestor d'interrupcions
- Pas 8: assigneu els valors de la tecla
- Pas 9: Codi i vídeo per a la versió 1
- Pas 10: Codi de la versió 2
- Pas 11: Com desfer-nos del botó? Versió 3
- Pas 12: Codi i vídeo per a la versió de treball
Vídeo: Tutorial AVR Assembler 7: 12 passos
2024 Autora: John Day | [email protected]. Última modificació: 2024-01-30 08:10
Benvingut al tutorial 7!
Avui mostrarem primer com eliminar un teclat i, a continuació, mostrarem com utilitzar els ports d’entrada analògics per comunicar-nos amb el teclat. Ho farem amb interrupcions i un sol cable com a entrada. Connectarem el teclat de manera que cada premuda enviï un voltatge únic a l’entrada analògica que ens permetrà distingir pel voltatge quina tecla s’ha premut. A continuació, enviarem el número premut al nostre analitzador de registres per demostrar que tot està passant com hauria de fer-ho. Hi ha una sèrie d’esculls en què podeu executar quan feu servir el convertidor analògic a digital (ADC) a l’ATmega328p i així ho farem prendre les coses en algunes etapes en el camí per intentar esbrinar com evitar-les. També veurem per què l’ús del convertidor analògic a digital no és la millor manera de controlar un teclat, tot i que utilitza menys ports al microcontrolador. En aquest tutorial necessitareu:
- un teclat. Podeu comprar-ne un o fer el que jo vaig fer i escanejar-ne un.
- 2 capçaleres femenines per al teclat (si en feu una)
- connexió de cables
- una pissarra
- 4 resistències de 1 Kohm
- 1 resistència de 15 Kohm
- 1 resistència de 3,3 Kohm
- 1 resistència de 180 ohms
- 1 680 ohm de resistència
- un multímetre digital
- el vostre analitzador del tutorial 5
És possible que vulgueu ometre els primers passos si ja teniu un teclat i no en necessiteu cap.
Aquí hi ha un enllaç a la col·lecció completa dels meus tutorials del muntador AVR:
Pas 1: escanejar un teclat 1
Fa molt de temps, quan fins i tot els vostres avis eren simples fills, la gent solia utilitzar aquests dispositius d’aspecte estrany, que tenien cables llargs endollats a la paret, per comunicar-se entre ells. Es deien "telèfons" i normalment eren coses de plàstic barates que feien un so molest quan algú us trucava (no és que els tons de trucada "Justin Bieber" d'avui no siguin igual de molestos). En qualsevol cas, aquests dispositius disposaven de teclats que estaven molt fàcilment connectats i que són fàcils de recuperar i tenen 2 tecles addicionals ("tornar a marcar" i "flaix") dels teclats que podeu comprar que us recomanem com a "tecles de fletxa", "tecles de menú" o una altra cosa. Per tant, començarem descarregant un teclat d'un telèfon antic. Primer agafeu el telèfon (en faig servir un de GE tal com es mostra a les imatges) i separeu-lo per revelar el cablejat. A continuació, agafeu un cisell i traieu els petits poms de plàstic que subjecten el teclat i traieu el teclat.
Pas 2: descarregueu un teclat 2
Ara agafeu una serra de PVC i talleu el plàstic al voltant dels forats de la clau i, a continuació, talleu-lo al voltant de la vora per obtenir la profunditat adequada deixant un teclat prim.
A continuació, torneu a posar el teclat amb les petites clavilles que queden després d’haver-les retallat les tapes en l’últim pas i utilitzeu un soldador per ficar simplement la planxa calenta a cada forat de clavilles que fongui el plàstic i l’estengui per sobre del part inferior del teclat formant nous "comandaments" que mantindran el teclat al seu lloc com abans.
M'agrada escanejar els tres altaveus i potser altres coses com ara interruptors i què-no que hi ha al tauler. Tanmateix, aquesta vegada no vaig a escombrar els canvis i coses perquè ara tenim altres objectius. A més, hi ha un CI lineal TA31002 que hi ha un timbre de telèfon. El full de dades es troba i descarrega fàcilment en línia, donant informació detallada i funcions. Així que vaig a deixar-ho soldat al tauler per ara i després a jugar-hi més tard. M’agradaria connectar-lo a un oscil·loscopi i veure quins senyals tan genials en puc treure. Potser fins i tot fer-ne un timbre. Qui sap.
De totes maneres, un cop hàgiu acabat de destruir el telèfon i escanejar les peces, acabarem de fabricar el nostre teclat.
Pas 3: descarregueu un teclat 3
Utilitzeu una metxa per dessoldar i traieu els cables de cinta de la part inferior del teclat assegurant-vos que els forats de la placa de circuit quedin lliures i, a continuació, poseu dues capçaleres femenines al tauler on hi ha els forats. Probablement haureu de retallar les capçaleres perquè siguin capçaleres de 4 pins.
Ara que les capçaleres estan connectades, podeu connectar-lo a una placa de paret, agafar un multímetre i provar les tecles enganxant el multímetre a través de pins aleatoris i mesurant la resistència. Això us permetrà traçar les claus. És difícil veure com es connecten les tecles a les sortides mirant el circuit, però si utilitzeu un multímetre podeu connectar-lo a dos pins qualsevol i després prémer els botons fins que vegeu un número a la pantalla en lloc d’un circuit obert.. Aquest serà el pinout d'aquesta clau.
Assigneu totes les tecles als pins de sortida d'aquesta manera.
Pas 4: connecteu el teclat
Ara seguiu l'esquema de cablejat i connecteu el teclat a la vostra taula.
Com funcionarà això, posarem 5V a la part esquerra i la dreta es dirigeix a GND. El primer pin de la dreta del diagrama entra al primer dels nostres pins analògics del microcontrolador Atmega328p. Quan no hi ha cap botó premut, el senyal serà 0V i, quan es premen cadascun dels diferents botons, l'entrada al port analògic oscil·larà entre 0V i 5V amb una quantitat diferent en funció de la tecla que s'hagi premut. Vam escollir els valors de la resistència de manera que cada ruta contingués una resistència diferent de la resta. El port analògic del microcontrolador pren un senyal analògic i el divideix en 1024 canals diferents entre 0V i 5V. Això significa que cada canal té una amplada de 5V / 1024 = 0,005 V / canal = 5 mV / canal. Així doncs, el port analògic pot distingir les tensions d’entrada sempre que difereixen en més de 5 mV. En el nostre cas, hem escollit valors de resistència de manera que qualsevol pressió de dues tecles enviarà un senyal de voltatge que difereixi més que aquest, de manera que el microcontrolador hauria de poder decidir fàcilment quina tecla es va prémer. El gran problema és que tot el sistema és molt sorollós, de manera que haurem de triar una gamma de tensions per assignar a cada botó que premeu, però hi entrarem una mica més endavant.
Tingueu en compte que som capaços de controlar un teclat de 14 botons utilitzant només una línia d’entrada única al controlador. Aquest és un dels aspectes útils de les entrades analògiques.
Ara, el nostre primer intent de controlar el teclat serà que premeu una tecla que provoqui una interrupció, la subrutina d’interrupció llegirà el port d’entrada analògica i decidirà quina tecla es va prémer i, a continuació, enviarà aquest número al nostre subrutina de l’analitzador de registres que mostrarà el valor clau en binari en els nostres 8 LED que vam configurar al Tutorial 5.
Pas 5: connecteu el teclat al vostre analitzador
Les imatges mostren com volem connectar el teclat al microcontrolador perquè puguem veure la sortida a la pantalla del nostre analitzador. Bàsicament, simplement connectem la sortida del teclat al pin 0 del PortC, que també es diu ADC0 a l'ATmega328P.
No obstant això, hi ha un parell de coses addicionals. També connectarem un botó a PD2. És a dir, agafeu un cable del vostre carril de 5V a un botó i de l’altre costat del botó a PD2 i, finalment, volem desconnectar el pin AREF del nostre carril de 5V i deixar-lo desconnectat. Podríem inserir un condensador de desacoblament de 0,1 microfarad si ho volguéssim. Es tracta d’un condensador de ceràmica amb un 104 escrit. Els dos primers dígits són el nombre i l’últim dígit és la potència de 10, el multipliquem per obtenir una resposta en picofarads (pico significa 10 ^ -12), de manera que 104 significa 10 x 10 ^ 4 picofarads, que és el mateix que 100 nanofarades (nano significa 10 ^ -9), que és el mateix que 0,1 microfarades (micro significa 10 ^ -6). De tota manera, tot el que fa és establir el pin AREF quan el puguem utilitzar com a pin de referència.
També volem una resistència d’1 Mohm entre PD2 i terra. Establirem PD2 com a pin de sortida a 0V i estarem activant en una vora positiva en aquest pin. Volem que la vora desaparegui immediatament quan deixem anar el botó, de manera que inserirem aquesta resistència de "baixada".
El motiu pel qual volem que el botó sigui perquè volem activar el convertidor analògic-digital des del pin INT0 al xip, que també és PD2. Finalment, ens agradaria que la pressió de tecles activés l'ADC i també proporcionés l'entrada que es convertís sense tenir un botó separat, però a causa de la forma en què funciona el temps, començarem tenint un botó separat per activar l'ADC i una vegada que planxem tot eliminem els errors i estem segurs que tot funciona correctament, llavors abordarem els problemes de soroll i de temps que es produeixen amb l’activació des del mateix botó que volem llegir.
Per tant, per ara, la forma en què funciona és que mantindrem premuda una tecla, després premem el botó per activar l'ADC i, a continuació, deixarem anar i espero que el valor binari del botó que hem pressionat aparegui a l'analitzador.
Escrivim, doncs, un codi que ho aconsegueixi.
Pas 6: quins commutadors de commutació hauríem de configurar?
Primer pensem en com codificarem això perquè el controlador pugui llegir l'entrada del teclat i convertir-la en un valor numèric corresponent al botó que s'ha premut. Utilitzarem el convertidor analògic a digital (ADC) integrat a l'Atmega328p. Utilitzarem AREF com a tensió de referència i la sortida del teclat estarà connectada a PortC0 o PC0. Tingueu en compte que aquest pin també s’anomena ADC0 per al convertidor analògic-digital 0. Pot ser una bona idea que llegiu la secció 12.4 sobre les interrupcions de l’ATmega328P i també el capítol 24 del convertidor analògic-digital abans d’arribar iniciar o, com a mínim, tenir aquestes seccions a punt per fer-ne referència. Per configurar el microcontrolador de manera que sàpiga què fer amb un senyal d’entrada analògica i com interactuar amb el nostre programa, primer hem d’establir alguns dels diversos ADC bits de registre relacionats. Aquests són bàsicament equivalents als antics commutadors alternatius dels primers ordinadors. Feu girar un interruptor ON o OFF, o fins i tot més enrere connectareu els cables entre una presa de sortida i una altra perquè els electrons que arribin a la bifurcació de la carretera trobin una porta tancada i una altra oberta obligant-la a baixar per un camí diferent al laberint de i així realitzar una tasca lògica diferent. Quan codifiquem en llenguatge ensamblador, tenim un accés proper a aquestes funcions del microcontrolador, que és una de les coses més atractives de fer-ho en primer lloc. És més "mans a mà" i passa molt menys "entre bastidors". Per tant, no penseu en establir aquests registres com una tasca tediosa. Això és el que fa que el llenguatge assemblador sigui interessant. Tenim una relació molt personal amb el funcionament intern i la lògica del xip i el fem fer exactament el que volem, ni més ni menys. No hi ha cicles de rellotge perduts. Per tant, aquí teniu una llista dels commutadors que hem d’establir:
- Apagueu el bit ADC de reducció d'energia, PRADC, que és el bit 0 del registre PRR, ja que si aquest bit està activat, s'apagarà l'ADC. El registre de reducció de potència és essencialment una manera d’apagar diverses coses que fan servir l’energia quan no les necessiteu. Com que fem servir l'ADC, volem assegurar-nos que no estigui desactivat d'aquesta manera. (Vegeu PRADC a la pàgina 46)
- Seleccioneu el canal d'entrada analògic que serà ADC0 desactivant MUX3 … 0 al registre ADC Multiplexer Selection (ADMUX) (vegeu la taula 24-4 pàgina 249), ja estan desactivats per defecte, de manera que no cal que ho fem. Tanmateix, ho incloc, ja que si alguna vegada utilitzeu un port diferent de l'ADC0, haureu de canviar aquests commutadors en conseqüència. Diverses combinacions de MUX3, MUX2, MUX1, MUX0 us permeten utilitzar qualsevol dels ports analògics com a entrada i també podeu canviar-los sobre la marxa si voleu veure un munt de senyals analògics diferents alhora.
- Desactiveu els bits REFS0 i REFS1 al registre ADMUX de manera que farem servir AREF com a tensió de referència en lloc de referència interna (vegeu la pàgina 248).
- Activeu el bit ADLAR a ADMUX de manera que el resultat estigui "ajustat a l'esquerra", parlarem d'aquesta elecció al següent pas.
- Configureu el bit ADC0D al registre de desactivació de l'entrada digital (DIDR0) per desactivar l'entrada digital a PC0. Estem utilitzant aquest port per a l'entrada analògica, de manera que és possible que desactivem l'entrada digital per a això.
- Establiu ISC0 i ISC1 al registre de control d’interrupcions externs A (EICRA) per indicar que volem activar a la vora ascendent d’un senyal de tensió al pin INT0 (PD2), vegeu la pàgina 71.
- Esborreu els bits INT0 i INT1 al registre de màscares d’interrupció externa (EIMSK) per indicar que no utilitzem interrupcions en aquest pin. Si haguéssim d’habilitar les interrupcions en aquest pin, necessitaríem un controlador d’interrupcions a l’adreça 0x0002, però en lloc d’això el configurem de manera que un senyal d’aquest pin activi la conversió ADC, la finalització de la qual s’encarrega de la interrupció completa de la conversió ADC a adreça 0x002A. Vegeu la pàgina 72.
- Definiu el bit ADEN Enable (ADEN) (bit 7) al control ADC i al registre d'estat A (ADCSRA) per habilitar l'ADC. Vegeu la pàgina 249.
- Podríem iniciar una sola conversió configurant el bit de conversió d’inici ADC (ADSC) cada vegada que volguéssim llegir el senyal analògic, però, ara preferim que es llegeixi automàticament cada vegada que algú prem el botó, de manera que activarem l’ADC El bit Habilita el desencadenament automàtic (ADATE) al registre ADCSRA perquè l'activació es faci automàticament.
- També establim els bits ADPS2..0 (els bits AD Prescalar) a 111 perquè el rellotge ADC sigui el rellotge de la CPU dividit per un factor de 128.
- Seleccionarem la font del desencadenant ADC per ser PD2, que també s’anomena INT0 (External Interrupt Request 0). Ho fem canviant els diversos bits al registre ADCSRB (vegeu la taula 24-6 a la pàgina 251). Veiem a la taula que volem que ADTS0 estigui desactivat, ADTS1 activat i ADTS2 desactivat de manera que l’ADC s’activi des d’aquest pin. Tingueu en compte si volíem provar contínuament el port analògic com si estiguéssim llegint un senyal analògic continu (com ara un mostreig de so o alguna cosa així), el configuraríem en mode de funcionament lliure. El mètode que fem servir per configurar el desencadenament a PD2 provoca una lectura ADC del port analògic PC0 sense provocar cap interrupció. La interrupció arribarà quan la conversió estigui completa.
- Habiliteu el bit ADC Interrupt Enable (ADIE) al registre ADCSRA perquè, quan es completi la conversió analògica a digital, generi una interrupció per a la qual puguem escriure un controlador d'interrupcions i posar-la a.org 0x002A.
- Establiu el bit I a SREG per habilitar les interrupcions.
Exercici 1: assegureu-vos de llegir les seccions rellevants del full de dades per a cadascuna de les opcions anteriors, de manera que entengueu què passa i què passaria si les canviéssim a paràmetres alternatius.
Pas 7: escriviu el Gestor d'interrupcions
En l'últim pas, vam veure que l'hem configurat de manera que una vora ascendent detectada a PD2 activi una conversió analògica a digital a PC0 i, quan aquesta conversió es completi, llançarà una interrupció de conversió completa de l'ADC. Ara volem fer alguna cosa amb aquesta interrupció. Si examineu la taula 12-6 a la pàgina 65, veureu una llista de les possibles interrupcions. Ja hem vist la interrupció RESET a l'adreça 0x0000 i la interrupció Timer / Counter0 Overflow a l'adreça 0x0020 en tutorials anteriors. Ara volem veure la interrupció ADC que veiem a la taula a l'adreça 0x002A. Així doncs, al principi del nostre codi de llenguatge ensamblador necessitarem una línia que digui:
.org 0x002Arjmp ADC_int
que passarà al nostre gestor d'interrupcions anomenat ADC_int sempre que l'ADC hagi completat una conversió. Llavors, com hem d’escriure el nostre gestor d’interrupcions? La manera com funciona l’ADC és mitjançant el següent càlcul:
ADC = Vin x 1024 / Vref
Així que anem a veure què passa si premo el botó "tornar a marcar" del teclat. En aquest cas, la tensió a PC0 canviarà fins a un cert valor, per exemple, 1,52 V, i com que Vref és a 5 V tindrem:
ADC = (1,52 V) x 1024/5 V = 311.296
i, per tant, es mostraria com un 311. Si volguéssim convertir-lo en un voltatge, només invertiríem el càlcul. No haurem de fer-ho però, ja que no ens interessen les tensions reals només per distingir-les. Quan s'hagi acabat la conversió, el resultat s'emmagatzema en un número de 10 bits col·locat als registres ADCH i ADCL i hem provocat que estigui "ajustat a l'esquerra", cosa que significa que els 10 bits comencen al bit 7 d'ADCH i baixen a bit 6 d'ADCL (hi ha 16 bits en total en aquests dos registres i només en fem servir 10, és a dir, 1024 canals). Podríem tenir el resultat "ajustat a la dreta" si volguéssim esborrant el bit ADLAR al registre ADMUX. La raó per la qual escollim ajustat a l'esquerra és perquè els nostres senyals estan prou separats perquè els dos darrers dígits del número de canal no siguin rellevants i probablement només siguin sorolls, de manera que distingirem les pulsacions de tecles utilitzant només els vuit dígits superiors, és a dir, només haurem de mirar ADCH per esbrinar quin botó es va prémer. registreu-vos, convertiu aquest número en un valor del teclat i, a continuació, envieu-lo als LEDs de l'analitzador de registre perquè puguem verificar que si premeu un "9", s'encendran els LED corresponents a "00001001". Abans d'anar encara que primer hem de veure què es mostra a ADCH quan premem els diversos botons. Escrivim, doncs, un senzill gestor d’interrupcions que només envia el contingut d’ADCH a la pantalla de l’analitzador. Per tant, això és el que necessitem:
ADC_int: lds analyzer, ADCH; carregueu el valor d’ADCH als nostres analitzadorsbi EIFR, 0; esborreu el senyal d'interrupció extern perquè estigui a punt per tornar a anar
A hores d'ara, només hauríeu de poder copiar el codi del nostre analitzador al tutorial 5 i afegir aquesta interrupció i la configuració de commutació i executar-la. Exercici 2: escriviu el codi i executeu-lo. Comproveu que obteniu la visualització ADCH a la pantalla de l'analitzador. Proveu de prémer la mateixa pressió diverses vegades. Sempre obteniu el mateix valor a ADCH?
Pas 8: assigneu els valors de la tecla
El que hem de fer ara és convertir els valors de l'ADCH en números corresponents a la tecla que s'ha premut. Ho fem escrivint el contingut d’ADCH per a cada pulsació de tecla i després convertint-lo en un nombre decimal com ho vaig fer a la imatge. A la nostra rutina de manipulació d’interrupcions, considerarem tot un ventall de valors que corresponen a cada pulsació de tecla de manera que l’ADC assignarà qualsevol cosa d’aquest interval a una pulsació de tecla determinada.
Exercici 3: feu aquest mapatge i torneu a escriure la vostra rutina d'interrupcions ADC.
Això és el que he obtingut per al meu (és probable que el vostre sigui diferent). Tingueu en compte que l’he configurat amb un interval de valors per a cada pressió de tecla.
ADC_int:; Analitzador handlerclr d'interrupció externa; prepareu-vos per al nou número de botó H, ADCH; Actualitzacions ADC quan es llegeix ADCH clccpi buttonH, 240brlo PC + 3; si ADCH és més gran, és un analitzador 1ldi, 1; analitzador de càrrega amb retorn 1rjmp; i torna el botó clccpi H, 230; si ADCH és més gran que un analitzador 2brlo PC + 3ldi, 2rjmp return clccpi buttonH, 217brlo PC + 3ldi analyzer, 3rjmp return clccpi buttonH, 203brlo PC + 3ldi analyzer, 4rjmp return clccpi buttonH, 187brlo PC + 3ldi analyzer, 5rjmp return clccpi buttonH, 155brlo PC + 3ldi analitzador, 6rjmp retorn clccpi botó H, 127brlo PC + 3ldi analitzador, 255; configurarem el flaix com a botó clccpi de retorn onrjmpH, analitzador PC 115brlo + 3ldi, botó clccpi retorn 7rjmp, analitzador PC 94brlo + analitzador 3ldi, botó clccpi retorn 8rjmpH, analitzador PCbr3ldi de 32brlo, 9rjmp botó clccpi de tornadaH, analitzador PC 37brlo + 3ldi, 0b11110000; asterisc és la meitat superior onrjmp return clccpi buttonH, 28brlo PC + 3ldi analyzer, 0rjmp return clccpi buttonH, 17brlo PC + 3ldi analyzer, 0b00001111; el signe hash és la meitat inferior onrjmp return clccpi buttonH, 5brlo PC + 3ldi analyzer, 0b11000011; tornar a marcar és superior 2 inferior 2rjmp retorn ldi analitzador, 0b11011011; en cas contrari, s'ha produït un error return: reti
Pas 9: Codi i vídeo per a la versió 1
He adjuntat el meu codi per a aquesta primera versió del controlador del teclat. En aquest, cal prémer la tecla i després prémer el botó per tal de fer que l'ADC llegeixi l'entrada del teclat. El que preferiríem és que no hi hagi cap botó, sinó que el senyal per fer la conversió prové de la pròpia tecla. Exercici 3: Muntar i penjar aquest codi i provar-lo. És possible que hagueu de canviar els diversos llindars de conversió perquè corresponguin als voltatges de pressió de tecles, ja que probablement difereixen dels meus. Què passa si proveu d’utilitzar una entrada del teclat tant per a l’ADC0 com per al pin d’interrupció extern en lloc de fer-ho mitjançant un botó? També adjuntaré un vídeo del funcionament d’aquesta primera versió del nostre controlador de pressió de tecles. al meu codi hi ha una secció inicialitzant el Stack Pointer. Hi ha diversos registres que és possible que vulguem empènyer i sortir de la pila quan manipulem variables i què no, i també hi ha registres que és possible que vulguem desar i restaurar més endavant. Per exemple, SREG és un registre que no es conserva a través de les interrupcions, de manera que els diversos indicadors que es defineixen i esborren com a resultat de les operacions es poden canviar si es produeix una interrupció enmig d'alguna cosa. Per tant, és millor si premeu SREG a la pila al principi d’un controlador d’interrupcions i, després, torneu a desactivar-lo al final del controlador d’interrupcions. L’he col·locat al codi per mostrar com s’inicialitza i anticipar-nos a com ho necessitarem més endavant, però com que ens importa el que passi a SREG durant les interrupcions del nostre codi, no he utilitzat la pila per a això. que he utilitzat l'operació de desplaçament per configurar diversos bits en registres en inicialitzar. Per exemple, a la línia:
ldi temp, (1 <
L'ordre "<<" de la primera línia de codi anterior és una operació de desplaçament. Bàsicament pren el número binari 1, que és 0b00000001 i el canvia per la quantitat del número ISC01. Aquesta és la posició del bit anomenat ISC01 al registre EICRA. Com que ISC01 és el bit 1, el número 1 es desplaça cap a la posició 1 esquerra per convertir-se en 0b00000010. De manera similar, el segon, ISC00, és el bit 0 d'EICRA i, per tant, el desplaçament del número 1 és zero posicions cap a l'esquerra. Si mireu, mireu de nou el fitxer m328Pdef.inc que heu descarregat al primer tutorial i que heu utilitzat evrr des de llavors, veureu que només és una llarga llista d’instruccions ".equ". Trobareu que ISC01 és igual a 1. El muntador reemplaça cada instància per 1 abans de començar a muntar res. Només són noms de bits de registre per ajudar-nos als humans a llegir i escriure codi. Ara, la línia vertical entre les dues operacions de desplaçament anteriors és una operació lògica "o". Aquí teniu l’equació:
0b00000010 | 0b00000001 = 0b00000011
i això és el que estem carregant (utilitzant "ldi") a temp. La raó per la qual la gent utilitza aquest mètode per carregar valors en un registre és que permet utilitzar el nom del bit en lloc de només un número i això fa que el codi sigui molt més fàcil de llegir. També hi ha altres dues tècniques que hem utilitzat. Utilitzem les instruccions "ori" i "andi". Aquests ens permeten SET i CLEAR bits respectivament sense canviar cap dels altres bits en un registre. Per exemple, quan feia servir
ori temp, (1
aquesta temperatura "o" s amb 0b00000001 que posa un 1 al bit zero i deixa la resta sense canvis. També quan vam escriure
andi temp, 0b11111110
això canvia el bit de temperatura zero a 0 i deixa la resta sense canvis.
Exercici 4: heu de revisar el codi i assegurar-vos que enteneu cada línia. Pot ser que us interessi trobar millors mètodes per fer coses i escriure un programa millor. Hi ha cent maneres de codificar les coses i estic bastant segur que podeu trobar una manera molt millor que la meva. També podeu trobar (ompliu el cel!) Errors i omissions. En aquest cas, segur que voldria saber-ne per solucionar-los.
D’acord, ara a veure si podem desfer-nos d’aquest botó superflu …
Pas 10: Codi de la versió 2
La forma més senzilla d’eliminar el botó és eliminar-lo completament, oblidar l’entrada de PB2 i canviar l’ADC al “mode d’execució lliure”.
En altres paraules, simplement canvieu el registre ADCSRB de manera que ADTS2, ADTS1 i ADTS0 siguin zero.
A continuació, configureu el bit ADSC a ADCSRA a 1, que iniciarà la primera conversió.
Ara pengeu-lo al microcontrolador i veureu que apareix el número correcte a la pantalla mentre premeu el botó i només mentre premeu el botó. Això es deu al fet que l'ADC mostra contínuament el port ADC0 i mostra el valor. Quan traieu el dit del botó, el "botó de botó" farà que es produeixin uns quants valors aleatoris molt ràpidament i es tornarà a establir a 0V d'entrada. Al nostre codi tenim aquest 0V que apareix com a 0b11011011 (perquè la tecla "0" ja utilitza el valor de visualització 0b00000000)
Aquesta no és la solució que volem per dos motius. En primer lloc, no volem haver de prémer el botó. Volem prémer-lo una vegada i mostrar el número (o utilitzar-lo en algun codi nou en un tutorial posterior). En segon lloc, no volem provar contínuament l’ADC0. Volem que faci una sola lectura, la converteixi i, a continuació, dormi fins que una nova pulsació de tecla desencadeni una nova conversió. El mode d’execució lliure és millor si l’únic que voleu que faci el microcontrolador és llegir contínuament algunes entrades analògiques, com si voleu mostrar temperatures en temps real o alguna cosa així.
Així que anem a trobar una altra solució …
Pas 11: Com desfer-nos del botó? Versió 3
Hi ha moltes maneres de procedir. Primer podríem afegir maquinari per desfer-nos del botó. Per exemple, podem provar de posar un transistor al circuit a la línia de sortida de la tecla perquè agafi un petit fil de corrent de la sortida i enviï un pols de 5 V al pin d'interrupció PD2.
No obstant això, probablement seria massa sorollós i, en el pitjor dels casos, no permetria prou temps per a una lectura precisa de la tecla, ja que la tensió de sortida del teclat no tindria temps d’estabilitzar-se abans de capturar la lectura de l’ADC.
Per tant, preferiríem trobar una solució de programari. El que ens agradaria fer és afegir una interrupció al pin PD2 i escriure-hi un controlador d’interrupcions que cridi una sola lectura del pin del teclat. Dit d’una altra manera, desferem l’interrupció de desencadenament automàtic de l’ADC i afegirem una interrupció externa que crida l’ADC al seu interior. D'aquesta manera, el senyal per llegir l'ADC apareix després que el senyal PD2 ja s'ha produït i això pot donar temps a les coses per establir-se a una tensió precisa abans que es llegeixi i es converteixi el pin PC0. Encara tindríem una interrupció de finalització de l’ADC que al final mostra el resultat a la pantalla de l’analitzador.
Té sentit? Doncs fem-ho …
Mireu el nou codi adjunt.
Veureu els canvis següents:
- Hem afegit un rjmp a l'adreça.org 0x0002 per gestionar la interrupció externa INT0
- Hem canviat el registre EIMSK per indicar que volem interrompre al pin INT0
- Hem canviat el pin ADATE al registre ADCSRA per desactivar el desencadenament automàtic
- Ens vam desfer de la configuració de l'ADCSRB, ja que són irrellevants quan ADATE està desactivat
- Ja no hem de restablir el senyalador d’activació extern, ja que la rutina d’interrupció INT0 ho fa automàticament quan es completa: anteriorment no teníem una rutina d’interrupció, només activàvem l’ADC d’un senyal en aquest pin, així que vam haver de esborreu aquesta bandera a mà.
Ara, al gestor d’interrupcions, simplement anomenem una sola conversió des de l’ADC.
Exercici 5: executeu aquesta versió i vegeu què passa.
Pas 12: Codi i vídeo per a la versió de treball
Com hem vist a l'última versió, la interrupció del botó no funciona molt bé perquè la interrupció s'activa en una vora ascendent fins al pin PD2 i el gestor d'interrupcions crida la conversió ADC. Tanmateix, l’ADC obté la lectura del voltatge abans que s’estabilitzi i, per tant, llegeix tonteries.
El que necessitem és introduir un retard entre la interrupció a PD2 i la lectura ADC a PC0. Ho farem afegint un temporitzador / comptador, una interrupció de desbordament de comptador i una rutina de retard. Per sort, ja sabem com fer-ho des del tutorial 3. Així doncs, només copiarem i enganxarem el codi corresponent.
He donat el codi resultant i un vídeo que el mostra en funcionament.
Notareu que les lectures no són tan exactes com hom esperaria. Això és probable a causa de diverses fonts:
- estem tocant des de la sortida de tensió del teclat per activar el PD2, que afecta la lectura del PC0.
- realment no sabem quant de temps s’ha de retardar després del disparador per obtenir la millor lectura.
- la conversió ADC triga uns quants cicles, cosa que significa que no podem disparar ràpidament al teclat.
- probablement hi ha soroll al teclat mateix.
- etc …
Per tant, tot i que hem aconseguit que el teclat funcioni i ara el podríem fer servir en aplicacions fent servir els valors de premuda de tecla d’una altra manera en lloc de publicar-los a la pantalla de l’analitzador, no és molt precís i és molt molest. És per això que crec que la millor manera de connectar teclats és simplement enganxar cada sortida del teclat a un port diferent i decidir quina tecla es prem mitjançant quins ports veuen un voltatge. Això és fàcil, molt ràpid i molt precís.
De fet, només hi ha dues raons per les quals es vol conduir un teclat com hem fet aquí:
- Només utilitza 2 dels pins del nostre microcontrolador en lloc de 8.
- És un gran projecte per mostrar diferents aspectes de l'ADC al microcontrolador, que és diferent de les coses estàndard que podeu trobar allà, com ara lectures de temperatura, potenciòmetres de gir, etc. en lloc d’executar de manera gratuïta el mode d’englossament de la CPU.
De totes maneres, aquí teniu un parell d’exercicis finals:
Exercici 6: Torneu a escriure el controlador d'interrupcions complet de conversió ADC per utilitzar una taula de cerca. És a dir, De manera que prova el valor analògic amb el primer element de la taula i, si és més gran, torna de la interrupció; si no és així, incrementa Z al següent element de la taula i torna a tornar a la prova. Això reduirà el codi i netejarà la rutina d’interrupcions i farà que sembli més agradable. (Donaré una possible solució com a pas següent) Exercici 7: Connecteu el teclat a 8 pins del microcontrolador i escriviu-hi el controlador senzill i experimenteu el millor que és. Se us acudeixen algunes maneres de fer que el nostre mètode funcioni millor?
Això és tot per a aquest tutorial. He adjuntat la versió final amb indicadors. A mesura que ens apropem al nostre objectiu final, tornarem a utilitzar el teclat al Tutorial 9 per mostrar com controlar les pantalles de set segments amb ell (i construir alguna cosa interessant que faci servir les tecles addicionals del teclat del telèfon) i, a continuació, ho farem canvieu a controlar les coses fent clic amb els botons (ja que aquest mètode s'adapta millor al producte final que estem construint amb aquests tutorials) i només deixarem el teclat.
Ens veiem a la propera!
Recomanat:
Tutorial AVR Assembler 2: 4 passos
AVR Assembler Tutorial 2: aquest tutorial és una continuació del " AVR Assembler Tutorial 1 " Si no heu passat pel tutorial 1, hauríeu d'aturar-vos ara i fer-ho primer. En aquest tutorial continuarem el nostre estudi de la programació del llenguatge assemblador de l'atmega328p u
Tutorial AVR Assembler 1: 5 passos
AVR Assembler Tutorial 1: He decidit escriure una sèrie de tutorials sobre com escriure programes de llenguatge ensamblador per a l'Atmega328p, que és el microcontrolador utilitzat a l'Arduino. Si la gent continua interessada, continuaré sortint una a la setmana aproximadament fins que em quedi sense
Tutorial AVR Assembler 6: 3 passos
AVR Assembler Tutorial 6: Benvingut al Tutorial 6. El tutorial d'avui serà breu, on desenvoluparem un mètode senzill per comunicar dades entre un atmega328p i un altre mitjançant dos ports que els connecten. Després agafarem el rodet de daus del tutorial 4 i el registre
Tutorial AVR Assembler 8: 4 passos
AVR Assembler Tutorial 8: Benvingut al Tutorial 8. En aquest breu tutorial farem una mica de diversió en introduir nous aspectes de la programació del llenguatge ensamblador per mostrar com moure els nostres components de prototipatge a un "imprès" separat. targeta de circuits. El
Tutorial AVR Assembler 9: 7 passos
AVR Assembler Tutorial 9: Benvingut al Tutorial 9. Avui mostrarem com controlar tant una pantalla de 7 segments com una pantalla de 4 dígits mitjançant el nostre codi de llenguatge de muntatge ATmega328P i AVR. Al llarg de fer això, haurem de desviar-nos de com utilitzar la pila