Forum: Mikrocontroller und Digitale Elektronik Problem bei umstellung von ATMega32 auf ATMega644


von Tobias (Gast)


Lesenswert?

Hallo,
ich hatte bisher auf einem ATMega32 programmiert auf dem ich unter 
anderem einen OC Ausgang betrieben habe:
1
TCCR2 = (1 << CS22);  //Timer2 auf FCPU/64 einstellen
2
TCCR2 |= (1 << WGM21); // CTC Modus (Timer2 wird bei erreichen von OCR2 zurück gesetzt
3
OCR2 = 108; //Compare Match alle 1/4048Hz
4
TCCR2 |= (1 << COM20)
5
TIMSK |= (1<<TOIE2);    //Timer2 wird aktiviert
da ich nun zwecks Platzproblemen auf einen Pinkompatiblen ATMega644 
umgestiegen bin, musste ich einige Register anpassen. Aus dem obigen 
Code ist folgender geworden:
1
TCCR2A = (1 << CS22);  //Timer2 auf FCPU/64 einstellen
2
TCCR2A |= (1 << WGM21); // CTC Modus (Timer2 wird bei erreichen von OCR2 zurück gesetzt
3
OCR2A = 108; //Compare Match alle 1/4048Hz
4
TCCR2A |= (1 << COM2A0)
5
TIMSK2 |= (1<<TOIE2);    //Timer2 wird aktiviert

nur leider passiert beim 644 gar nichts. Ich sehe auch in den 
Datenblätter keine Gründe warum das nicht funktionieren sollte.

von Bensch (Gast)


Lesenswert?

Es gibt eine Migration Note AVR505 von Atmel

von Tobias (Gast)


Lesenswert?

dem Dokument zufolge müsste es funktionieren :/

von holger (Gast)


Lesenswert?

TCCR2A = (1 << CS22);  //Timer2 auf FCPU/64 einstellen

CS22 gibt es nur in TCCR2B

von Oliver (Gast)


Lesenswert?

>dem Dokument zufolge müsste es funktionieren :/

Nö. Ein Register ist falsch.

644er Datenblatt öffnen, per mit Textsuche alle Konfigurationsbits 
suchen, und nachschauen, in welchem Register die stecken. Am einfachsten 
in Kapitel 29 "register summary".

Oliver

von Tobias (Gast)


Lesenswert?

Hallo nochmals,
leider sind die Probleme noch nicht gelöst. Die verwendeten Timer 
funktionieren nun auch auf dem 644, aber was ich nicht zum laufen kriege 
ist die USART Schnittstelle.

Initialisierung ATMega32:
1
  UBRRH = UBRR_VAL >> 8;
2
  UBRRL = UBRR_VAL & 0xFF;
3
   
4
  UCSRB = (1<<RXEN)|(1<<TXEN)| (1 << RXCIE);      //UART TX einschalten
5
  UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);      //8 data, 2 stop bits
ATmega 644:
1
  UBRR0H = UBRR_VAL >> 8;
2
  UBRR0L = UBRR_VAL & 0xFF;
3
   
4
  UCSR0A = 0;
5
  UCSR0B = (1<<RXEN0)|(1<<TXEN0)| (1 << RXCIE0);      //UART TX einschalten
6
  UCSR0C = (1<<USBS0)|(3<<UCSZ00);      //8 data, 2 stop bits

