Matrična tastatura sa osam tastera. Povezivanje matrične tastature sa AVR mikrokontrolerima

10.09.2021

Vrijeme je da vam kažemo kako organizirati istraživanje takve tastature. Da vas podsjetim da se tastatura sastoji od redova koji vise na portovima i kolona koje skenira drugi port. Kod je napisan za kontroler ATMega8535, ali zbog činjenice da je tamo sve specificirano u obliku makroa, može se brzo prenijeti na bilo koji drugi kontroler klase Mega, kao i za najmodernije Tiny. Iako u slučaju Tiny Može doći do nekih grešaka zbog njihovog nepotpunog skupa naredbi. Morat ćete ga malo podesiti pomoću datoteke.

Ukratko, bliže kodu. Odmah da rezervišem da sam usvojio način da jedan projekat podelim na desetak malih fajlova, a zatim ih povežem po potrebi. Prvo, ovo oštro strukturira kod, što olakšava navigaciju, a drugo, kod postaje modularan i njegovi dijelovi se mogu koristiti kao gotove biblioteke u drugim programima. Samo ga malo podesi. Iz istog razloga sve definicije pravim putem makronaredbi, tako da ne moram uređivati ​​cijeli kod, već samo trebam promijeniti par redaka u konfiguracijskoj datoteci.

Sada ukratko o fajlovima:
keyboard_define.inc— konfiguracioni fajl tastature.
Ova datoteka pohranjuje sve makro definicije koje koristi tastatura. Ovdje postavljamo koji pinovi mikrokontrolera su povezani na koju liniju. Jedna suptilnost - izlazi u stupce ( port za skeniranje) mora biti sekvencijalni skup linija jednog porta. To su, na primjer, noge 0,1,2,3 ili 4,5,6,7 , ili 3,4,5,6 . Nije bitno koji port, glavna stvar je da je konzistentan.
Mislim da neće biti problema sa identifikacijom nogu, ali u vezi sa parametrom KEYMASKŽelim da ti kažem nešto posebno.
Ovo je maska ​​po kojoj će se skenirani port identificirati. Trebalo bi da sadrži 6 jedinica i jednu 0. Nula je postavljena na krajnju desnu poziciju porta za skeniranje.

primjer:
Moj port za skeniranje visi na bitovima 7,6,5,4, krajnji desni bit porta za skeniranje je bit 4, stoga je maska ​​0b11101111 - nula je na 4. poziciji. Ako linije za skeniranje vise na nogama 5,4,3,2, tada će maska ​​već biti 0b11111011 - nula na drugoj poziciji. Zašto sve ovo biće objašnjeno u nastavku.

Tu je i maska ​​aktivnih linija porta za skeniranje - SCANMSK. U njemu jedinice stoje samo nasuprot linijama kolona. Moje kolone su postavljene na najznačajniju tetradu porta, tako da maska ​​za skeniranje izgleda tako 0b11110000.

U odeljku za inicijalizaciju, morate zapamtiti da konfigurišete noge porta za skeniranje za izlaz, a noge čitača za unos sa povlačenjem. A zatim umetnite šifru za rukovanje tastaturom negde u obliku obične potprograma. Lako se koristi - pozivamo potprogram za čitanje sa tastature, a kada se vratimo, imamo skenirani kod ključa u registru R16.

Ovako je izgledao moj test kod:

Glavni: SEI ; Omogući prekide.

RCALL KeyScan ; Skeniranje tastature
CPI R16.0; Ako se vrati 0, to znači da nije bilo pritiskanja
BREQ Main ; U ovom slučaju idite na početak
RCALL CodeGen ; Ako se skenirani kod vrati, prenosimo ga na
; ASCII kod.

MOV R17,R16 ; Učitavanje u prijemni registar LCD rukovaoca
RCALL DATA_WR ; Prikazujemo ga na displeju.

RJMP Main ; Hajde da sve popravimo.

O LCD prikaz, neću još ništa reći, jer procedure još nisu finalizirane, ali će biti raspoređene i raspravljene u bliskoj budućnosti.

Sada ću vam reći kako to funkcionira KeyScan procedura

Def COUNT = R18
KeyScan: LDI COUNT,4 ; Skenirajmo 4 kolone
LDI R16, KEYMASK ; Učitajte masku na skeniranje kolone 0.

Prvo pripremamo masku za skeniranje. Poenta je u tome da ne možemo uzeti podatke i poslati ih na port ovako. Uostalom, linije vise samo na posljednja četiri bita, a na prvom može biti bilo što, tako da nam je glavna stvar da ni pod kojim okolnostima ne mijenjamo stanje bitova tetrade nižeg reda porta.

KeyLoop: IN R17,COL_PORT ; Prethodnu vrijednost preuzimamo iz porta
ORI R17,SCANMSK ; Postavljamo bitove skeniranog dijela na 1.


