Vielleicht kann mir jemand helfen. Stehe etwas auf dem Schlauch. Und zwar benutze ich die Tastenprell Routine aus dem Tutorial von Peter Dannegger. Funktioniert einwandfrei, nur wenn ich zu schnell die Tasten druecke, dann kommt mein LCD Display nicht mehr mit und zeigt nichts mehr an. Ich habe schon versucht, die Zeiten zu aendern, aber leider ohne Erfolg. Dies liegt wahrscheinlich daran, dass ich nicht weiss, ob ich die Zeiten von der Tastenabfrage aendern soll oder die Zeiten meiner LCD Routine. Die Tastenabfrage hab ich in der main Schleife drin(wie im Tutorial), nur benutze ich nicht den Overflowinterrupt sondern den Compareinterrupt, da ich eine Uhr parrallel dazu laufen habe. Mein Systemtakt liegt bei 4Mhz und der Overflow wird erreicht alle 10ms. Leider bin ich kein Profi und habe noch Schwierigkeiten mit dem einen oder anderen Problem. Daher hoffe ich, dass mir einer helfen kann. Gruss Daniel
Hab gerade gemerkt, dass auch bei langsamen schalten, eine Stoerung auftreten kann und dass Display nicht mehr funktioniert. Es scheint als ob sich irgenwie etwas zufaellig ueberlappt.
Nochmal ich. Vielleicht habe ich das Problem gefunden. Ich habe zwei Datenbits fuer das Display am Pin PC7 und PC6. Leider kann ich diese nicht mehr verschieben. Da in der Abfrage der Tastenentprellung der PINC geprueft wird koennte ich mir vorstellen, dass es da Konflikte gibt. Wie begrenze ich die Abfrage nur auf die Pins 0-3 i = key_state ^ ~KEY_PIN; #define KEY_PIN PINC Oder kann da es da kein Problem geben und es liegt doch an den Zeiten. Bitte helft mir.
Daniel wrote: > begrenze ich die Abfrage nur auf die Pins 0-3 > i = key_state ^ ~KEY_PIN; > #define KEY_PIN PINC > Da im Tastencode reine Abfragen des PIN Registers gemacht werden, sollte das kein Problem sein. Der Tasten Code führt dir 2 Pseudo Tasten mit, die sich etwas seltsam verhalten werden aber wenn du die Tasten nicht benutzt sollte das kein Problem darstellen. Welchen LCD Code benutzt du? Könnte es eventuell ein Problem mit dem Handling des DDR Registers sein? Was ich mal tun würde: Alle High-Level LCD Funktionen dahingehend bearbeiten, dass sie am Funktionsstart einen cli() und am Funktionsende einen sei() haben. Dann kann dir zumindest der Tasten-Interrupt nicht mehr in die LCD Funktionen reinspucken.
Hier mal meine LCD Routine. Wie gesagt, LCD_D6 und 7 sins als Pin PC6 und PC7 definiert. Wenn ich ein cli() und sei() in die LCD_data routine einsetze, dann resetet mein µC beim druecken der Taste. P.S. Die delay Zeiten musste ich aendern, sodass die Anzeige was anzeigt. #define LCD_D4 SBIT( PORTC, 7 ) #define LCD_DDR_D4 SBIT( DDRC, 7 ) #define LCD_D5 SBIT( PORTC, 6 ) #define LCD_DDR_D5 SBIT( DDRC, 6 ) #define LCD_D6 SBIT( PORTD, 2 ) #define LCD_DDR_D6 SBIT( DDRD, 2 ) #define LCD_D7 SBIT( PORTD, 3 ) #define LCD_DDR_D7 SBIT( DDRD, 3 ) #define LCD_RS SBIT( PORTD, 4 ) #define LCD_DDR_RS SBIT( DDRD, 4 ) #define LCD_E0 SBIT( PORTD, 5 ) #define LCD_DDR_E0 SBIT( DDRD, 5 ) void lcd_data( u8 d ) { LCD_RS = 1; lcd_byte( d ); } void lcd_nibble( u8 d ) { LCD_D4 = 0; if( d & 1<<4 ) LCD_D4 = 1; LCD_D5 = 0; if( d & 1<<5 ) LCD_D5 = 1; LCD_D6 = 0; if( d & 1<<6 ) LCD_D6 = 1; LCD_D7 = 0; if( d & 1<<7 ) LCD_D7 = 1; LCD_E0 = 1; _delay_us( 4 );//1 // 1us LCD_E0 = 0; } void lcd_byte( u8 d ) { lcd_nibble( d ); lcd_nibble( d<<4 ); _delay_us( 45 );//45 // 45us } void lcd_command( u8 d ) { LCD_RS = 0; lcd_byte( d ); switch( d ){ case 1: case 2: case 3: _delay_ms( 4 );//2 // wait 2ms } } void lcd_init( void ) { LCD_DDR_D4 = 1; LCD_DDR_D5 = 1; LCD_DDR_D6 = 1; LCD_DDR_D7 = 1; LCD_DDR_RS = 1; LCD_DDR_E0 = 1; LCD_E0 = 0; LCD_RS = 0; // send commands _delay_ms( 40 );//15 // wait 15ms lcd_nibble( 0x30 ); _delay_ms( 13 ); //5 // wait >4.1ms lcd_nibble( 0x30 ); _delay_us( 400 ); //100 // wait >100æs lcd_nibble( 0x30 ); // 8 bit mode _delay_us( 400 ); //100 // wait >100æs lcd_nibble( 0x20 ); // 4 bit mode _delay_us( 400 );//100 // wait >100æs lcd_command( 0x28 ); // 2 lines 5*7 lcd_command( 0x08 ); // display off lcd_command( 0x01 ); // display clear lcd_command( 0x06 ); // cursor increment lcd_command( 0x0C ); // on, no cursor, no blink } // setzt den Cursor in Zeile y (1..4) Spalte x (0..15) void set_cursor(uint8_t column, uint8_t line) { if( line & 1 ) column += 0x40; lcd_command( 0x80 + column ); } // Schreibt einen String auf das LCD void lcd_string(char *data) { while(*data) { lcd_data(*data); data++; } } Deine Routine wird im Compare Interrupt mit dieser Funktion abgefragt. void exe_keypad(void) { static unsigned char ct0, ct1, rpt; unsigned char i; //TCNT0 = (u8)(s16)-(XTAL / 1024 * 10e-3 + 0.5); // preload for 10ms i = key_state ^ ~KEY_PIN; // key changed ? ct0 = ~( ct0 & i ); // reset or count ct0 ct1 = ct0 ^ (ct1 & i); // reset or count ct1 i &= ct0 & ct1; // count until roll over ? key_state ^= i; // then toggle debounced state key_press |= key_state & i; // 0->1: key press detect if( (key_state & REPEAT_MASK) == 0 ) // check repeat function rpt = REPEAT_START; // start delay if( --rpt == 0 ){ rpt = REPEAT_NEXT; // repeat delay key_rpt |= key_state & REPEAT_MASK; } }
Lange Sachen immer als Anhang! Es ist auch völlig nutzlos, nur Fragmente zu posten. Insbesondere das main fehlt. Poste was compilierbares, was den Fehler enthält. Bei mehreren Files als ZIP. Peter
Ich hoffe du kannst mir irgendwie helfen. Dies ist so ungefaer mein erstes grosse Projekt. Daher ist es wahrscheinlich bei weitem nicht optimal. Aber vielleicht findest du das Problem. Ich bin naemlich schon am verzweifeln. Vielen Dank schon mal!!!!
Sorry, kleiner Fehler. LCD_routines wird nicht verwendet, ist aber in der ZIP Datei.
@Peter Hab wahrscheinlich an der falschen Stelle mein cli() gesetzt. Jetzt funktionierts. Danke aber vielmals!!!! Mit deiner Hilfe kann man immer rechnen
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.