Hallo, ich habe folgendes Problem: Mein AtMega64 beliebt beim ausführen eines Unterprogramms vom Typ: void init_uart(void) hängen. Ich habe das Programm vorher auf einem AtMega16 laufen lassen ohne Probleme. Nun passte ich es an den AtMega64 an, in dem ich die UART-Register änderte. Ich habe auch die Ausführung des Unterprogramms durch das Anbinden einer LED getestet. D.H. er führt das Unterprogramm noch aus springt aber nicht zurück. Muss ich was mit dem Stackpointer wegen des großen Flash-speicher beachten?
>Muss ich was mit dem Stackpointer wegen des großen Flash-speicher >beachten? Was haben die beiden miteinander zu tun? Stimmt! Gar nichts! Ein (grossen) Stück Code zu posten, könnte helfen. Vielleicht sogar das konplette Programm...
#include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #define CONTROL_DIRECTION DDRA #define WRITE_CONTROL PORTA #define CTRL_DATA 2 // (RS) 1->Data 0->Control #define WR 3 // (W_R) 0-> zum Schreiben #define RD 4 // (E) 0-> zum LESEN #define CE 5 // (CS) 0-> Chip aktivieren #define Reset 6 // (RESET) 0-> Initialisierung wird ausgeführt #define WRITE_DATA PORTC #define READ_DATA PINC #define DATA_DIRECTION DDRC #define IN 0x00 #define OUT 0xFF unsigned char recieve_byte; unsigned char send_byte; void LCD_INIT(void); void LCD_READ_DATA(void); void LCD_WRITE_DATA(unsigned char dat); void LCD_WRITE_COMMAND(unsigned char cmd); void INIT_UART(void); void SEND_UART(void); void LCD_SET_PAGE(unsigned char site); void LCD_SET_COLUMN(unsigned char column); //Interrupts###################################### ISR(USART0_RX_vect) { recieve_byte = UDR0; LCD_SET_PAGE(0); LCD_SET_COLUMN(0); LCD_WRITE_DATA(recieve_byte); LCD_SET_PAGE(0); LCD_SET_COLUMN(0); LCD_READ_DATA(); SEND_UART(); } //################################################# //Hauptprogramm#################################### int main(void) { //INIT PORTS CONTROL_DIRECTION = OUT; //PortA als Ausgang WRITE_CONTROL = 0xFF; //Portzustand -> 0xFF DATA_DIRECTION = OUT; //Datenbus(PortC) als Ausgang WRITE_DATA = 0xFF; //Datenbuszustand -> 0xFF //INIT UART INIT_UART(); //UART Kontrolle send_byte = 0x00; //01011010 SEND_UART(); sei(); WRITE_CONTROL &= ~(1<<Reset); //löscht Reset _delay_ms(100); WRITE_CONTROL |= (1<<Reset); //setzt Reset int b,page; LCD_INIT(); for(page=0;page<16;page++) { LCD_SET_PAGE(page); LCD_SET_COLUMN(0); for(b=0;b<300;b++) { LCD_WRITE_DATA(0x00); _delay_ms(1); } _delay_ms(100); LCD_SET_PAGE(page); LCD_SET_COLUMN(0); LCD_WRITE_DATA(0x00); _delay_ms(1); LCD_WRITE_DATA(0x82); } _delay_ms(10000); PORTC=send_byte; SEND_UART(); int c; do { if(c>0x3F)c=0; LCD_WRITE_COMMAND(0x81); // Contrast set LCD_WRITE_COMMAND(c); // 0x00-0x3F ->2F ist gut _delay_ms(200); c++; } while(1); } void LCD_INIT(void) //S6B0741 { LCD_WRITE_COMMAND(0xE2); // Reset LCD_WRITE_COMMAND(0xAE); // display off LCD_WRITE_COMMAND(0xAB); // Osc on LCD_WRITE_COMMAND(0x67); // DC_DC LCD_WRITE_COMMAND(0x26); // Resistor ratio LCD_WRITE_COMMAND(0x81); // Contrast set LCD_WRITE_COMMAND(0x2F); // 0x00-0x3F ->2F ist gut LCD_WRITE_COMMAND(0x55); // LCD bias 1/10 LCD_WRITE_COMMAND(0x2f); // power cntrl LCD_WRITE_COMMAND(0xA1); // A0 SEG0 -> SEG127 || A1 SEG127 -> 0 LCD_WRITE_COMMAND(0xC0); // SHL LCD_WRITE_COMMAND(0x44); // Start Com LCD_WRITE_COMMAND(0x00); // value LCD_WRITE_COMMAND(0x40); // Start Line LCD_WRITE_COMMAND(0x00); // value LCD_WRITE_COMMAND(0xB0); // page adress LCD_WRITE_COMMAND(0x17); // Col Adr high LCD_WRITE_COMMAND(0x0F); // Col adress low LCD_WRITE_COMMAND(0xA6); // Displ Mode reverse LCD_WRITE_COMMAND(0xA2); // Icon LCD_WRITE_COMMAND(0xE1); // release Power save mode LCD_WRITE_COMMAND(0xE4); // release n-line inversion LCD_WRITE_COMMAND(0x93); // 15PWM 4FRC LCD_WRITE_COMMAND(0x8F); //Grauwerte LCD_WRITE_COMMAND(0x00); LCD_WRITE_COMMAND(0x89); LCD_WRITE_COMMAND(0x00); LCD_WRITE_COMMAND(0x8a); LCD_WRITE_COMMAND(0x77); LCD_WRITE_COMMAND(0x8b); LCD_WRITE_COMMAND(0x77); LCD_WRITE_COMMAND(0x8c); LCD_WRITE_COMMAND(0xAA); LCD_WRITE_COMMAND(0x8d); LCD_WRITE_COMMAND(0xaa); LCD_WRITE_COMMAND(0x8e); LCD_WRITE_COMMAND(0xff); LCD_WRITE_COMMAND(0x8f); LCD_WRITE_COMMAND(0xff); LCD_WRITE_COMMAND(0x4f); //n-line inversion LCD_WRITE_COMMAND(0x05); LCD_WRITE_COMMAND(0xAF); // display on } void LCD_WRITE_DATA(unsigned char dat) // Write data to the controller { DATA_DIRECTION = OUT; WRITE_CONTROL |= (1<<CTRL_DATA); //RS=1 ->Display-Daten 1->Data 0->Control WRITE_CONTROL &= ~(1<<CE); //CS=0; ->Bausteinfreigabe WRITE_CONTROL &= ~(1<<WR); //WR=0; ->Schreiben WRITE_DATA = dat; WRITE_CONTROL |= (1<<WR); //Daten werden in Displayspeicher übernommen WRITE_CONTROL |= (1<<CE); //CS=1; ->Baustein sperren } void LCD_WRITE_COMMAND(unsigned char cmd) // Write commands to the controller { DATA_DIRECTION = OUT; WRITE_CONTROL &= ~(1<<CTRL_DATA); //RS=0 ->Control-Daten 1->Data 0->Control WRITE_CONTROL &= ~(1<<CE); //CS=0 ->Bausteinfreigabe WRITE_CONTROL &= ~(1<<WR); //WR=0; ->Schreiben WRITE_DATA = cmd; WRITE_CONTROL |= (1<<WR); //Daten werden in Displayspeicher übernommen WRITE_CONTROL |= (1<<CE); //CS=1; ->Baustein sperren WRITE_CONTROL |= (1<<CTRL_DATA); //RS=1 ->Display-Daten 1->Data 0->Control } void LCD_READ_DATA(void) { DATA_DIRECTION = IN; WRITE_CONTROL |= (1<<CTRL_DATA); //RS=0 ->Control-Daten 1->Data 0->Control WRITE_CONTROL &= ~(1<<CE); //CS=0 ->Bausteinfreigabe WRITE_CONTROL &= ~(1<<RD); //WR=0; ->Schreiben WRITE_CONTROL |= (1<<RD); //Dummy WRITE_CONTROL &= ~(1<<RD); //WR=0; ->Schreiben send_byte = READ_DATA; WRITE_CONTROL |= (1<<RD); //Daten werden in Displayspeicher übernommen WRITE_CONTROL |= (1<<CE); //CS=1; ->Baustein sperren } void LCD_SET_PAGE(unsigned char site) { site = site + 0xB0; LCD_WRITE_COMMAND(site); } void LCD_SET_COLUMN(unsigned char column) { unsigned char column_msb = 0x10; unsigned char column_lsb = 0x00; if(bit_is_set(column,6)) column_msb = column_msb + 4; if(bit_is_set(column,5)) column_msb = column_msb + 2; if(bit_is_set(column,4)) column_msb = column_msb + 1; if(bit_is_set(column,3)) column_msb = column_lsb + 8; if(bit_is_set(column,2)) column_msb = column_lsb + 4; if(bit_is_set(column,1)) column_msb = column_lsb + 2; if(bit_is_set(column,0)) column_msb = column_lsb + 1; LCD_WRITE_COMMAND(column_msb); LCD_WRITE_COMMAND(column_lsb); } void SEND_UART(void) { loop_until_bit_is_set(UCSR0A,UDRE0); UDR0 = send_byte; } void INIT_UART(void) { //Bei 1MHz U2X=0->4800 U2X=1->9600 UBRR0L = 12; //Bei 8MHz U2X=0->19,2KB U2X=1->38,4KB UCSR0B = (1<<RXCIE0)|(1<<RXEN0)|(1<<TXEN0); UCSR0A = (1<<U2X0); }
Also führt den letzten Befehl im UP void INIT_UART(void) noch aus(letzte Zeile) springt aber nicht zurück. >>Muss ich was mit dem Stackpointer wegen des großen Flash-speicher >>beachten? >Was haben die beiden miteinander zu tun? Stimmt! Gar nichts! Speichert der Stackpointer keine Adresse vom Programmspeicher für den Rücksprunges aus einem UP?
Applikation: Ich steuere damit eine grafischen Controller vom Typ S6B0741 mit einenm Display von 128x128 an.
Lasse ich die Unterprogramme INIT_UART(); SEND_UART(); aus bleibt der AtMega64 im UP _delay_ms(100), hängen. Das UP sei() wir noch ausgeführt. Was könnte das sein da vorher das Programm auf einem AtMega16 ohne Fehler ausgeführt wurde?
Mit welcher Taktfrequenz läuft der µC? Die _delay_xx-Funktionen aus der util.h können nur eine begrenzte Verzögerungszeit. Für die _delay_ms()-Funktion gilt: Maximale Verzögerungszeit = 262.14 ms / F_CPU in MHz. _delay_ms(100) geht mit Taktfrequenzen über 2,6 MHz nicht mehr...
2Mhz ist mein Takt. Ich habe meinen Fehler gefunden. -> DER µC WAR DEFEKT. Obwohl er noch von meiner Seite aus jungfräulich war. Ich glaube ich muss meinen Arbeitsplatz ESD/EGB entsprechend einrichten;) Danke trotzdem.
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.