U početku učitavanje podataka iz port registra da imate pri ruci početnu konfiguraciju porta. Također moramo postaviti sve bitove skeniranja porta na 1, to se radi kroz operaciju ILI maskom za skeniranje. U dijelu gdje su stajale jedinice nakon operacije ILI po maski 11110000 (moje značenje SCANMASK) svi bitovi će postati jedinice, a tamo gdje je bila nula će ostati nepromijenjena.

I R17,R16 ; Resetiranje bita skenirane kolone
IZLAZNI COL_PORT,R17 ; Izbacujemo generirani bajt iz porta.


Sada superponiramo generirani bajt maska ​​aktivne kolone. U početku ima nulu na prvoj poziciji, a sve ostale su jedinice. Kao rezultat toga, ostale vrijednosti porta se neće promijeniti, ali će se u prvom stupcu pojaviti 0, a zatim će se maska ​​pomaknuti i cijela operacija će se ponoviti. Kao rezultat, nula će već biti u sljedećoj koloni i tako dalje. Tako organiziramo „pokrenutu“ nulu u portu za skeniranje, dok ostali, strani bitovi porta ostaju nepromijenjeni. Zatim se generirani broj učitava u registar portova i noge prihvataju odgovarajuće nivoe napona.

NOP ; Kašnjenje za promjenu nogu.
NOP
NOP
NOP

SBIS ROW0_PIN,ROW0 ; Provjera koja je linija pritisnuta
RJMP bt0

SBIS ROW1_PIN,ROW1
RJMP bt1

SBIS ROW2_PIN,ROW2
RJMP bt2

SBIS ROW3_PIN,ROW3
RJMP bt3


Serije NOP je neophodno kako bi noga imala vremena da dostigne željeni nivo prije provjere. Činjenica je da pravi krug ima određenu vrijednost kapacitivnosti i induktivnosti, što čini nemoguće je trenutno promijeniti nivo, još uvijek postoji malo kašnjenje. A pri brzinama od 8 MHz i više, procesor klikće komande takvom brzinom da se napetost u nozi još nije spustila, a mi već provjeravamo stanje izlaza. Tako da sam ubacio nekoliko praznih operacija. Na 8 MHz sve radi dobro. On viša frekvencija, vjerovatno će biti potrebno instalirati još pet ili šest NOP ili staviti u jednostavnu petlju. Međutim, ovdje morate pogledati šta će biti ekonomičniji bajt bajt.
Nakon petlji slijede četiri provjere po liniji. I prijelaz na odgovarajuću obradu događaja.

ROL R16 ; Pomicanje maske za skeniranje
DEC COUNT ; Smanjenje brojača kolona
BRNE KeyLoop ; Ako još nismo prošli kroz sve, uradite još jednu iteraciju

CLR R16; Ako nije bilo klikova, vraćamo 0
RET
.undef COUNT

Ovo je mjesto gdje se maska ​​pomiče ulijevo pomoću komande cikličkog pomaka. ROL. Nakon toga smanjujemo brojač iteracija (u početku jednak četiri, pošto imamo četiri kolone). Ako nije bilo klikova, onda na kraju sve četiri iteracije ispadamo iz petlje i resetujemo registar R16 i mi se vraćamo.


bt0: ANDI R16,SCANMSK ; Generiranje koda za skeniranje
ORI R16.0x01; Vraćamo ga u registar 16
RET

A evo jednog od mogućih krajeva kada se pritisne. Ovdje se generiše kod za skeniranje koji će biti vraćen u registar R16. Odlučio sam da se ne trudim, već kao i uvijek, uguram desetak bajtova i učinim što brže i kraće. Dakle, šta imamo kada dođemo do ovog dijela koda. I imamo jednu od opcija porta za skeniranje ( 1110,1101,1011,0111 ), a znamo i broj reda po kojem smo došli ovdje. Ovom konkretnom komadu se može doći samo iz prvog reda koristeći naredbu RJMP bt0.
Dakle, napravimo kod za skeniranje od kombinacije skeniranja i broja reda! Ne pre rečeno nego učinjeno! Prvo, moramo izdvojiti kombinaciju skeniranja iz vrijednosti porta - ona je pohranjena u registru R16, tako da nema potrebe da ga birate iz porta. Proguramo operaciju I vrijednost R16 kroz SCANMASK i sve što je bilo ispod jedinica prošlo je bez promjena, a gdje su bile nule, resetirano je na nulu. Ups, i imamo prikazan komad za skeniranje - najznačajniji grickanje. Sada zalijepimo broj reda tamo - sa operacijom ILI. Jednom smo dobili konstrukciju kao [scan][line]
Tako da to ostavljamo u registru R16, a mi sami odlazimo! Isto je i sa ostalim linijama. Pogledajte izvor, neću ih duplirati ovdje.

