EB keyboard

Z MAM wiki

Verze z 11. 3. 2014, 14:48; Horcik (diskuse | příspěvky)
(rozdíl) ← Starší verze | zobrazit aktuální verzi (rozdíl) | Novější verze → (rozdíl)
Přejít na: navigace, hledání

S připojením jednotlivých tlačítek jsme se seznámili při našem prvním pokusu v simulátoru AVR, jakmile se množství tlačítek zvětší (6 a více), ušetříme vývody procesoru zapojením tlačítek do matice a jejich postupným souřadnicovým čtením. Klávesnice vývojové destičky má 10 tlačítek S1 až S10 zapojených v neúplné matici 3*4, je tedy připojena 7 vodiči, 3 pro řady a 4 pro sloupce. Pozor, na plošném spoji destičky je uspořádání tlačítek odlišné od schématu, fyzicky jsou v horní vodorovné řadě tlačítka S1, S4 a S7 připojená ke vstupu PC1, druhá řada je S2, S5 a S8 na PC2, třetí řada S3, S6, S9 na PC3, a ve čtvrté řadě je pouze tlačítko S10 připojené jako čtvrté ke vstupu PC2.


Schéma zapojení klávesnice:

Klávesnice

Obsluha klávesnice je obdobná jako v prvním pokusu v simulátoru AVR s interním pull-up rezistorem na vstupech PC1-PC3, jen nemáme tlačítka připojená druhým koncem přímo k zemi, ale přes diody D1-D10 k výstupním portům PD2-PD5. Pro nalezení, které tlačítko bylo stisknuto, je vždy jenom jeden budicí výstup ve stavu L, všechny ostatní jsou ve třetím stavu (díky diodám mohou být i v H). Která řada je v L periodicky měníme. Vstupy jsou interními pull-up rezistory (měkká jednička) drženy v H. Zachycení stavu L na některém vstupu PC1-PC3 znamená stisknutí tlačítka, jeho souřadnici určuje řada a sloupec, na kterých je nalezena úroveň L. Výstup nakonfigurujeme do třetího stavu přepnutím příslušného bitu registrů DDRD a PORTD do log. 0, tj. na vstup bez pull-up rezistoru.

Pro zjištění, že bylo zmáčknuto nějaké tlačítko, můžeme nastavit všechny výstupu PD2-PD5 do log. 0 a hlídat změnu kteréhokoliv vstupu PC1-PC3 do log. 0, teprve když se log. 0 objeví, tak je třeba prohledat celou matici tlačítek klávesnice postupně.


Přerušení

Přerušení vyvolá změnu běhu programu v závislosti na vnějším hardwarovém podnětu. Přerušení lze vyvolat prakticky od všech periferií a mnoha dalšími událostmi, podrobný popis je v sekci Interrupts datasheetu. My v programu využíváme přerušení vyvolané změnou úrovně signálu na klávesnici, každá změna způsobí skok do tabulky interrupt vektorů, umístěné např. od začátku programové paměti, podle typu procesoru je v ní pro každý zdroj přerušení vyhrazeno 1 šestnáctibitové slovo (ATmega48 a 88) nebo 2 slova (ATmega168) pro skok na obsluhu přerušení. Obsluha je zajištěna podprogramem, který končí instrukci reti, návrat z interruptu. Jaké přerušení je povoleno a na co reaguje je třeba nastavit řídicími slovy, konkrétně pro náš případ čtení klávesnice aktivujeme přerušení od 3 bitů PINC, kam máme připojené vstupy pro čtení klávesnice (PC1..PC3), v řídicím registru PCICR přerušení povolujeme přerušení PCINT1 od portu C a v řídicím registru PCMSK1 nastavujeme masku, které bity portu mohou přerušení vyvolat. Přerušení je třeba globálně povolit instrukcí SEI. Pro obsluhu přerušení je nutné mít předem správně nastavený zásobník (stack), ukládají se do něj návratové adresy! Vhodné je nastavit ho na konec RAM, lze využít low(RAMEND) a high(RAMEND) z .INCLUDE "m168Adef.inc".

