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.
 Thread beobachten
 Thread beobachten Seitenaufteilung abschalten
 Seitenaufteilung abschalten