Dekodiranje skeniranog koda.
Odlično, postoji kod za skeniranje, ali šta s njim? Ne možete ga nigdje zalijepiti. Znamo da je ovo sranje 01110001 ovo je jedan kod, ali neki LCD ekran ili standardni terminal će nam se jezivo našaliti i reći nam sve što ona misli o našem sistemu notacije - vidite ASCII daj. U redu, to će biti ASCII.

šta da radim? Prođite kroz cijelu strukturu CASE gdje dodijeliti kod za svako skeniranje ASCII Pritišće me žaba - ima toliko provjera koje treba uraditi! Koliko će bajtova biti potrebno za sve ove gluposti? A naša memorija nije gumena, oskudnih osam kilobajta, i dva bajta po komandi, ovo je u najboljem slučaju. Mogao bih sve ovo da uradim direktno u rukovaocu tastature. NE!!! U VATRU!!! Ići ćemo svojim putem.
Ok, šta imamo na zalihama? Metoda prijelazne tablice ne radi zbog strašnog poremećaja kodova za skeniranje. Počešao sam bundevu, preturao po stanu... i onda mi je sinulo. Naravno!!! Brute force!!!

Brute force scan code.
Dakle, imamo užasno neprobavljiv kod za skeniranje, kao i vitak sto ASCII karaktera. Kako ukrstiti zmiju sa ježem? To je jednostavno! Postavimo u memoriju tabelu simbola u vezi [skani kod]:, a zatim ćemo pokrenuti svaki traženi kod za skeniranje kroz ovu tablicu i, ako postoji podudaranje, zamijeniti traženi kod u izlazu ASCII iz snopa. Klasičan primjer programiranja - izgubljen u vremenu, ali dobijen u pamćenju.

Ovako to izgleda:

CodeGen:LDI ZH,High(Code_Table*2) ; Učitana adresa tablice kodova
LDI ZL, Niska (Tablica_koda*2) ; Visoki i niski bajtovi

Ovdje smo učitali adresu naše tablice u registar indeksa. Množenjem sa dva tako da adresa bude u bajtovima, jer U okruženju kompajlera, kodni prostor se adresira riječima.

Brute: LPM R17,Z+ ; Uzeo sam prvi znak iz tabele - skenirani kod

CPI R17.0xFF ; Ako je kraj tabele
BREQ CG_Exit ; Onda izlazimo

CPI R16.0; ako je nula,
BREQ CG_Exit ; onda izlazimo

CP R16,R17 ; Uporedio sam ga sa kodom za skeniranje ključa.
BREQ Equal ; Ako je jednak, onda idemo na zamjenu ascii koda

Učitajte prvi kod za skeniranje iz tabele i upišite ga u registar R17, istovremeno povećavajući adresu u registru Z(odabirom sljedeće ćelije tablice) i prije svega je usporedite sa FF je kod za kraj tabele. Ako je sto gotov, onda idemo odavde. Ako nismo sortirali cijelu tabelu, tada počinjemo porediti ulaznu vrijednost (u registru R16) prvo sa nulom (bez pritiskanja), ako se izlazi i iz nule. I sa kodom za skeniranje sa stola. Ako se skeniranje tablice podudara sa skeniranjem ulaza, idite na Jednako.

LPM R17,Z+ ; Povećajte Z za 1
RJMP Brute; Ponovite ciklus

A ako se ništa ne pronađe, ponovo pozivamo komandu LPM R17,Z+ samo da se ona poveća Z po jedan - treba da pređemo ASCII kod i uzmite sljedeći kod za skeniranje iz tabele. Samo INC Z neće raditi jer Z ovdje dvobajt. ZL i ZH. U nekim slučajevima to je dovoljno INC ZL, ali to je slučaj kada smo potpuno sigurni da je adresa blizu početka i da se niži bajt neće preliti (u suprotnom, umjesto adrese 00000001:00000000, jednostavno ćemo dobiti 00000000:0000000, što je suštinski pogrešno) , i naredbu LPMće učiniti sve za nas, pa smo ovdje sačuvali još par bajtova. Onda ćemo se vratiti na početak ciklusa, i tamo će opet biti LPM koji će preuzeti sljedeći kod za skeniranje.

Jednako: LPM R16,Z ; Učitavanje ASCII koda iz memorije.
RET ; Hajdemo nazad

Ako je bilo slučajnosti, onda kao rezultat LPM Z+ ovdje Z pokazuje na sljedeću ćeliju - sa ASCII kod. Učitavamo ga u registar R16 i izađi napolje.

CG_Exit: CLR R16 ; Reset 0 = povratak 0
RET ; Hajdemo nazad

A u slučaju nultog ishoda, kada je tabela završila, a kod za skeniranje nikada nije pronađen, ili je nula bila u registru R16 na ulazu, vraćamo se sa istom nulom na izlazu. Samo tako.



