Hi,
ich habe offensichtlich ein Verständnisproblem mit dem
keyboard-interface des AT89C51ED2. Es ist eine einfache 2x3
Tastaturmatrix angeschlossen.
Das Atmel-Testprogramm erkennt keine Taste, da kein Interrupt ausgelöst
wird.
Woran kann das liegen? Den SPI-Bus benutze ich auch, später, wenn die
Tasten
erkannt werden...
Verschiedene KBE, KBLS Registerkombinationen habe ich schon probiert...
Danke für etl. Tipps
RABIS 1 | // SDCC
| 2 | #include <AT89C51ED2.h>
| 3 | // ...
| 4 |
| 5 | unsigned int keypressed; /* key pressed value */
| 6 | __bit volatile key_flag; /* software flag */
| 7 |
| 8 | void main()
| 9 | {
| 10 | EA=1; /* enable interrupts */
| 11 | /* init keyboard */
| 12 | KBE=0xFF; /*Enable all P1 I/O as keyboard IO */
| 13 | KBF=0x00; /* Clear all keyboard flags */
| 14 | IEN1 |=0x01; /* Enable keyboard interupt */
| 15 |
| 16 | while(1) /* endless */
| 17 | {
| 18 | if (key_flag) /* keyboard occur */
| 19 | {
| 20 | printf_fast("keypressed: %x\r\n",keypressed);
| 21 | key_flag=0; /* reset softaware flag */
| 22 | }
| 23 | }
| 24 | }
| 25 |
| 26 | /**
| 27 | * FUNCTION_PURPOSE:keyboard_interrupt. Save pressed key
| 28 | * FUNCTION_INPUTS:void
| 29 | * FUNCTION_OUTPUTS:void
| 30 | */
| 31 | void keyboard_interrupt() interrupt 7 using 1
| 32 | {
| 33 | keypressed=KBF; /* save pressed key */
| 34 | key_flag=1; /* set the software flag */
| 35 | KBF=0x00; /* clear keyboard flags */
| 36 | }
|
R. B. schrieb:
> Das Atmel-Testprogramm erkennt keine Taste, da kein Interrupt ausgelöst
> wird.
Da hatter auch recht, High auf High ergibt keine Änderung.
Du müßtest erstmal P1.0 - P1.2 auf Low setzen.
Erst dann ändern sich beim Drücken P1.3 oder P1.4.
Peter
@ Peter
Bis jetzt habe ich P1.3 und P1.4 auf low gesetzt und R1 und R2
weggelassen.
Dann werden zumindest alle Tasten (doppelt) erkannt.
Danke vorerst, Deinen Tipp werde ich heute ausprobieren.
Atmel-Support ggrrrhhh.
RABIS
R. B. schrieb:
> Dann werden zumindest alle Tasten (doppelt) erkannt.
Willkommen in der realen Welt der Mechanik, Taster prellen nunmal.
Deshalb nimmt man den Keyboard-Interrupt nur zum Aufwachen aus dem
Powerdown.
Das Einlesen und Entprellen macht man dann in der üblichen Weise mit dem
Timerinterrupt.
R. B. schrieb:
> Atmel-Support ggrrrhhh.
Der Support wird Dir kaum beim Programmieren lernen helfen.
Er ist für konkrete Probleme mit dem Chip zuständig, z.B. wenn Du einen
Bugreport hast.
Peter
R. B. schrieb:
> Bis jetzt habe ich P1.3 und P1.4 auf low gesetzt und R1 und R2
> weggelassen.
Wie rum, ist egal.
Ich hatte nur andersrum geschrieben, damit die 2 Pullups nicht nutzlos
sind.
Peter
Hier mal ne gute Beschreibung, die ich gefunden habe:
http://mikrocontroller.rahm-home.de/docfiles/Uebungen/4_7_6_Matrixtastatur_mit_Interrupt.pdf
Ich bin davon ausgegangen, dass die Keyboard-Steuerung im AT89C51ED2
"intelligent" ist und Entprellung, Dekodierung und Multiplex übernimmt.
Zu der Annahme hat mich die Application Note ANM071 für den TSC80251G1
von Atmel verleitet.
Die "normale" Keyboardmatrix hatte ich schon.
Gruß
RABIS
R. B. schrieb:
> Ich bin davon ausgegangen, dass die Keyboard-Steuerung im AT89C51ED2
> "intelligent" ist und Entprellung, Dekodierung und Multiplex übernimmt.
> Zu der Annahme hat mich die Application Note ANM071 für den TSC80251G1
> von Atmel verleitet.
Nö, da steht doch:
"In the demonstration software, timer 1 is used to manage the debounce
delay."
Ein stupides Warten ist allerdings kein sehr zuverlässiges Entprellen,
wird aber leider oft so gemacht.
Peter
So, hier nun meine (abschließende) Lösung:
keyboard.c 1 | //-----------------------------------------------------------------------------
| 2 | #ifndef __KEYBOARD
| 3 | #define __KEYBOARD
| 4 | #include <stdio.h>
| 5 | #include <serial_IO.h>
| 6 | #include ".\keyboard.h"
| 7 | //-----------------------------------------------------------------------------
| 8 |
| 9 | volatile __bit key_flag; // software flag
| 10 | unsigned char Keycode;
| 11 |
| 12 | //-----------------------------------------------------------------------------
| 13 | void Keyboard_Init(void) {
| 14 | P1 = #0b00000111; // Spaltenleitungen = 0, Zeilenleitungen = 1
| 15 | KBLS = #0b00000000; // L-Pegel für Auslösung Keyboardinterrupt
| 16 | KBE = #0b00000111; // Tastatur Zeileninterrupts freigeben
| 17 | IEN1 |= KBD;
| 18 | }
| 19 |
| 20 | //-----------------------------------------------------------------------------
| 21 | //
| 22 | // main
| 23 | //
| 24 | //-----------------------------------------------------------------------------
| 25 | void main(void) {
| 26 |
| 27 | #if (X2Mode == 1)
| 28 | CKCON0 = 0x01; // X2 Mode
| 29 | CKCON1 = 0x01; // SPI clock = Xtal/12
| 30 | #else
| 31 | CKCON0 = 0x00; // STD Mode
| 32 | CKCON1 = 0x00; // SPI clock = Xtal/12
| 33 | #endif
| 34 |
| 35 | key_flag = 0;
| 36 | Keyboard_Init();
| 37 | EA = 1;
| 38 |
| 39 | inituart((unsigned int) \
| 40 | (256-((Xtal/Baud)*(X2Mode+1)/192))); // Timer 1
| 41 | printf_fast("\r\n\-- Keyboard V 0.01 -- \r\n>");
| 42 |
| 43 | while(1){
| 44 | if (key_flag) {
| 45 | printf_fast("Keycode: %x\r\n",Keycode);
| 46 | key_flag = 0;
| 47 | }
| 48 | }
| 49 | }
| 50 |
| 51 | //-----------------------------------------------------------------------------
| 52 | #endif
| 53 | //-----------------------------------------------------------------------------
|
keyboard.h 1 | //-----------------------------------------------------------------------------
| 2 |
| 3 | #ifndef __AT89C51ED2
| 4 | #define __AT89C51ED2
| 5 | #include "D:\SDCC_include\AT89C51ED2.h"
| 6 | #define Xtal 22118400
| 7 | #define X2Mode 1
| 8 | #endif
| 9 |
| 10 | //-----------------------------------------------------------------------------
| 11 |
| 12 | #define EEPROM 0x0000 // chip internal EEPROM
| 13 | #define EEPROMSIZE 2048
| 14 | #define XRAM 0x0000 // chip internal XRAM
| 15 | #define XRAMSIZE 1792
| 16 | #define Baud 38400
| 17 |
| 18 | //-----------------------------------------------------------------------------
| 19 |
| 20 | #ifdef __KEYBOARD
| 21 | extern void ISR_KBD (void) __interrupt KBD_VECTOR __using 1 __naked ;
| 22 | #endif
|
und die isr.c 1 | //-----------------------------------------------------------------------------
| 2 | #include ".\keyboard.h"
| 3 | //-----------------------------------------------------------------------------
| 4 | //
| 5 | // Function: Interrupt service routines
| 6 | //
| 7 |
| 8 | void ISR_Int0 (void) __interrupt IE0_VECTOR __using 0 { EA = 0 ;}
| 9 | void ISR_Timer0 (void) __interrupt TF0_VECTOR __using 0 { EA = 0 ;}
| 10 | void ISR_Int1 (void) __interrupt IE1_VECTOR __using 0 { EA = 0 ;}
| 11 | void ISR_Timer1 (void) __interrupt TF1_VECTOR __using 0 { EA = 0 ;}
| 12 | void ISR_Timer2 (void) __interrupt TF2_VECTOR __using 0 { EA = 0 ;}
| 13 | void ISR_UART (void) __interrupt SI0_VECTOR __using 0 { EA = 0 ;}
| 14 | void ISR_PCA (void) __interrupt PCA_VECTOR __using 0 { EA = 0 ;}
| 15 | void ISR_KBD (void) __interrupt KBD_VECTOR __using 1 ;
| 16 | void ISR_SPI (void) __interrupt SPI_VECTOR __using 0 { EA = 0 ;}
| 17 |
| 18 | //-----------------------------------------------------------------------------
| 19 |
| 20 | extern volatile __bit key_flag; // software flag
| 21 | extern unsigned char Keycode;
| 22 | unsigned char Spalte;
| 23 |
| 24 | //-----------------------------------------------------------------------------
| 25 |
| 26 | void ISR_KBD (void) __interrupt KBD_VECTOR __using 1 __naked {
| 27 | __asm
| 28 | push acc
| 29 | push psw
| 30 | mov psw, #0x08
| 31 | mov _KBE, #0b00000000
| 32 | mov a, _KBF
| 33 | jb acc.0, 00001$ // Zeile 1
| 34 | jb acc.1, 00002$ // Zeile 2
| 35 | jb acc.2, 00003$ // Zeile 3
| 36 | 00001$: // Zeile 1
| 37 | mov P1, #0b11111110
| 38 | mov _Keycode, #0x02
| 39 | sjmp 00004$
| 40 | 00002$: // Zeile 2
| 41 | mov P1, #0b11111101
| 42 | mov _Keycode, #0x04
| 43 | sjmp 00004$
| 44 | 00003$: // Zeile 3
| 45 | mov P1, #0b11111011
| 46 | mov _Keycode, #0x06
| 47 | sjmp 00004$
| 48 | 00004$: // FertigZeile
| 49 | acall 00005$
| 50 | sjmp 00008$
| 51 | 00005$: // Spaltentest
| 52 | mov a, P1
| 53 | cpl a
| 54 | anl a, #0b00011000
| 55 | swap a
| 56 | mov _Spalte,#0x01
| 57 | clr c
| 58 | 00006$: // Next Spalte
| 59 | rlc a
| 60 | jc 00007$
| 61 | dec _Keycode
| 62 | djnz _Spalte,00006$
| 63 | 00007$: // Break
| 64 | ret
| 65 | 00008$: // Finished
| 66 | mov P1, #0b00000111
| 67 | mov _KBF, #0b00000000
| 68 | mov _KBE, #0b00000111
| 69 | setb _key_flag
| 70 | pop psw
| 71 | pop acc
| 72 | reti
| 73 | __endasm;
| 74 | }
| 75 | //-----------------------------------------------------------------------------
|
Viel Spaß allen!
RABIS
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
|