Der Interrupt wird bei Empfang einer Botschaft ausgelöst und er springt 
in die Funktion in der ich die Bytes einer Botschaft weiter bearbeite, 
allerdings scheinen die Bytes nicht korrekt gelesen zu werden, da 
bereits das Startbyte im ATMega644 nicht erkannt wird (funktioniert im 
ATMega32 alles problemlos
ATMega32:
1
void ProcessRXByte(void){
2
3
uint8_t RX_Byte = RXB;
4
5
  if ((RX_Byte == 170) && (ReadingFrame == 0)){
6
//Startbyte
7
    RS_CRC_SUM = 0;
8
    ReadingFrame = 1;
9
    RS_Frame_len = 0;
10
11
  }
12
  else if (ReadingFrame == 1) {
13
    if (RS_Frame_len == 0) {      // Zweites Byte = Länge und Adresse
14
      if ((RX_Byte & 7) != HOME_ADDR){
15
        ReadingFrame = 0;
16
        return;
17
    }
18
      RS_data_len = ((RX_Byte >> 3) & 0x1F);
19
      RS_Frame_len = RS_data_len + 3;
20
    }
21
    else if ((RS_Frame_len - RS_data_len) == 2) {    // Drittes Byte = Identifier
22
      RS_Identifier = RX_Byte;
23
    }
24
    else if (RS_Frame_len == 1) {    // CRC Byte
25
26
      RS_CRC = RX_Byte;
27
      ReadingFrame = 0;
28
      if ((RS_CRC_SUM % 256) == RS_CRC) {
29
        pfunc = Botschaftsliste[RS_Identifier];
30
        LastMsgContact = 0;
31
        (*pfunc)();    //Funktion entsprechend des Identifiers aufrufen
32
      }
33
      else {    // CRC-Prüfung nicht bestanden
34
        fcn_crc_error();
35
      }
36
37
    }
38
    else {  // Datenbytes
39
      RS_DataBuffer[RS_data_len + 1 - RS_Frame_len] = RX_Byte;
40
    }
41
    RS_CRC_SUM += RX_Byte;
42
    RS_Frame_len--;
43
  }
44
}
ATMega644:
1
void ProcessRXByte(void){
2
3
uint8_t RX_Byte = RXB;
4
5
  if ((RX_Byte == 170) && (ReadingFrame == 0)){
6
//Startbyte
7
                SET_LED_USR1;   // LED geht an zu zeigen dass ein Startbyte erkannt wurde
8
    RS_CRC_SUM = 0;
9
    ReadingFrame = 1;
10
    RS_Frame_len = 0;
11
12
  }
13
  else if (ReadingFrame == 1) {
14
    if (RS_Frame_len == 0) {      // Zweites Byte = Länge und Adresse
15
      if ((RX_Byte & 7) != HOME_ADDR){
16
        ReadingFrame = 0;
17
        return;
18
    }
19
      RS_data_len = ((RX_Byte >> 3) & 0x1F);
20
      RS_Frame_len = RS_data_len + 3;
21
    }
22
    else if ((RS_Frame_len - RS_data_len) == 2) {    // Drittes Byte = Identifier
23
      RS_Identifier = RX_Byte;
24
    }
25
    else if (RS_Frame_len == 1) {    // CRC Byte
26
27
      RS_CRC = RX_Byte;
28
      ReadingFrame = 0;
29
      if ((RS_CRC_SUM % 256) == RS_CRC) {
30
        pfunc = Botschaftsliste[RS_Identifier];
31
        LastMsgContact = 0;
32
        (*pfunc)();    //Funktion entsprechend des Identifiers aufrufen
33
      }
34
      else {    // CRC-Prüfung nicht bestanden
35
        fcn_crc_error();
36
      }
37
38
    }
39
    else {  // Datenbytes
40
      RS_DataBuffer[RS_data_len + 1 - RS_Frame_len] = RX_Byte;
41
    }
42
    RS_CRC_SUM += RX_Byte;
43
    RS_Frame_len--;
44
  }
45
}

Hoffe auf Hilfe.

Danke

von Tobias (Gast)


Lesenswert?

ich merk grad, die beiden Funktionen sind ja identisch. Sollten sie ja 
auch sein. Also sind die Unterschiede nur in der Initialisierung (und 
beim Senden, was im Moment aber noch zweitrangig ist solang die 
Botschaften noch nichtmal gelesen werden können).

von Tobias (Gast)


Lesenswert?

Berechnung von UBBR_VAL bei beiden µC identisch:
1
#define F_CPU 14745600L 
2
#define BAUD 115200L
3
4
#define UBRR_VAL ((F_CPU+BAUD * 8)/(BAUD*16)-1)      //clever runde
5
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))         //reale Baudrate

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
Noch kein Account? Hier anmelden.