Forum: Mikrocontroller und Digitale Elektronik UART ein Program auf Atmega32 leufts auf Atmega1284P nicht


von Mike B. (mike13579)


Lesenswert?

Hi

Ich habe hier einen Aufbau auf dem ich den Atmega stecken kann, somit 
immer die gleichen Voraussetzungen. Ich will einen Atmega1284P 
verwenden(habe bisher immer Atmega32 verwendet).

Nun wollte ich das Programm erstellen, da ich für den ATmega32 schon 
einmal den UART Baugleich verwendet hatte habe ich das Alte Programm als 
Basis genommen und die Register angepasst. Als ich das Testen wollte hat 
es nicht funktioniert. Um nun einen Fehler im Aufbau Ausschließen zu 
können Habe ich die selbe Formlage noch einmal genommen diesmal jedoch 
die Register gelassen und das Programm auf einen Atmega32 aufgespielt. 
Da hat es Sofort funktioniert.

Nun habe ich die Programme nebeneinander gelegt und miteinander 
verglichen.
Sie unterscheiden sich nur dadurch das ich beim einen nicht genutztes 
Gelöscht beim andren auskommentiert habe und durch die geäderten 
Register Bezeichnungen.

die Datenblätter habe ich auch nochmal durchgesehen und konnte nichts 
finden was ich meiner Meinung nach anders hätte machen müssen.

Das Programm soll das empfangene Zeichen wieder zurücksenden.

Atmega32
1
#include <avr/io.h>
2
#include <inttypes.h>
3
#include <stdlib.h>
4
#include <avr/interrupt.h>
5
#include <stdint.h> 
6
7
 
8
#define BAUD 9600
9
#include <util/setbaud.h>
10
11
12
///////////////////////////////////////////////////////////////////////////////////init uart
13
 
14
void uart_init(void)   
15
{
16
   UBRRH = UBRRH_VALUE;
17
   UBRRL = UBRRL_VALUE;
18
   /* evtl. verkuerzt falls Register aufeinanderfolgen (vgl. Datenblatt)
19
      UBRR = UBRR_VALUE;
20
   */
21
#if USE_2X
22
   /* U2X-Modus erforderlich */
23
   UCSRA |= (1 << U2X);
24
#else
25
   /* U2X-Modus nicht erforderlich */
26
   UCSRA &= ~(1 << U2X);
27
#endif
28
29
30
  UCSRC = (1<<URSEL)|(1 << UCSZ1)|(1 << UCSZ0); // Asynchron 8N1
31
  UCSRB |= (1<<RXEN)|(1<<TXEN);  // UART RX, TX einschalten
32
 
33
  
34
}
35
36
/////////////////////////////////////////////////////////////////var def 
37
38
39
  volatile unsigned char uart[256];  //buffer uart empfang
40
  volatile uint8_t r=0;     //lese zeiger
41
  volatile uint8_t w=0;    //schreib zeiger
42
  volatile unsigned char uarts[256];  //buffer uart senden
43
  volatile uint8_t rs=0;      //lese zeiger senden
44
  volatile uint8_t ws=0;    //schreib zeiger senden
45
  volatile uint8_t a=0x00;    //0x01 '#\n'empfangen,0x02 Tarix neu berechnen,
46
  volatile uint8_t CPU1=0x00;    //CPU1
47
  volatile uint8_t CPU2=0x00;    //CPU2
48
  volatile uint8_t CPU3=0x00;    //CPU3
49
  volatile uint8_t CPU4=0x00;    //CPU4
50
  volatile uint8_t X=0x00;    //LEDX
51
  volatile uint8_t XB[8]={0x01,0x02,0x04,0x08,0x00,0x00,0x00,0x00};    //LEDXPortB
52
  volatile uint8_t XD[8]={0x00,0x00,0x00,0x00,0x04,0x08,0x10,0x20};    //LEDXPortC
53
  volatile uint8_t XA[8];
54
  volatile uint8_t XC[8];  
55
  volatile uint8_t i=0;      //anzeige zeiger matrix
56
57
 
58
///////////////////////////////////////////////////////////////////////uart 
59
60
int uart_getc(void)
61
{
62
    while (!(UCSRA & (1<<RXC)))   // warten bis Zeichen verfuegbar
63
        ;
64
//unsigned char i= UDR;
65
  // uart[w] = i;
66
  // w++;
67
  // if (i == '\n')a |=0x01;
68
   return UDR;
69
}
70
71
72
int uart_putc(unsigned char c)
73
{
74
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
75
    {
76
    }                             
77
 
78
    UDR = c;                      /* sende Zeichen */
79
    return 0;
80
}
81
82
83
  
84
85
86
/////////////////////////////////////////////////////////////////main int
87
88
89
int main(void)
90
{
91
  uart_init();
92
  DDRA = 0x00;
93
  DDRB = 0x00;
94
  DDRC = 0xFF;
95
  DDRD = 0x00;
96
  PORTA = 0x00;
97
  PORTC = 0x00;
98
  PORTB = 0x00;
99
  PORTD = 0x00;
100
101
102
  
103
  
104
//////////////////////////////////////////////////////////////////main loop
105
 
106
 
107
  while (1) 
108
  {
109
110
   if ( (UCSRA & (1<<RXC)) )
111
    {
112
    i=uart_getc();//uart zeichen angekommen
113
    uart_putc(i);
114
    }
115
  }
116
  return 0; // never reached 
117
}