; STATIČKI PODACI
;========================================
Code_Table: .db 0x71,0x31 ;1
.db 0xB1,0x32 ;2
.db 0xD1,0x33 ;3
.db 0x72,0x34 ;4
.db 0xB2,0x35 ;5
.db 0xD2,0x36 ;6
.db 0x73,0x37 ;7
.db 0xB3,0x38 ;8
.db 0xD3,0x39 ;9
.db 0x74,0x30 ;0
.db 0xFF,0 ;END

Postoji samo tabela statičkih podataka na ivici memorije. Kao što vidite, podaci su grupisani u dva bajta - scancode/ASCII

Zahvaljujući ovakvim perverzijama, cijeli program, sa obradom tastature, dekodiranjem koda za skeniranje, čitanjem/upisivanjem na LCD indikator i resetiranjem RAM-a (potrebno da bi se osiguralo da je memorija nula) je trajao samo 354 bajta. Ko može manje?

Ako je potrebno koristiti tastaturu s velikim brojem tipki u uređaju, na primjer, u kombinovanoj bravi, često se koristi matrična tastatura. Ako povežete 12 tipki na uobičajen način, trebat će vam 12 pinova mikrokontrolera plus zajednička žica, ali matrica koristi samo jedan port za kontroler, što pomaže u čuvanju pinova kontrolera. Tasteri u takvoj tastaturi su povezani na zajedničke kolone i na zajedničke redove, linije porta mikrokontrolera su podeljene na ulaz PB7-PB4 i izlaz PB3-PB0. U svakom trenutku signal nizak nivo(logička nula) se isporučuje samo jednom redu dugmadi, ostatak mora biti dostavljen logičkom. Ovo će eliminisati nejasnoće u određivanju broja pritisnutog dugmeta. Binarni signali prisutni na kolonama tastature čitaju se kroz ulazni port mikrokontrolera.

Moramo organizovati beskonačnu petlju u programu. IN posebna funkcija Ispitujemo tastaturu, analiziramo primljene podatke i prikazujemo rezultate na indikatoru. Prozivanje tastature se sastoji od sekvencijalnog skeniranja svake linije za ovu svrhu, logička nula se primenjuje na odgovarajuću liniju izlaznog porta (ekvivalentno zajednička žica), preostali redovi bi trebali biti visoki, nakon čega se kod čita sa ulaznog porta na koji su stupci povezani. Ako su svi pročitani, tada se ne pritisne nijedan taster, inače kod sadrži informacije o pritisnutim tasterima. Vrijedi napomenuti da kod za čitanje sadrži ne samo broj zatvorenog kontakta, već i informacije o istovremenom pritisku na nekoliko tipki, pa je bolje pročitani kod pohraniti direktno u memoriju kontrolera, a ne gotovo dugme broj. Da biste pohranili pročitani kod, morate unijeti poseban algoritam i varijable.

Ispod je primjer programa u kojem kada pritisnete određeni taster, njegova vrijednost se prikazuje sedmosegmentni indikator. Atmega8 mikrokontroler radi od internog oscilatora sa frekvencijom od 8MHz.

/*** Veza matrična tastatura na AVR mikrokontrolere ***/ #include #include // Niz vrijednosti za izlazni port unsigned char key_tab = (0b11111110, 0b11111101, 0b11111011, 0b11110111); // Funkcija anketiranja tipkovnice unsigned char scan_key(void) (unsigned char key_value = 0; unsigned char i; for(i = 0;i)< 4;i++) { PORTB = key_tab[i]; // выводим лог. 0 в порт вывода _delay_us(10); switch (PINB & 0xF0) { case 0b11100000: key_value = 1 + i * 3; return (key_value); case 0b11010000: key_value = 2 + i * 3; return (key_value); case 0b10110000: key_value = 3 + i * 3; return (key_value); default: break; } } return (key_value); } int main(void) { // массив цифр для индикатора unsigned char num = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F}; DDRB |= (1 << PB3)|(1 << PB2)|(1 << PB1)|(1 << PB0); // Порт вывода DDRB &= ~(1 << PB7)|(1 << PB6)|(1 << PB5)|(1 << PB4); // Порт ввода PORTB = 0xF0; // Устанавливаем лог. 1 в порт ввода DDRD = 0xFF; // Выход на индикатор PORTD = 0x00; _delay_ms(10); while(1) { // Выводим значение нажатой кнопки на индикатор if(scan_key()==1) PORTD = num; if(scan_key()==2) PORTD = num; if(scan_key()==3) PORTD = num; if(scan_key()==4) PORTD = num; if(scan_key()==5) PORTD = num; if(scan_key()==6) PORTD = num; if(scan_key()==7) PORTD = num; if(scan_key()==8) PORTD = num; if(scan_key()==9) PORTD = num; if(scan_key()==11) PORTD = num; } }

