Hallo zusammen,
ich bin gerade dabei mich in die Mikrocontrollerprogrammierung
hineinzuarbeiten und will mir gerade die Kommunikation zwischen µC und
PC beibringen, hab da aber ein kleines Problemchen. Benutzt wird ein
ATmega 328p im Arduino Uno.
Und zwar hab ich dieses Programm gefunden, was auch bestens
funktioniert, selbst wenn ich den _delay_ms auf z.B. 1ms stelle.
1 | #ifndef F_CPU
|
2 | #define F_CPU 16000000UL
|
3 | #endif
|
4 | #define BAUDRATE 9600
|
5 | #define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)
|
6 | #include <util/delay.h>
|
7 | #include <avr/io.h>
|
8 | #include <avr/interrupt.h>
|
9 |
|
10 | void USART_init(void);
|
11 | void USART_send( unsigned char data);
|
12 | void USART_putstring(char* StringPtr);
|
13 |
|
14 |
|
15 | int main(void)
|
16 | {
|
17 | char String[]="Hello world!!";
|
18 | USART_init();
|
19 |
|
20 | while(1){
|
21 | USART_putstring(String);
|
22 | _delay_ms(1000);
|
23 | }
|
24 | return 0;
|
25 | }
|
26 |
|
27 |
|
28 | void USART_send(unsigned char data)
|
29 | {
|
30 | while (!(UCSR0A & (1<<UDRE0)))
|
31 | {
|
32 | }
|
33 | UDR0= data;
|
34 |
|
35 | }
|
36 |
|
37 | void USART_putstring(char* StringPtr)
|
38 | {
|
39 | while(*StringPtr != 0x00)
|
40 | {
|
41 | USART_send(*StringPtr);
|
42 | StringPtr++;
|
43 | }
|
44 | }
|
45 |
|
46 | void USART_init(void)
|
47 | {
|
48 | UBRR0H = (uint8_t)(BAUD_PRESCALLER>>8);
|
49 | UBRR0L = (uint8_t)(BAUD_PRESCALLER);
|
50 | UCSR0B = (1<<TXEN0);
|
51 | UCSR0C = ((1<<UCSZ00)|(1<<UCSZ01));
|
52 | }
|
Funktioniert so weit so gut mir "Hello World" im Atmel Studio anzeigen
zu lassen.
Ich habe jetzt also versucht ohne das UART_putstring mir was ausgeben zu
lassen.
1 | #ifndef F_CPU
|
2 | #define F_CPU 16000000UL
|
3 | #endif
|
4 | #define BAUDRATE 9600
|
5 | #define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)
|
6 | #include <util/delay.h>
|
7 | #include <avr/io.h>
|
8 | #include <avr/interrupt.h>
|
9 |
|
10 | void USART_init(void);
|
11 | void USART_send( void);
|
12 | void USART_putstring(char* StringPtr);
|
13 |
|
14 |
|
15 | int main(void){
|
16 | USART_init();
|
17 | while(1)
|
18 | {
|
19 | USART_send();
|
20 | _delay_ms(1000);
|
21 | }
|
22 | return 0;
|
23 | }
|
24 |
|
25 |
|
26 | void USART_send(void)
|
27 | {
|
28 | while (!(UCSR0A & (1<<UDRE0)))
|
29 | {
|
30 | }
|
31 | UDR0='a';
|
32 | UDR0='b';
|
33 | UDR0='c';
|
34 | }
|
35 |
|
36 |
|
37 |
|
38 | void USART_init(void)
|
39 | {
|
40 | UBRR0H = (uint8_t)(BAUD_PRESCALLER>>8);
|
41 | UBRR0L = (uint8_t)(BAUD_PRESCALLER);
|
42 | UCSR0B = (1<<TXEN0);
|
43 | UCSR0C = ((1<<UCSZ00)|(1<<UCSZ01));
|
44 | }
|
Hier will ich quasi jedes Zeichen selber ausgeben ohne diese in eine
String zu verketten. Funktioniert fast. Als Ausgabe steht nämlich nur
"ab" da und das "c" fällt weg. Selbst mit einem _delay_ms(1) nach
UDR0='b' ist die Ausgabe weiterhin "ab". Bei einem delay von 10ms klappt
das Ganze dann wieder und es steht korrekt "abc" da. Es ist also klar,
dass es eine Timing Sache ist, aber warum genau weiß ich eben nicht. Bei
dem oberen Code und einem delay von 1ms in der main funktioniert es ja
eben doch....