Úplný seznam vektorů přerušení a jejich možná obsluha pro ATmega168 (pozor, u ATmega88 s menší velikostí paměti se liší, jsou na po sobě bezprostředně následujících adresách, neboť místo skoku JMP na absolutní adresu stačí relativní RJMP, který se vejde do jednoho slova místo JMP ve dvou slovech!):

.org 0x0000 
	jmp RESET ; Reset Handler
.org 0x0002 
	jmp EXT_INT0 ; IRQ0 Handler
.org 0x0004 
	jmp EXT_INT1 ; IRQ1 Handler
.org 0x0006 
	jmp PCINT0 ; PCINT0 Handler
.org 0x0008 
	jmp PCINT1 ; PCINT1 Handler
.org 0x000A 
	jmp PCINT2 ; PCINT2 Handler
.org 0x000C 
	jmp WDT ; Watchdog Timer Handler
.org 0x000E 
	jmp TIM2_COMPA ; Timer2 Compare A Handler
.org 0x0010 
	jmp TIM2_COMPB ; Timer2 Compare B Handler
.org 0x0012 
	jmp TIM2_OVF ; Timer2 Overflow Handler
.org 0x0014 
	jmp TIM1_CAPT ; Timer1 Capture Handler
.org 0x0016 
	jmp TIM1_COMPA ; Timer1 Compare A Handler
.org 0x0018 
	jmp TIM1_COMPB ; Timer1 Compare B Handler
.org 0x001A 
	jmp TIM1_OVF ; Timer1 Overflow Handler
.org 0x001C 
	jmp TIM0_COMPA ; Timer0 Compare A Handler
.org 0x001E 
	jmp TIM0_COMPB ; Timer0 Compare B Handler
.org 0x0020 
	jmp TIM0_OVF ; Timer0 Overflow Handler
.org 0x0022 
	jmp SPI_STC ; SPI Transfer Complete Handler
.org 0x0024 
	jmp USART_RXC ; USART, RX Complete Handler
.org 0x0026 
	jmp USART_UDRE ; USART, UDR Empty Handler
.org 0x0028 
	jmp USART_TXC ; USART, TX Complete Handler
.org 0x002A 
	jmp ADCon ; ADC Conversion Complete Handler
.org 0x002C 
	jmp EE_RDY ; EEPROM Ready Handler
.org 0x002E 
	jmp ANA_COMP ; Analog Comparator Handler
.org 0x0030 
	jmp TWI ; 2-wire Serial Interface Handler
.org 0x0032 
	jmp SPM_RDY ; Store Program Memory Ready Handler


Užitečné fragmenty programu pro obsluhu klávesnice:


.INCLUDE "m168def.inc"


.ORG 0x0000 
	jmp Main ; Reset Handler

.ORG 0x0008 
	jmp isr1 ; PCINT1 Handler



; Main program start

Main: 

; Stack pointer init:
	ldi r16,high(RAMEND)	;Main program start
	out SPH,r16 	;Set Stack Pointer to top of RAM
	ldi r16,low(RAMEND)
	out SPL,r16


; Hardware initialization

; Keyboard init:
; PC3:1 inputs with pull-ups
; PD5:2 outputs with log.0

Nastavení řídicích slov pro vyvolání přerušení

; Keyboard interrupt setup
;
; Activation of pin change interrupt - PROBLEM!!! PCICR and PCIMSK are 
; extended I/O registers (0x68 and 0x6C), and must be handled as 
; a memory location
;
; X - alias for 16-bit register created from two 8-bit registers R27, R26

	ldi r26, PCICR ; load address of PCICR in X low
	clr r27 ; load high byte with 0
	ldi r16,0b00000010 ; activate PCINT1
	st X, r16 ; store new PCINT1

	ldi r26, PCMSK1 ; load address of PCMSK1 in X low
	clr r27 ; load high byte with 0
	ldi r16,0b00001110 ; allow pin change interrupt on portC bits 1,2,3
	st X, r16 ; store new PCMSK1

	sei ; Enable interrupts

Obsluha přerušení od klávesnice - bylo zmáčknuto nějaké tlačítko, potřebujeme zjistit jaké a jeho kód zobrazit na displeji

isr1:
	rcall KEYPRESS
	rcall DISPLAY
	reti ; return from Interrupt
Osobní nástroje