Arhiva za članak "Povezivanje matrične tastature na AVR mikrokontrolere"
Opis: Projekt AVRStudio i Proteus
Veličina fajla: 37,33 KB Broj preuzimanja: 1 905
  1. Proučiti karakteristike rada paralelnih portova mikrokontrolera.
  2. Proučite dijagrame za povezivanje dugmadi i matrične tastature na mikrokontroler.
  3. Naučite odrediti stanje dugmadi pomoću programa.
  4. Naučite kako da otklanjate greške u programima na LESO1 laboratorijskoj klupi.
  5. Naučite kako radi matrična tastatura.

2 Prethodne pripreme za rad

  1. Koristeći bilješke s predavanja i preporučenu literaturu, proučite sklopove paralelnih portova mikrokontrolera.
  2. Koristeći bilješke s predavanja i preporučenu literaturu, proučite dijagrame za povezivanje tipki i tastatura na paralelne portove.
  3. Proučite arhitekturu ADuC842 mikrokontrolera.
  4. Proučite šematski dijagram laboratorijskog stalka LESO1.
  5. Kreirajte algoritam za program: kada pritisnete dugme, prema opciji, zasvetli kombinacija LED dioda, koja u binarnom obliku odgovara broju dugmeta; Kada se dugme otpusti, LED diode bi se trebale ugasiti.
  6. Napišite program u programskom jeziku C.

3 Kratke teorijske informacije

3.1 Korišćenje matrične tastature za unos informacija u mikroprocesorski sistem

Za implementaciju interakcije korisnika sa mikroprocesorskim sistemom koriste se različiti ulazno-izlazni uređaji. U najjednostavnijem slučaju, dugme može djelovati kao ulazni uređaj, što je elementarni mehanizam koji zatvara i otvara kontakte pod utjecajem vanjske mehaničke sile. Šema povezivanja dugmeta sa ulaznom linijom paralelnog ulaznog porta mikrokontrolera prikazana je na slici 1. Kada su kontakti dugmeta S1 otvoreni preko otpornika R1, na ulazu kontrolera se prima visoki logički nivo „1“. kada su kontakti zatvoreni, ulaz je povezan na zajedničku žicu, što odgovara logičkom nivou "0". Ako paralelni port mikrokontrolera ima ugrađeni generator struje, krug može bez otpornika R1.

Slika 1 – Povezivanje jednog dugmeta na paralelni port

Nedostatak gornjeg dijagrama je taj što je za povezivanje svakog dugmeta potrebna posebna linija paralelnog porta. Pošto je često potrebno unositi informacije sa velikog broja dugmadi, da bi se smanjio broj I/O linija, koristi se tastatura, koja je dvodimenzionalna matrica dugmadi organizovanih u redove i kolone (slika 2).

Povezivanje tastature razlikuje se od dijagrama povezivanja za jedno dugme po tome što se potencijal zajedničke žice dovodi do tastera koji se prozivaju ne direktno, već preko izlaznog porta.

U svakom trenutku, signal niske razine (logička nula) se dostavlja samo jednoj koloni dugmadi; Ovo će eliminisati nejasnoće u određivanju broja pritisnutog dugmeta. Binarni signali prisutni na linijama tastature čitaju se kroz ulazni port mikrokontrolera.


Slika 2 – Povezivanje matrične tastature na paralelni port

Vremenski dijagram napona na izlaznim portovima prilikom izvršavanja programa prozivanja tastature prikazan je na slici 3.


Slika 3 – Vremenski dijagrami rada izlaznog porta

U svakom trenutku, informacije se čitaju sa ulaznog porta. Program mikrokontrolera mora odrediti broj pritisnutog dugmeta tastature na osnovu pročitane kombinacije.

Program za mikrokontroler striktno ovisi o dijagramu sklopa uređaja koji se razvija. Nemoguće je napisati program za mikrokontrolerski uređaj, a da pred sobom nemate njegov dijagram. Stoga, prije nego počnete raditi na šematskom dijagramu LESO1 stalka za vježbanje, trebali biste proučiti način povezivanja tipkovnice i LED dioda na mikrokontroler: odrediti na koje su portove spojene LED diode, stupci i redovi tipkovnice. Zatim, koristeći SFR tablicu, trebate saznati adrese registra uključenih I/O portova.

Program koji upravlja mikrokontrolerom počinje kada se uređaj uključi i ne završava svoj rad sve dok se napajanje ne isključi. Stoga program mora imati beskonačnu petlju. Telo petlje bi trebalo da anketira tastaturu, analizira primljene podatke i šalje rezultat na LED. Prozivanje tastature se sastoji od sekvencijalnog skeniranja svake kolone, za to se logička nula (ekvivalentna zajedničkoj žici) primjenjuje na odgovarajući red izlaznog porta, nakon čega se čita kod; ulazni port na koji su redovi povezani. Ako su svi pročitani, tada se ne pritisne nijedan taster, inače kod sadrži informacije o pritisnutim tasterima. Vrijedi napomenuti da kod za čitanje sadrži ne samo broj zatvorenog kontakta, već i informacije o istovremenom pritisku na nekoliko tipki, pa je bolje pročitani kod pohraniti direktno u memoriju kontrolera, a ne gotovo dugme broj. Da biste pohranili pročitani kod, morate unijeti posebnu varijablu.

