ATmega328P UART Problem mit uart_puts

Gast #2933965
Lesenswert?

Hallo,

ich habe ein Problem mit der seriellen Schnittstelle eines ATmega328P 
(Crumb328 mit integriertem USB-Wandler von chip45.com) und komme aktuell 
einfach nicht mehr weiter.

Anbei ein Testprogramm, welches auf dem AVR-Evalboard von Pollin mit 
einem ATmega8 (16 MHz) problemlos funktioniert. Auf dem ATmega328P (20 
MHz) werden nur Ausgaben von uart_putc korrekt ausgegeben. Versuche ich 
eine Ausgabe mit uart_puts gibt es überhaupt keine Ausgabe auf der 
seriellen Schnittstelle. Die LED blinkt in beiden Fällen.
1
#include <avr/io.h>
2

3
#include <util/delay.h>
4

5
#define SLEEP(VALUE)    _delay_ms(VALUE) 
6

7
#define LED_CONFIG( DDR, LED)   DDR |= (1<<(LED))
8
#define LED_ON( PORT, LED)  PORT |=  (1<<(LED))
9
#define LED_OFF( PORT, LED)  PORT &= ~(1<<(LED))
10
#define LED_TOGGLE( PORT, LED)  PORT ^=  (1<<(LED))
11

12
#define LED1_DDR DDRB
13
#define LED1_PORT PORTB
14
#define LED1 PB2
15

16
#if defined(__AVR_ATmega8__)
17

18
#define UART_MODE_8N1 (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0)
19

20
#define UBRR0H UBRRH
21
#define UBRR0L UBRRL
22
#define UCSR0A UCSRA
23
#define UCSR0B UCSRB
24
#define UCSR0C UCSRC
25
#define RXEN0 RXEN
26
#define TXEN0 TXEN
27
#define RXC0 RXC
28
#define UDR0 UDR
29
#define UDRE0 UDRE
30

31
#elif defined(__AVR_ATmega328P__)
32

33
#define UART_MODE_8N1 (1<<UCSZ01) | (1<<UCSZ00)
34

35
#endif
36

37
#define UART_BAUD_9600_16_MHZ 103
38
#define UART_BAUD_9600_20_MHZ 129
39

40

41
int uart_putc( char data)
42
{
43
  while( bit_is_clear( UCSR0A, UDRE0) );
44

45
  UDR0 = data;
46

47
  return 0;
48
}
49

50

51
int uart_puts( const char *data)
52
{
53
  uint16_t index = 0;
54

55
  while( data[index] != '\0') { 
56
    uart_putc( data[index]);
57
    index++;
58
  }
59

60
  return index;
61
}
62

63

64
int main( void)
65
{
66
  LED_CONFIG( LED1_DDR, LED1);
67
  
68
  LED_OFF( LED1_PORT, LED1);
69

70
  uint16_t ubbr = UART_BAUD_9600_20_MHZ;
71
  // uint16_t ubbr = UART_BAUD_9600_16_MHZ;
72

73
  // load uart parameter
74
  UBRR0H = (uint8_t) (ubbr>>8);
75
  UBRR0L = (uint8_t) ubbr;
76

77
  // enable receiver/transmitter
78
  UCSR0B |= (1<<RXEN0) | (1<<TXEN0);
79

80
  // set mode (8n1)
81
  UCSR0C |= UART_MODE_8N1;
82

83
  while( 1 ) { 
84
    uart_putc( 't');
85
    uart_putc( 'e');
86
    uart_putc( 's');
87
    uart_putc( 't');
88
    uart_putc( '\n');
89

90
    uart_puts( "TEST\n");
91

92
    SLEEP( 500);
93
    LED_TOGGLE( LED1_PORT, LED1);
94
  }
95

96
  return 0;
97
}

Das Testprogramm wird mit folgenden Aufrufen übersetzt und hochgeladen.
1
avr-gcc -O1 -Wall -mmcu=atmega328p -DF_CPU=20000000 -c uart_test_complete.c -o uart_test_complete.o
2
avr-gcc  uart_test_complete.o -o uart_test_complete.bin
3
avr-objcopy -j .text -j .data -O ihex uart_test_complete.bin uart_test_complete.hex
4
avrdude -P usb -c usbtiny -p m328p -U flash:w:uart_test_complete.hex

Folgende Fuses sind auf dem Crumb328 gesetzt.
1
avrdude -P usb -c usbtiny -p m328p -n -v
2

3
avrdude: Device signature = 0x1e950f
4
avrdude: safemode: lfuse reads as FF
5
avrdude: safemode: hfuse reads as D9
6
avrdude: safemode: efuse reads as 7

Ich bin dankbar für jeden Hinweis, mir sind leider die Ideen 
ausgegangen, was ich falsch gemacht habe.


Gruss

   Micha
Gast #2934004
Lesenswert?

Hallo Stefan,

> Beim Linken fehlt das -mmcu.
vielen vielen Dank, den Fehler hätte ich nie allein gefunden. Bislang 
habe ich ausschließlich mit dem Eval-Board von Pollin rumgespielt, da 
ist das Problem nie aufgetreten.


Gruss

    Micha

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren