Forum: Compiler & IDEs atmega128 receive uart0 funktioniert nicht


von lisa (Gast)


Lesenswert?

hallo,

ich möchte mit atmega128 ein "start" vom PC1 durch USRT0 empfangen und 
es durch USART1 an PC2 senden.

ich habe eine serielle schnittstelle mit interrupt programme von peter 
fleury genohmen und es für meinem Atgemeag8 angepasst und getestet 
soweit lauft alles super.
 - leider beim versuch mit atmega128,
werden keine interrupts behandelt .... ???

auch wenn ich den block

SIGNAL(__vector_default)
{
    // user code here z.b. led on
}

einbaue geschieht nichts obwohl die serielle schnittstelle funktioniert
(ohne interrupt und auch im polling-betrieb, ggf. auch ohne die ganzen 
buffer --> schon getestet)

was kann das sein (stack.fuse bits ) ???

hier unten den Code

danke
1
#include <stdlib.h>
2
#include <avr/io.h>
3
#include <util/delay.h>
4
#include <avr/interrupt.h>
5
#include <inttypes.h>
6
#include <string.h>
7
8
#define LENGTH 15
9
10
#ifndef F_CPU
11
#warning "F_CPU was not defined yet, now make up with 4000000"
12
#define F_CPU 4000000L   // Systemtakt in Hz
13
#endif
14
15
16
#define BAUD 9600L
17
#define UBRR_VAL ((F_CPU+BAUD * 8)/(BAUD*16)-1)     //clever round
18
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))         //real baud rate
19
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000)     //Error per thousand
20
21
22
#if ((BAUD_ERROR>10)||(BAUD_ERROR<-10))
23
#error Systematic error in the baud rate more than 1% and thus too high!
24
#endif
25
26
27
//  constants and macros
28
/* size of RX/TX buffers */
29
#define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1)
30
#define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1)
31
32
#if ( UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK )
33
#error RX buffer size is not a power of 2
34
#endif
35
#if ( UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK )
36
#error TX buffer size is not a power of 2
37
#endif
38
39
/** Size of the circular receive buffer, must be power of 2 */
40
#ifndef UART_RX_BUFFER_SIZE
41
#define UART_RX_BUFFER_SIZE 32
42
#endif
43
/** Size of the circular transmit buffer, must be power of 2 */
44
#ifndef UART_TX_BUFFER_SIZE
45
#define UART_TX_BUFFER_SIZE 32
46
#endif
47
48
/* test if the size of the circular buffers fits into SRAM */
49
#if ( (UART_RX_BUFFER_SIZE+UART_TX_BUFFER_SIZE) >= (RAMEND-0x60 ) )
50
#error "size of UART_RX_BUFFER_SIZE + UART_TX_BUFFER_SIZE larger than size of SRAM"
51
#endif
52
53
/* 
54
** high byte error return code of uart_getc()
55
*/
56
#define UART_FRAME_ERROR      0x0800              // Framing Error by UART
57
#define UART_OVERRUN_ERROR    0x0400              // Overrun condition by UART
58
#define UART_BUFFER_OVERFLOW  0x0200              // receive ringbuffer overflow
59
#define UART_NO_DATA          0x0100              // no receive data available
60
61
62
63
// ATmega with two USART
64
 #define ATMEGA_USART0
65
 #define ATMEGA_USART1
66
 #define UART0_RECEIVE_INTERRUPT   SIG_UART0_RECV
67
 #define UART1_RECEIVE_INTERRUPT   SIG_UART1_RECV
68
 #define UART0_TRANSMIT_INTERRUPT  SIG_UART0_DATA
69
 #define UART1_TRANSMIT_INTERRUPT  SIG_UART1_DATA
70
71
 #define UART0_STATUS   UCSR0A
72
 #define UART0_CONTROL  UCSR0B
73
 #define UART0_DATA     UDR0
74
 #define UART0_UDRIE    UDRIE0
75
76
 #define UART1_STATUS   UCSR1A
77
 #define UART1_CONTROL  UCSR1B
78
 #define UART1_DATA     UDR1
79
 #define UART1_UDRIE    UDRIE1
80
81
82
//module global variables
83
84
//ATMEGA_USART0
85
static volatile unsigned char UART0_TxBuf[UART_TX_BUFFER_SIZE];
86
static volatile unsigned char UART0_RxBuf[UART_RX_BUFFER_SIZE];
87
static volatile unsigned char UART0_TxHead;
88
static volatile unsigned char UART0_TxTail;
89
static volatile unsigned char UART0_RxHead;
90
static volatile unsigned char UART0_RxTail;
91
static volatile unsigned char UART0_LastRxError;
92
93
//ATMEGA_USART1
94
static volatile unsigned char UART1_TxBuf[UART_TX_BUFFER_SIZE];
95
static volatile unsigned char UART1_RxBuf[UART_RX_BUFFER_SIZE];
96
static volatile unsigned char UART1_TxHead;
97
static volatile unsigned char UART1_TxTail;
98
static volatile unsigned char UART1_RxHead;
99
static volatile unsigned char UART1_RxTail;
100
static volatile unsigned char UART1_LastRxError;
101
102
103
104
SIGNAL(UART0_RECEIVE_INTERRUPT)
105
/*************************************************************************
106
Function: UART Receive Complete interrupt
107
Purpose:  called when the UART has received a character
108
**************************************************************************/
109
{
110
    unsigned char tmphead;
111
    unsigned char data;
112
    unsigned char usr;
113
    unsigned char lastRxError;
114
 
115
 
116
    // read UART status register and UART data register
117
    usr  = UART0_STATUS;
118
    data = UART0_DATA;
119
    
120
    // defined( ATMEGA_USART0 )
121
    lastRxError = (usr & (_BV(FE0)|_BV(DOR0)) );
122
        
123
    // calculate buffer index
124
    tmphead = ( UART0_RxHead + 1) & UART_RX_BUFFER_MASK;
125
    
126
    if ( tmphead == UART0_RxTail )
127
        // error: receive buffer overflow
128
        lastRxError = UART_BUFFER_OVERFLOW >> 8;
129
130
    else
131
  {
132
        // store new index
133
        UART0_RxHead = tmphead;
134
        // store received data in buffer
135
        UART0_RxBuf[tmphead] = data;
136
    }
137
138
    UART0_LastRxError = lastRxError;   
139
}
140
141
142
SIGNAL(UART0_TRANSMIT_INTERRUPT)
143
/*************************************************************************
144
Function: UART Data Register Empty interrupt
145
Purpose:  called when the UART is ready to transmit the next byte
146
**************************************************************************/
147
{
148
    unsigned char tmptail;
149
150
    
151
    if ( UART0_TxHead != UART0_TxTail)
152
  {
153
        // calculate and store new buffer index
154
        tmptail = (UART0_TxTail + 1) & UART_TX_BUFFER_MASK;
155
        UART0_TxTail = tmptail;
156
        // get one byte from buffer and write it to UART
157
        UART0_DATA = UART0_TxBuf[tmptail];  // start transmission
158
    }
159
  else
160
        // tx buffer empty, disable UDRE interrupt
161
        UART0_CONTROL &= ~_BV(UART0_UDRIE);
162
}
163
164
165
/*************************************************************************
166
Function: uart0_init()
167
Purpose:  initialize UART and set baudrate
168
Input:    baudrate using macro UART_BAUD_SELECT()
169
Returns:  none
170
**************************************************************************/
171
void uart0_init(void)
172
{
173
    UART0_TxHead = 0;
174
    UART0_TxTail = 0;
175
    UART0_RxHead = 0;
176
    UART0_RxTail = 0;
177
    
178
179
    
180
  //defined (ATMEGA_USART0 )
181
    
182
    UBRR0H = (unsigned char)(UBRR_VAL>>8);
183
    UBRR0L = (unsigned char) UBRR_VAL;
184
185
    // Enable USART receiver and transmitter and receive complete interrupt
186
    UART0_CONTROL = _BV(RXCIE0)|(1<<RXEN0)|(1<<TXEN0);
187
    
188
    // Set frame format: asynchronous, 8data, no parity, 1stop bit
189
    #ifdef URSEL0
190
    UCSR0C = (1<<URSEL0)| (1<<UCSZ01)|(1<<UCSZ00);
191
    #else
192
    UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
193
    #endif 
194
195
}// uart_init
196
197
198
/*************************************************************************
199
Function: uart0_getc()
200
Purpose:  return byte from ringbuffer  
201
Returns:  lower byte:  received byte from ringbuffer
202
          higher byte: last receive error
203
**************************************************************************/
204
unsigned char uart0_getc(void)
205
{    
206
    unsigned char tmptail;
207
    unsigned char data;
208
209
210
    if ( UART0_RxHead == UART0_RxTail ) {
211
        return (unsigned char) UART_NO_DATA;   // no data available
212
    }
213
    
214
    // calculate /store buffer index
215
    tmptail = (UART0_RxTail + 1) & UART_RX_BUFFER_MASK;
216
    UART0_RxTail = tmptail; 
217
    
218
    // get data from receive buffer
219
    data = UART0_RxBuf[tmptail];
220
    
221
    return (UART0_LastRxError << 8) + data;
222
223
}// uart_getc
224
225
/*************************************************************************
226
Function: uart0_gets()
227
Purpose:  function which receive a String Through usart
228
Returns:  lower byte:  received byte from ringbuffer
229
          higher byte: last receive error
230
**************************************************************************/
231
void uart0_gets (char* string, unsigned int Length)
232
{
233
  uint8_t i;
234
    char c;
235
    char* s;
236
    
237
    s=string;
238
    i=0;
239
    do
240
    {
241
      c=uart0_getc();    
242
      if (c!='\r') 
243
       {
244
          *s=c;    
245
        s++;
246
        i++;
247
       }       
248
    }
249
    while( i!=Length && c!='\r');  
250
    *s = '\0';
251
  
252
}//end UART_Gets
253
254
255
/*************************************************************************
256
Function: uart_putc()
257
Purpose:  write byte to ringbuffer for transmitting via UART
258
Input:    byte to be transmitted
259
Returns:  none          
260
**************************************************************************/
261
void uart0_putc(unsigned char data)
262
{
263
    unsigned char tmphead;
264
265
    // calculate /store buffer index
266
    tmphead  = (UART0_TxHead + 1) & UART_TX_BUFFER_MASK;
267
    
268
    while ( tmphead == UART0_TxTail ){
269
        ;// wait for free space in buffer
270
    }
271
    
272
    UART0_TxBuf[tmphead] = data;
273
    UART0_TxHead = tmphead;
274
275
    // enable UDRE interrupt
276
    UART0_CONTROL    |= _BV(UART0_UDRIE);
277
278
}// uart_putc
279
280
/*void USART_Putc(unsigned char c)
281
{
282
    while (!(UCSRA & (1<<UDRE))); // Do nothing until data have been transmited 
283
    
284
  UDR = c;                      // Put data into Buffer, sends the data
285
  _delay_ms(10);   
286
}//end USART_Putc()*/
287
/*************************************************************************
288
Function: uart_puts()
289
Purpose:  transmit string to UART
290
Input:    string to be transmitted
291
Returns:  none          
292
**************************************************************************/
293
void uart0_puts(char *s )
294
{
295
    while (*s != '\0' ) 
296
      uart0_putc(*s++);
297
298
}// uart_puts
299
300
301
/*************************************************************************
302
Function: uart_puts_p()
303
Purpose:  transmit string from program memory to UART
304
Input:    program memory string to be transmitted
305
Returns:  none
306
**************************************************************************/
307
void uart0_puts_p(const char *progmem_s )
308
{
309
    register char c;
310
    
311
    while ( (c = pgm_read_byte(progmem_s++)) ) 
312
      uart0_putc(c);
313
314
}//uart_puts_p
315
316
317
/*
318
 * these functions are only for ATMEGA_USART1
319
 */