Kada pišete program, morate zapamtiti karakteristike paralelnog porta P1 u mikrokontroleru ADuC842. Ovaj port je po defaultu konfiguriran za ulaz analognih signala (ADC funkcija). Da bi se port prebacio u režim digitalnog ulaza, logička nula mora biti upisana u odgovarajući bit porta. Ovo se mora uraditi jednom prilikom inicijalizacije mikrokontrolera. Port nema interni tranzistor za pojačanje, pa stoga, prilikom unosa diskretnih informacija kroz njega, nije potrebno upisivati ​​logički u bitove.

4 Zadatak za rad u laboratoriji

  1. Koristeći shematski dijagram, ustanovite na koje portove mikrokontrolera su povezane LED diode, kao i kolone i redove tastature.
  2. Koristite tablicu registara posebnih funkcija (SFR) da odredite adrese registra potrebnih portova.
  3. Uđite u Keil-C integrirano programsko okruženje.
  4. Kreirajte i pravilno konfigurišite projekat.
  5. Unesite tekst programa u skladu sa zadatkom: Pritiskom na dugme, prema opciji, svetli kombinacija LED dioda, koja u binarnom obliku odgovara broju tastera; Kada se dugme otpusti, LED diode bi se trebale ugasiti.
  6. Prevedite program i ispravite sintaksičke greške.
  7. Preuzmite primljeno *.hex fajl na laboratorijski štand LESO1.
  8. Provjerite funkcionira li program ispravno.

5 Uputstva za izradu izvještaja

Izvještaj mora sadržavati:

  1. Svrha rada.
  2. Šematski dijagram povezivanja tastature sa mikrokontrolerom.
  3. Grafički dijagram programskog algoritma.
  4. Izvorni tekst programa.
  5. Sadržaj datoteke sa listingom softverskih projekata.
  6. Zaključci obavljenog laboratorijskog rada.

Šeme, kao i izvještaj u cjelini, provode se u skladu sa standardima ESKD-a.

Otpornici R2 – R4, R8 – R11 su dizajnirani da ograniče ulazno/izlaznu struju u slučaju pogrešnih podešavanja porta ili istovremenog pritiska na nekoliko tastera. Pinovi PD0(RXD), PD1(TXD) su povezani na UART-RS232 pretvarač, koji nije prikazan na dijagramu. USART razmena se koristi za otklanjanje grešaka u programu.

Matrični algoritam za ispitivanje tastature

Linije tastature su povezane na pinove PD4, PD5, PD6, PD7. Oni su konfigurisani za izlaz i u početnom stanju postoji logički nulti napon na ovim pinovima. Kolone su povezane na pinove PC0, PC1, PC2. Postavljeni su na ulaz, interni pull-up otpornici su onemogućeni, a ovi vodovi su “null powered” koristeći eksterne 10K otpornike.

Procedura za skeniranje tastature je sljedeća. Postavljamo 1 na pin PD4 i provjeravamo stanje pinova PC0, PC1, PC2 (odnosno čitamo sadržaj PINC registra). Ako je jedan od pinova postavljen na 1, to znači da je dugme spojeno na prvu liniju trenutno pritisnuto na tastaturi. Bitove PD4, PD5, PD6, PD7 i PC0, PC1, PC2 spremamo u jednu varijablu - pomoću ovog koda ćemo odrediti broj pritisnutog dugmeta. Ako nijedno dugme nije pritisnuto, nastavite sa procedurom skeniranja.

Resetujemo 1 na pin PD4 i postavljamo 1 na pin PD5. Ponovo provjeravamo stanje pinova PC0, PC1, PC2, i ako se pritisne dugme, spremamo bitove PD4, PD5, PD6, PD7 i PC0, PC1, PC2 u varijablu.

Ponavljamo opisani niz za preostala dva reda.

Prebacivanje tastera na tastaturi je praćeno odbijanjem kontakta, koje mikrokontroler može „percipirati“ kao višestruko pritiskanje. U aplikacijama koje koriste tastature, ovo je nepoželjna pojava, pa program za ispitivanje tastature mora imati neku vrstu zaštite. Obično to rade - činjenica pritiska na dugme se registruje ako se drži pritisnuto nekoliko ciklusa glasanja.