Atmega1284P
1
#include <avr/io.h>
2
#include <inttypes.h>
3
#include <stdlib.h>
4
#include <avr/interrupt.h>
5
#include <stdint.h> 
6
7
 
8
#define BAUD 9600
9
#include <util/setbaud.h>
10
11
12
///////////////////////////////////////////////////////////////////////////////////init uart
13
 
14
void uart_init(void)   
15
{
16
   UBRR0H = UBRRH_VALUE;
17
   UBRR0L = UBRRL_VALUE;
18
   /* evtl. verkuerzt falls Register aufeinanderfolgen (vgl. Datenblatt)
19
      UBRR = UBRR_VALUE;
20
   */
21
#if US0E_2X
22
   /* U2X-Modus erforderlich */
23
   UCSR0A |= (1 << U2X0);
24
#else
25
   /* U2X-Modus nicht erforderlich */
26
   UCSR0A &= ~(1 << U2X0);
27
#endif
28
29
30
  UCSR0C = (1<<UMSEL01)|(1 << UCSZ01)|(1 << UCSZ00); // Asynchron 8N1
31
  UCSR0B |= (1<<RXEN0)|(1<<TXEN0);  // UART RX, TX einschalten
32
 
33
  
34
}
35
36
/////////////////////////////////////////////////////////////////var def 
37
38
39
  volatile unsigned char uart[256];  //buffer uart empfang
40
  volatile uint8_t r=0;     //lese zeiger
41
  volatile uint8_t w=0;    //schreib zeiger
42
  volatile unsigned char uarts[256];  //buffer uart senden
43
  volatile uint8_t rs=0;      //lese zeiger senden
44
  volatile uint8_t ws=0;    //schreib zeiger senden
45
  volatile uint8_t a=0x00;    //0x01 '#\n'empfangen,0x02 Tarix neu berechnen,
46
  volatile uint8_t CPU1=0x00;    //CPU1
47
  volatile uint8_t CPU2=0x00;    //CPU2
48
  volatile uint8_t CPU3=0x00;    //CPU3
49
  volatile uint8_t CPU4=0x00;    //CPU4
50
  volatile uint8_t X=0x00;    //LEDX
51
  volatile uint8_t XB[8]={0x01,0x02,0x04,0x08,0x00,0x00,0x00,0x00};    //LEDXPortB
52
  volatile uint8_t XD[8]={0x00,0x00,0x00,0x00,0x04,0x08,0x10,0x20};    //LEDXPortC
53
  volatile uint8_t XA[8];
54
  volatile uint8_t XC[8];  
55
  volatile uint8_t i=0;      //anzeige zeiger matrix
56
57
 
58
///////////////////////////////////////////////////////////////////////uart 
59
60
int uart_getc(void)
61
{
62
    while (!(UCSR0A & (1<<RXC0)))   // warten bis Zeichen verfuegbar
63
        ;
64
//unsigned char i= UDR;
65
  // uart[w] = i;
66
   //w++;
67
  // if (i == '\n')a |=0x01;
68
   return UDR0;
69
}
70
71
72
int uart_putc(unsigned char c)
73
{
74
    while (!(UCSR0A & (1<<UDRE0)))  /* warten bis Senden moeglich */
75
    {
76
    }                             
77
 
78
    UDR0 = c;                      /* sende Zeichen */
79
    return 0;
80
}
81
82
83
  
84
85
86
/////////////////////////////////////////////////////////////////main int
87
88
89
int main(void)
90
{
91
  uart_init();
92
  DDRA = 0x00;
93
  DDRB = 0x00;
94
  DDRC = 0xFF;
95
  DDRD = 0x00;
96
  PORTA = 0x00;
97
  PORTC = 0x00;
98
  PORTB = 0x00;
99
  PORTD = 0x00;
100
101
  // Timer 1 konfigurieren
102
//  TCCR0 = (1<<WGM01); // CTC Modus
103
//  TCCR0 |= (1<<CS01); // Prescaler 8
104
//  TCCR0 |= (1<<CS00); // Prescaler 64 wen  TCCR0 |= (1<<CS01);0 
105
// (16000000/64/1600) = 156,25
106
// (16000000/8/408000) = 4,9
107
//  OCR0 = 156-1;
108
// Compare Interrupt erlauben
109
//  TIMSK |= (1<<OCIE0);
110
// Global Interrupts aktivieren// Global Interrupts aktivieren
111
112
//  sei();
113
  
114
  
115
//////////////////////////////////////////////////////////////////main loop
116
 
117
 
118
  while (1) 
119
  {
120
   
121
   if ( (UCSR0A & (1<<RXC0)) )
122
   {
123
   i=uart_getc();//uart zeichen angekommen
124
  PORTC=i;
125
   uart_putc(i);
126
  }
127
  }
128
  return 0; // never reached 
129
}
130
//time interupt
131
//ISR (TIMER0_COMP_vect)
132
//{
133
134
//}