320
321
SIGNAL(UART1_RECEIVE_INTERRUPT)
322
/*************************************************************************
323
Function: UART1 Receive Complete interrupt
324
Purpose:  called when the UART1 has received a character
325
**************************************************************************/
326
{
327
    unsigned char tmphead;
328
    unsigned char data;
329
    unsigned char usr;
330
    unsigned char lastRxError;
331
332
 
333
    /* read UART status register and UART data register */ 
334
    usr  = UART1_STATUS;
335
    data = UART1_DATA;
336
    
337
    /* */
338
    lastRxError = (usr & (_BV(FE1)|_BV(DOR1)) );
339
        
340
    /* calculate buffer index */ 
341
    tmphead = ( UART1_RxHead + 1) & UART_RX_BUFFER_MASK;
342
    
343
    if ( tmphead == UART1_RxTail )
344
        /* error: receive buffer overflow */
345
        lastRxError = UART_BUFFER_OVERFLOW >> 8;
346
    
347
  else
348
  {
349
        /* store new index */
350
        UART1_RxHead = tmphead;
351
        /* store received data in buffer */
352
        UART1_RxBuf[tmphead] = data;
353
    }
354
355
    UART1_LastRxError = lastRxError;   
356
}
357
358
359
SIGNAL(UART1_TRANSMIT_INTERRUPT)
360
/*************************************************************************
361
Function: UART1 Data Register Empty interrupt
362
Purpose:  called when the UART1 is ready to transmit the next byte
363
**************************************************************************/
364
{
365
    unsigned char tmptail;
366
367
    
368
    if ( UART1_TxHead != UART1_TxTail)
369
  {
370
        /* calculate and store new buffer index */
371
        tmptail = (UART1_TxTail + 1) & UART_TX_BUFFER_MASK;
372
        UART1_TxTail = tmptail;
373
        /* get one byte from buffer and write it to UART */
374
        UART1_DATA = UART1_TxBuf[tmptail];  /* start transmission */
375
    }
376
  else
377
    /* tx buffer empty, disable UDRE interrupt */
378
        UART1_CONTROL &= ~_BV(UART1_UDRIE);
379
}
380
381
382
/*************************************************************************
383
Function: uart1_init()
384
Purpose:  initialize UART1 and set baudrate
385
Input:    baudrate using macro UART_BAUD_SELECT()
386
Returns:  none
387
**************************************************************************/
388
void uart1_init()
389
{
390
    UART1_TxHead = 0;
391
    UART1_TxTail = 0;
392
    UART1_RxHead = 0;
393
    UART1_RxTail = 0;
394
    
395
396
    UBRR1H = (unsigned char)(UBRR_VAL>>8);
397
    UBRR1L = (unsigned char) UBRR_VAL;
398
399
    // Enable USART receiver and transmitter and receive complete interrupt
400
    UART1_CONTROL = _BV(RXCIE1)|(1<<RXEN1)|(1<<TXEN1);
401
    
402
    // Set frame format: asynchronous, 8data, no parity, 1stop bit   
403
    #ifdef URSEL1
404
    UCSR1C = (1<<URSEL1)|(3<<UCSZ10);
405
    #else
406
    UCSR1C = (3<<UCSZ10);
407
    #endif 
408
  
409
}// uart_init
410
411
412
/*************************************************************************
413
Function: uart1_getc()
414
Purpose:  return byte from ringbuffer  
415
Returns:  lower byte:  received byte from ringbuffer
416
          higher byte: last receive error
417
**************************************************************************/
418
unsigned char uart1_getc(void)
419
{    
420
    unsigned char tmptail;
421
    unsigned char data;
422
423
424
    if ( UART1_RxHead == UART1_RxTail ) {
425
        return (unsigned char) UART_NO_DATA;   // no data available
426
    }
427
    
428
    // calculate /store buffer index
429
    tmptail = (UART1_RxTail + 1) & UART_RX_BUFFER_MASK;
430
    UART1_RxTail = tmptail; 
431
    
432
    // get data from receive buffer
433
    data = UART1_RxBuf[tmptail];
434
    
435
    return (UART1_LastRxError << 8) + data;
436
437
}// uart1_getc
438
439
/*************************************************************************
440
Function: uart1_gets()
441
Purpose:  function which receive a String Through usart
442
Returns:  lower byte:  received byte from ringbuffer
443
          higher byte: last receive error
444
**************************************************************************/
445
void uart1_gets (char* string, unsigned int Length)
446
{
447
  uint8_t i;
448
    char c;
449
    char* s;
450
    
451
    s=string;
452
    i=0;
453
    do
454
    {
455
      c=uart1_getc();    
456
      if (c!='\r') 
457
       {
458
          *s=c;    
459
        s++;
460
        i++;
461
       }       
462
    }
463
    while( i!=Length && c!='\r');  
464
    *s = '\0';
465
  
466
}//end uart1_gets
467
468
/*************************************************************************
469
Function: uart1_putc()
470
Purpose:  write byte to ringbuffer for transmitting via UART
471
Input:    byte to be transmitted
472
Returns:  none          
473
**************************************************************************/
474
void uart1_putc(unsigned char data)
475
{
476
    unsigned char tmphead;
477
478
    
479
    tmphead  = (UART1_TxHead + 1) & UART_TX_BUFFER_MASK;
480
    
481
    while ( tmphead == UART1_TxTail ){
482
        ;// wait for free space in buffer
483
    }
484
    
485
    UART1_TxBuf[tmphead] = data;
486
    UART1_TxHead = tmphead;
487
488
    // enable UDRE interrupt
489
    UART1_CONTROL    |= _BV(UART1_UDRIE);
490
491
}// uart1_putc
492
493
494
/*************************************************************************
495
Function: uart1_puts()
496
Purpose:  transmit string to UART1
497
Input:    string to be transmitted
498
Returns:  none          
499
**************************************************************************/
500
void uart1_puts(const char *s )
501
{
502
    while (*s) 
503
      uart1_putc(*s++);
504
505
}// uart1_puts
506
507
508
  