Kod primljen tokom skeniranja tastature često treba da se konvertuje u simboličku vrednost broja/slova dugmeta (na primer, za prenos preko USART-a). Da biste to učinili, možete kreirati tablicu konverzije - dvodimenzionalni niz. Prva kolona tabele će pohraniti kodove dugmadi, a druga kolona će sadržavati odgovarajuće simboličke vrijednosti. Koristeći metodu sekvencijalnog pretraživanja u tabeli, možete pronaći željenu vrijednost.

Algoritam anketiranja matrične tastature može se implementirati kao konačni stroj (State Machine) - funkcija koja, ovisno o svom stanju (vrijednosti određene varijable) i ulaznoj radnji, obavlja različite poslove. Na slici ispod prikazan je dijagram takve mašine.

Početno stanje mašine je 0. Mašina ostaje u ovom stanju sve dok se ne pritisne bilo koje dugme. Kada se otkrije pritisak na dugme, pokreće se funkcija skeniranja tastature ScanKey(), kod pritisnutog dugmeta se pamti i mašina prelazi u stanje 1.

U stanju 1, mašina provjerava da li je trenutno pritisnuto isto dugme kao u stanju 0 ili ne. Ako se kodovi dugmadi ne poklapaju, mašina se vraća u stanje 0, ako se podudaraju, pokreće se funkcija FindKey(), koja pronalazi simboličku vrednost broja dugmeta i postavlja zastavice koje signaliziraju sistemu o pritisnutom dugmetu. Po završetku funkcije, mašina prelazi u stanje 2.

Sve dok je isto dugme pritisnuto, mašina je u stanju 2. Ako dođe do bilo kakvih promena, prelazi u stanje 3.

Ako je promjena bila slučajna, mašina se vraća u stanje 2, a ako nije, prelazi u početno stanje kako bi ponovo pokrenula funkciju skeniranja tastature.

Softverska implementacija mašine

Prikazani dijagram državnog stroja može se lako pretvoriti u programski kod.

//pohranjuje trenutno stanje mašine
unsigned char keyState;

//prototipovi funkcija koje koristi mašina
unsigned char AnyKey( void );
unsigned char SameKey( void );
void ScanKey( void );
unsigned char FindKey( void );
void ClearKey( void );

