Forum: Mikrocontroller und Digitale Elektronik ATmega328P UART Problem mit uart_puts


von Micha C. (Gast)


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

von Stefan E. (sternst)


Lesenswert?

Beim Linken fehlt das -mmcu.

von Micha C. (Gast)


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

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.