509
int main(void)
510
{
511
512
  DDRD = 0xFF;    // PORTD auf Eingang
513
  PORTD = 0xFF;   //Internal pull ups resistance for key inputs  PortD2 and portD3 was activated
514
515
  DDRC = 0xFF;       // outputs for LEDs
516
  PORTC = 0x00;      // LEDs off
517
518
  //  Initialize UART library, pass baudrate and AVR cpu clock with the macro
519
  uart0_init();  
520
  uart1_init();   
521
    
522
  // now enable interrupt, since UART library is interrupt controlled
523
  sei();
524
525
  char Command [LENGTH+1];
526
527
  for(;;)
528
  {
529
    PORTC = 0xAA;
530
    
531
    uart0_gets( Command, LENGTH );
532
    uart0_puts( Command );
533
    uart0_puts( "\r\n" );
534
        
535
536
      if(strcmp(Command, "start") == 0)
537
    {
538
          PORTC = 0xFA;
539
      for(int i=0; i<19; i++)
540
          uart1_puts("start");
541
      _delay_ms(10);
542
    }
543
      else if(strcmp(Command, "exit") == 0)
544
    {
545
          PORTC = 0xBA;
546
      for(int i=0; i<19; i++)
547
          uart1_puts("exit");
548
      _delay_ms(10);
549
      }
550
  }  
551
  return 0;
552
}