void ScanKeyboard( void )
{
prekidač(keyState)(
slučaj 0:
ako(Bilo koji ključ()) (
ScanKey();
keyState = 1;
}
break;

slučaj 1:
ako(SameKey()) (
FindKey();
keyState = 2;
}
ostalo keyState = 0;
break;

slučaj 2:
ako(SameKey())()
ostalo keyState = 3;
break;

slučaj 3:
ako(SameKey()) (
keyState = 2;
}
ostalo {
ClearKey();
keyState = 0;
}
break;

Zadano:
break;
}

Prilično vizuelan unos. Sada nam preostaje samo da napišemo/raščlanimo implementacije funkcija koje nedostaju. Da bi programski kod bio što jasniji, hajdemo bez makro definicija. Dakle, redom.


unsigned char AnyKey( void )
{
PORTD |= 0xf0;
povratak(PINC&0x07);
}

Postavljamo pinove PD7 – PD4 na jedinice i vraćamo stanja pinova PC2 – PC0. Ako se u ovom trenutku pritisne bilo koja od tipki na tipkovnici, funkcija će vratiti vrijednost različitu od nule, odnosno true.

//pohranjuje kod pritisnutog dugmeta
unsigned char keyCode;

void ScanKey( void)
{
unsigned char aktivniRed = (1<<4);
dok(aktivni red) (
PORTD = (PORTD & 0x0f)|activeRow;
ako(PINC & 0x07) (
keyCode = (PINC & 0x07);
keyCode |= (PORTD & 0xf0);
}
activeRow<<= 1;
}
}

Postavite četvrti bit varijable activeRow na 1 (aktivirajte prvi red). Nakon brisanja bitova PD7 – PD4, upisujemo varijablu u PORTD. Ako je bilo koja od tri najmanje značajne cifre PINC registra postavljena na jedan, tada je trenutno pritisnuto dugme koje odgovara prvom redu. Bitove PD7 - PD4 i PC2 - PC0 spremamo u varijablu keyCode. Pomaknite vrijednost varijable activeRow ulijevo za jednu cifru i ponovite ciklus još tri puta.


unsigned char SameKey( void )
{
PORTD = (PORTD & 0x0f) | (ključni kod & 0xf0);
povratak((PINC & šifra ključa) & 0x07);
}

Funkcija provjerava da li kod trenutno pritisnutog dugmeta odgovara kodu primljenom u prethodnom ciklusu prozivanja. Da biste to učinili, postavite 1 na željenu liniju - najznačajnija 4 bita ključnog koda se upisuju u PORTD. Zatim se čita PINC registar, na njega se primjenjuje maska ​​u obliku varijable keyCode i dodjeljuju se 3 najmanje značajna bita. Rezultirajuća vrijednost se vraća. Ako se kodovi dugmadi podudaraju, vrijednost će biti različita od nule, odnosno tačna.


//pohranjuje simboličku vrijednost pritisnutog dugmeta
unsigned char keyValue;
//flag varijabla - postaviti ako se dugme drži pritisnuto
unsigned char keyDown;
//flag varijabla - postavlja se kada se pritisne novo dugme
unsigned char keyNew;

//tabela konverzije
__flash unsigned cha r tablica ključeva = (
(0x11, "1"),
(0x12, "2"),
(0x14, "3"),
(0x21, "4"),
(0x22, "5"),
(0x24, "6"),
(0x41, "7"),
(0x42, "8"),
(0x44, "9"),
(0x81, "*"),
(0x82, "0"),
(0x84, "#")
};

unsigned char FindKey( void )
{
unsigned char indeks;
za(indeks = 0; indeks< 12; index++) {
ako(tablica ključeva == šifra ključa) (
keyValue = keyTable ;
keyDown = 1;
keyNew = 1;
povratak 1;
}
}
povratak 0;

U ovom članku želim čitatelje upoznati sa povezivanjem tastature s mikrokontrolerima. Činjenica je da obično većina sklopova mikrokontrolera zahtijeva jedno ili više tipki za unos podataka. Ali kako projekti postaju složeniji, možda ćete morati koristiti manju tastaturu. Postoje varijante tastatura 3x4 ili 4x4, a gotovo uvijek su tipke u njima povezane prema matričnom dijagramu. Upotreba matrice je neophodna jer je za njeno povezivanje potreban minimalan broj ulazno-izlaznih linija. Na primjer, za tastaturu 4x4 koja se sastoji od 16 tipki potrebno je 16 ulaznih linija, pa je racionalnije organizirati je u obliku matrice, tj. rasporedite 4 dugmeta u 4 reda, koristeći 8 ulazno-izlaznih linija (jedan port mikrokontrolera). Najčešće rješenje za povezivanje matrice na jedan port je povezivanje redova na cifre visokog reda i kolone na one nižeg reda. Međutim, ovdje postoji problem - očitavanje stanja tipkovnice se događa kada dođe do prekida, ali u mikrokontroleru ATtiny2313 možemo koristiti dva eksterna prekida (ostatak pinova su zauzeti). Ovaj problem je riješen povezivanjem četiri diode koje formiraju "OR" element sa pull-up otpornikom na INT0 ulazu.

Dijagram za povezivanje tastature 4x4 matričnog tipa na mikrokontroler prikazan je na slici 1. Ima DB-9F konektor, MAX3232 konvertor nivoa, koji su neophodni za interakciju UART mikrokontrolera sa RS-232, a čiji je rad opisan u prethodnom članku. Otpornici R3 - R6 štite mikrokontroler od kratkog spoja struje na masu. Na ulazu INT0 nalazi se pull-up otpornik R7. Četiri diode VD1 - VD4 su povezane na I/O linije tastature (katode) i na pin INT0 (anode). Sada, kada pritisnete bilo koje dugme, ako su nule primenjene na kolone, nizak nivo će se pojaviti na INT0 ulazu.

Kao što je prikazano na slici 1, tastatura je povezana na port B mikrokontrolera. Njegov dijagram je prikazan na slici 2.

Pretpostavimo da je sav port B konfigurisan za ulaz, a svi ulazi su povučeni:

DDRB = &B00000000

PORTB = &B11111111

Neka tasteri (slika 2) budu nekako spojeni na masu (GND), onda kada pritisnete, na primer, dugme „1“, kontakti porta B PB3 i PB4 će biti niski, tj. port će uzeti vrijednost PORTB = &B11100111, što je kod za dugme “1”. Isto važi i za preostale dugmad (šifra dugmeta “B” je 01111011, “5” je 11011011, itd.). Ali, pošto dugmad nisu povezana na GND, potrebno je uvesti odvojenu definiciju redova i kolona, ​​nakon čega sledi zbrajanje i identifikaciju rezultata sa imenom dugmeta.

Napravimo redove PB0 - PB3 ulaze i uključimo njihovo povlačenje, a kolone PB3 - PB7 - izlaze:

DDRB = &B11110000

PORTB = &B00001111

Kada se pritisne dugme, određena linija će se spustiti. Na primjer, kada pritisnete dugme “1”, port B će poprimiti vrijednost 00000111, što je kod linije. Istovremeno će se uključiti prekid, tokom čije obrade je potrebno pročitati ovaj kod u Stro varijablu:

Invertirajmo postavke porta - napravimo stupce PB3 - PB7 ulaze i uključimo njihovo povlačenje, a redove PB0 - PB3 - izlaze:

DDRB = &B00001111

PORTB = &B11110000

Sada kada se pritisne dugme "1", port će imati vrednost 11100000, što je kod kolone. Ovaj kod čitamo u varijablu Col.