Uart empfängt nur kryptische Zeichen - Fehler in der Programmierung

Gast #5601500
Lesenswert?

Hallo, ich habe ein Problem mit UART. Das Problem liegt aber mehr an der 
Programmierung. Zunächst hatte ich eine .c file, wo ich alle funktionen 
drinnen hatte. Jetzt wollte ich es so aufbauen, dass ich im Projekt 
einen Ordner mit einer uart.h und uart.c file generiere und im projekt 
selber die main.c und eine defines.h die übergreifend ist
Projekt:
 -uart:
    -uart.h
    -uart.c
  main.c
  defines.h


main.c:
1
#include "defines.h"
2
#include <avr/io.h>
3
#include <util/delay.h>
4
#include "uart/uart.h"
5

6

7
int main(void)
8
{
9
    uart_init(MYUBRR);
10
    while (1) 
11
    {
12
    uart_sendString("nice :) ");
13
    _delay_ms(1000);
14
    }
15
}

uart.c
1
#include "../defines.h"
2
#include <avr/io.h>
3
#include <util/delay.h>
4
#include "uart.h"
5

6

7

8

9
void uart_init(unsigned int ubrr)
10
{  
11
  /* Set baud rate */
12
  //UBRR0H = UBRR_VAL >> 8;
13
  //UBRR0L = UBRR_VAL & 0xFF;
14

15
  /* Enable receiver and transmitter */
16
  UCSR0B |= (1<<RXEN0)|(1<<TXEN0);
17

18
  /* Set frame format: 8data, 2stop bit */
19
  UCSR0C = (1<<USBS0)|(3<<UCSZ00);
20
}
21

22
/* Simple methods to make UART read and transmit more readble - Extremely unnecessary*/
23
void uart_transmit( unsigned char data )
24
{
25
  while(!(UCSR0A & (1<<UDRE0)));
26
  UDR0 = data;
27
}
28

29

30
unsigned char uart_receive( void )
31
{
32
  return UDR0;
33
}
34

35
void uart_sendString(char *StringPtr)
36
{
37
  
38
  while(*StringPtr != 0x00)
39
  {
40
    uart_transmit(*StringPtr);
41
    StringPtr++;
42
  }
43

44
}

uart.h
1
#ifndef UART_H_
2
#define UART_H_
3

4
void uart_init( unsigned int ubrr);
5
void uart_interruptOn(void);
6
void uart_transmit( unsigned char data );
7
unsigned char uart_receive( void );
8
void uart_sendString(char *StringPtr);
9

10
#endif /* UART_H_ */

defines.h
1
#ifndef DEFINES_H_
2
#define DEFINES_H_
3

4

5
#define F_CPU 16000000UL
6

7

8
/* UART Serial defines */
9
#define BAUD 9600UL
10
#define MYUBRR F_CPU/16/BAUD-1
11

12
/* Berechnung UART */
13
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
14
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
15
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
16

17
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
18
#error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
19
#endif
20

21

22

23
#endif /* DEFINES_H_ */

Wenn ich das Programm so laufen lasse, kommen allerdings nur kryptische 
Zeichen an. Das ist aber erst, nachdem ich es aufgesplittet habe. Wie 
gesagt, als alles in der main.c drinn war, hat es funktioniert. Wie kann 
ich den parameter "nice :) " übergeben, damit dieser richtig empfangen 
wird?

Jens
Gast #5601507
Lesenswert?

Vergleiche nochmal diese Berechnungen:

#define MYUBRR F_CPU/16/BAUD-1

/* Berechnung UART */
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden

Die beiden Ausdrücke ergeben nicht den selben Wert.
Gast #5601510
Lesenswert?

Karl M. schrieb:
> Hallo Jens,
>
> Der USART ist nicht initialisiert, damit ist den Problem klar.

Richtig.

  //UBRR0H = UBRR_VAL >> 8;
  //UBRR0L = UBRR_VAL & 0xFF;

ist unwirksam, weil auskommentiert. Und UBRR_VAL muss durch ubrr ersetzt 
werden.

Das kommt davon, wenn man so früh am Sonntag programmiert. Hast Du denn 
schon Kaffee getrunken?

> Im
> Empfangsfall fehlt das Prüfen, ob ein Zeichen überhaupt empfangen wurde.

Ja. Daran würde ich noch arbeiten.
Gast #5601523
Lesenswert?

Theor schrieb:
> Karl M. schrieb:
>> Hallo Jens,
>>
>> Der USART ist nicht initialisiert, damit ist den Problem klar.
>
> Richtig.
>
>   //UBRR0H = UBRR_VAL >> 8;
>   //UBRR0L = UBRR_VAL & 0xFF;
>
> ist unwirksam, weil auskommentiert.

mhh stimmt, dass hatte ich auskommentiert, da UBRR_VAL nicht bekannt 
war, bis ich die Berechnung der Baudrate ins defines.h gepackt habe. 
Wollte es eigentlich in der main.c lassen. Dann habe ich es vergessen 
wieder einzukommentieren.


Theor schrieb:
> Und UBRR_VAL muss durch ubrr ersetzt
> werden.

Das ist auf der TutorialSeite aber anders erklärt. Also dort ist es so, 
wie ich es gemacht habe (bzw. ich habe es so gemacht wie es dort ist).
https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Der_UART


Theor schrieb:
>> Im
>> Empfangsfall fehlt das Prüfen, ob ein Zeichen überhaupt empfangen wurde.
>
> Ja. Daran würde ich noch arbeiten.

Das käme jetzt als nächstes.

Danke schon einmal.
Beitrag #5601571 wurde von einem Moderator gelöscht.
Beitrag #5601573 wurde von einem Moderator gelöscht.
Beitrag #5601579 wurde von einem Moderator gelöscht.
Gast #5602011
Lesenswert?

@ Jens
@ Achim

Achim S. schrieb:
> Theor schrieb:
>> Die beiden Ausdrücke ergeben nicht den selben Wert.
>
> Abgesehen vom gerundeten LSB: ist da ein Überlauf, oder was ist anders?

Tja. Da hatte ich wohl selbst noch nicht genug Kaffee. :-)

Ich habe das einfach mathematisch betrachtet anstatt das 
Trunkierungsproblem bei float nach int Konvertierungen mit zu 
berücksichtigen, dass mir natürlich bekannt ist.

Mein Fehler. Tut mir leid, wenn ich Verwirrung gestiftet habe.

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