von Karl H. (kbuchegg)


Lesenswert?

lisa schrieb:

>  - leider beim versuch mit atmega128,
> werden keine interrupts behandelt .... ???

Wie hast du das festgestellt

    PORTC = 0xAA;

kannst du dieses Muster auf dem Port noch feststellen?

Ist das ein nagelneuer Mega128 oder hattest du den schon im Einsatz? Der 
Grund für die Nachfrage: Beim 128 gibt es eine ganz fiese Falle, die 
M103 Fuse. Dies sorgt dafür, dass sich ein nagelneuer M128 wie ein 103 
verhält. Bemerkbar macht sich das aber erst beim ersten Funktionsaufruf, 
der ganz grauslich in die Hose geht, weil der Stack anders liegt.


SIGNAL(UART0_RECEIVE_INTERRUPT)

Das solltest du gegen die neueren ISR Makros austauschen.

von lisa (Gast)


Lesenswert?

danke für die schnelle antwort.

>>>  - leider beim versuch mit atmega128,
>>> werden keine interrupts behandelt .... ???

>>Wie hast du das festgestellt
1
SIGNAL(__vector_default)
2
{
3
    // user code here z.b. led on
4
}

tut nichts

>> PORTC = 0xAA;

>>kannst du dieses Muster auf dem Port noch feststellen?
"Ja"