Das Problem beim Atmega1284P Äußert sich dadurch das anstelle des 
gesendeten Zeichens ein "Leer" Zeichen zurück kommt. Um zu sehen ob da 
überhaupt was empfangen wird, habe ich mir was zeichne beim Atmega1284P 
auf Port C Anzeigen lassen, dieser ist mit 8 LEDs ausgestattet. Dabei 
ist mir Aufgefallen das wen ich das Gleiche Zeichen mehrfach sende die 
LEDs nicht immer das Gleiche anzeigen.

Zum Taktgeber ich verwende momentan ein 16MHz Quarzoszillator und habe 
in beiden Projekten 16MHz in der Konfiguration stehen später wollte ich 
auf 20MHz erhöhen.

die Variablen Bezeichnungen machen eigentlich keinen Sinn, sind noch 
nicht angepasst.

Kann mir jemand sagen was ich falsch mache. Ich möchte doch nur das, das 
gesendet Zeichen zurückkommt.

MFG MIKE

von Karl H. (kbuchegg)


Lesenswert?

Mike B. schrieb:

> Zum Taktgeber ich verwende momentan ein 16MHz Quarzoszillator

und ist der auch auf deinem 1284 aktiviert?
Anschliessen alleine ist zu wenig. Der muss auch per Fuse aktiviert 
werden.

: Bearbeitet durch User
von Mike B. (mike13579)


Lesenswert?

Sollte  so sein habe eben mal geschaut, das ist ausgewählt :

Ext. Crystal Osc. 8.0-    MHz; Start-up time: 16K CK + 65 ms

MFG MIKE

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Mike B. schrieb:
> Sollte  so sein habe eben mal geschaut, das ist ausgewählt :
>
> Ext. Crystal Osc. 8.0-    MHz; Start-up time: 16K CK + 65 ms


ok.
Ich würde das noch kontrollieren, deine 'Symptome' klingen ganz stark 
nach falscher Taktfrequenz.

Aber gut, wenn du sicher bist, dass der Takt passt, dann mach das als 
dein erstes Testprogramm
1
int main(void)
2
{
3
  uart_init();
4
5
  while (1) 
6
  {
7
    uart_putc( 'x' );
8
  }
9
}

und dann gehst du mal mit einer LED auf die Suche, ob am Tx Pin der 
UART0 was rauskommt und verfolgst es bis zur Gegenstelle.

von Stefan E. (sternst)


Lesenswert?

Mike B. schrieb:
> das Alte Programm als
> Basis genommen und die Register angepasst.

1
  UCSR0C = (1<<UMSEL01)|(1 << UCSZ01)|(1 << UCSZ00); // Asynchron 8N1
Nun, es wäre sinnvoll, sich beim Anpassen auch mal die Beschreibungen im 
Datenblatt zu Gemüte zu führen, und nicht nach dem Motto vorzugehen
"oh, der Mega1284 hat ja gar kein URSEL, dann nehme ich halt UMSEL, das 
klingt ja fast gleich".

von Mike B. (mike13579)


Lesenswert?

darauf wies klingt hab ich nicht geachtet fiel mehr darauf wo es stand.
gut das scheint auch keine gute Lösung gewesen zu sein.

es scheint es nicht zu geben aber mit weglassen funktioniert es auch 
nicht.
hat mir jemand ein Beispiel das funktioniert?

aktueller stand :
1
void uart_init(void)   
2
{
3
   
4
#if USE_2X
5
   /* U2X-Modus erforderlich */
6
   UCSR0A |= (1 << U2X0);
7
#else
8
   /* U2X-Modus nicht erforderlich */
9
   UCSR0A &= ~(1 << U2X0);
10
#endif
11
12
13
  UCSR0C = (1 << UCSZ01)|(1 << UCSZ00); 
14
  UCSR0B |= (1<<RXEN0)|(1<<TXEN0);  // UART RX, TX einschalten
15
 UBRR0 = UBRR_VALUE;
16
  
17
  
18
}
1
while (1) 
2
  {
3
    uart_putc( 'X' );
4
}

Das Ergebnis ist jedoch noch immer das selbe

von Stefan E. (sternst)


Lesenswert?

Mike B. schrieb:
> Sollte  so sein habe eben mal geschaut, das ist ausgewählt :
>
> Ext. Crystal Osc. 8.0-    MHz; Start-up time: 16K CK + 65 ms

Und was ist mit CKDIV8?

von Mike B. (mike13579)


Lesenswert?

CKDIV8 kante ich gar nicht, habe eben nachgelesen was das ist und die 
Fuses der Beiden Atmegas verglichen und festgesetzt das die sich 
unterscheiden.

Mit CKDIV8 aus und
Ext. Clock; Start-up time: 6 CK + 65 ms
funktioniert es

hab ich das richtig verstanden, wen CKDIV8 an ist habe ich einen 
Vorteiler von 8 und somit nur 2MHz anstelle von 16MHz ?

MFG MIKE

von Timmo H. (masterfx)


Lesenswert?

Ja

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.