Forum: Mikrocontroller und Digitale Elektronik USART AVR-GCC problem


von Paul F. (zwanzischmark)


Lesenswert?

Ich verzweifel an einer USART übertragung in C! Mit dem Bascom Programm 
funktioniert es ohne Probleme. Gleicher Controller mit dem C Programm 
funktioniert nicht. Ich habe mal mit dem Oszi mitgeloggt. Die Daten 
kommen raus, aber VIEL zu langsam (mehr als Faktor 10 zu langsam). Die 
Makefile sollte stimmen mit Taktfrequenz usw. es kann eigentlich nur an 
der Baudrate liegen, aber die Berechnung ist ja aus dem Turorial von 
hier. Hat jemand ne idee?
1
$regfile = "m32def.dat"
2
$crystal = 16000000
3
$baud = 9600
4
$hwstack = 32
5
$swstack = 10
6
$framesize = 40
7
8
Do
9
  Print "x"
10
  Waitms 500
11
Loop
12
13
End

1
#include <avr/io.h>
2
#include <util/delay.h>
3
 
4
#ifndef F_CPU
5
#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 16000000"
6
#define F_CPU 16000000UL    // Systemtakt in Hz
7
#endif
8
 
9
#define BAUD 9600UL          // Baudrate
10
 
11
// Berechnungen
12
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
13
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
14
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
15
 
16
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
17
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
18
#endif
19
20
void USART_Init(unsigned int baud) {
21
  /* Set baud rate */
22
  UBRRH = (unsigned char)(baud>>8);
23
  UBRRL = (unsigned char)baud;
24
  /* Enable receiver and transmitter */
25
  UCSRB = (1<<RXEN)|(1<<TXEN); 
26
  /* Set frame format: 8data, 1stop bit */
27
  UCSRC = (1<<UCSZ0)|(1<<UCSZ1);          
28
}
29
30
void USART_Transmit(unsigned char data) {
31
  /* Wait for empty transmit buffer */
32
  while (!( UCSRA & (1<<UDRE)));
33
  /* Put data into buffer, sends the data */
34
  UDR = data;
35
}
36
37
int main (void) {
38
  USART_Init(UBRR_VAL);
39
  
40
  while(1){
41
    USART_Transmit('x');
42
    USART_Transmit('\r');
43
    USART_Transmit('\n');
44
    _delay_ms(500);
45
  }
46
  
47
  return 0;
48
}

von Jean P. (fubu1000)


Lesenswert?

Hi,
du hast das URSEL - bit nicht gesetzt. So schreibst du wieder in UBRRH.
UCSRC = (1<<URSEL) | (1<<UCSZ0) | (1<<UCSZ1);

Gruß

P.S. : Außerdem kannst du dir schenken UBBRVAL mit der Funktion zu 
übergeben.
       Du hast es doch schon global definiert. Also einfsch:
       void USART_Init(unsigned int baud) {
       /* Set baud rate */
       UBRRH = (unsigned char)(UBRR_VAL>>8);
       UBRRL = (unsigned char)UBRR_VAL;
       .......

von Paul F. (zwanzischmark)


Lesenswert?

oh man... vielen dank

der code ist ja hauptsächlich aus der Manual, weil ich meinen Fehler 
einfach nicht gefunden hab. Jetzt kann ich natürlich optimieren ;)

danke

von Jean P. (fubu1000)


Lesenswert?

Die mit deinen Einstellungen Baudrate beträgt so um die 610Baud, kommt 
also deinen Beobachtungen mehr als Faktor zehn zu lahm sehr nah.

Kein Problem und viel Erfolg.

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.