ohoh!!! habe vergessen zu sagen, dass ich den atmega128 auf dem 
OctopusUSB benutze.

>>Ist das ein nagelneuer Mega128 oder hattest du den schon im Einsatz?
ist ein nagelneuer Octopus --> Mega128
MFG

von Stefan E. (sternst)


Lesenswert?

lisa schrieb:

>>>Ist das ein nagelneuer Mega128 oder hattest du den schon im Einsatz?
> ist ein nagelneuer Octopus --> Mega128

Im Shop steht:
1
Der Octopus ist aktuell noch nicht programmiert wenn er ausgeliefert wird.

Also wird es die M103C-Fuse sein.

von Karl H. (kbuchegg)


Lesenswert?

Stefan Ernst schrieb:
> lisa schrieb:
>
>>>>Ist das ein nagelneuer Mega128 oder hattest du den schon im Einsatz?
>> ist ein nagelneuer Octopus --> Mega128
>
> Im Shop steht:
>
1
Der Octopus ist aktuell noch nicht programmiert wenn er
2
> ausgeliefert wird.
>
> Also wird es die M103C-Fuse sein.

Hmm.
Weiß nicht so recht.
er hat ein paar Funktionsaufrufe, ehe der Port C das 0xAA Muster 
einnimmt. Und das sieht er ja noch.

Auf jeden Fall: Mit einfacheren Tests anfangen. Code reduzieren. Um 
abzuklären ob die Interrupts kommen benötigt man keine Input-Queue etc.

von lisa (Gast)


Lesenswert?

>> Also wird es die M103C-Fuse sein.

M103C ein- oder ausgeschalten bringt keine Lösung.

So sind die Fuse bei mir eingestellt:
EXTENDED: FF
HIGH:FF
LOW:C3

von lisa (Gast)


Lesenswert?

ok ich versuche es
danke an alle
MFG

von Stefan E. (sternst)


Lesenswert?

Karl heinz Buchegger schrieb:
>> Also wird es die M103C-Fuse sein.
>
> Hmm.
> Weiß nicht so recht.
> er hat ein paar Funktionsaufrufe, ehe der Port C das 0xAA Muster
> einnimmt. Und das sieht er ja noch.

Inlining? ;-)

Dem Shop nach müsste es auf jeden Fall ein "druckfrischer" M128 
(gewesen) sein, denn dort wird beschrieben, was vor der eigentlichen 
Verwendung noch zu erledigen ist, und dort steht auch "Fuses 
programmieren".

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.