Forum: Compiler & IDEs AVR Mega32 Umschalten UART Geschwindigkeit


von Nick (Gast)


Lesenswert?

Hallo,

ich muss eine LIN Komunikation ans laufen bringen.
UART sollte so konfiguriert werden:
 LIN überträgt die Daten byteweise. Die Bytes werden als UART-Zeichen 
übertragen. Die dabei verwendete Kodierung ist 8-N-1,1Startbit, 8 
Datenbits, kein Paritybit, 1 Stoppbit. Das Startbit ist eine logische 0, 
das Stoppbit ist eine logische 1. Die Daten werden mit der niedrigsten 
Stelle zuerst gesendet (LSB first). Damit besteht das LIN-UART4-Zeichen 
aus 10 Bits.

ich habe es mal so versucht:
1
#include <avr/interrupt.h>
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#define F_CPU 8000000UL     /* Quarz mit 8 Mhz  */
5
//#include <avr/delay.h>      /* definiert _delay_ms() ab avr-libc Version 1.2.0 */
6
7
8
9
#define RXB8 1
10
#define TXB8 0
11
#define UPE 2
12
#define OVR 3
13
#define FE 4
14
#define UDRE 5
15
#define RXC 7
16
17
#define FRAMING_ERROR (1<<FE)
18
#define PARITY_ERROR (1<<UPE)
19
#define DATA_OVERRUN (1<<OVR)
20
#define DATA_REGISTER_EMPTY (1<<UDRE)
21
#define RX_COMPLETE (1<<RXC)
22
23
// USART1 Receiver buffer
24
#define RX_BUFFER_SIZE1 8
25
26
27
volatile int msg_index=0;            //uart rx index
28
volatile char rx_buffer1[RX_BUFFER_SIZE1];
29
volatile unsigned char tx_can[8];
30
volatile unsigned char rx_wr_index1,rx_rd_index1,rx_counter1;
31
// This flag is set on USART1 Receiver buffer overflow
32
// bit rx_buffer_overflow1;
33
volatile char rx_buffer_overflow1;                      //Kläre BIT 
34
volatile char new_RX;
35
36
37
38
39
void seriell_int_9600(void)
40
{
41
// USART initialization
42
// Communication Parameters: 8 Data, 1 Stop, No Parity
43
// USART Receiver: On
44
// USART Transmitter: On
45
// USART Mode: Asynchronous
46
// USART Baud rate: 9600
47
UCSRA=0x00;
48
UCSRB=0x18;
49
50
UCSRC |= _BV(URSEL)|_BV(UCSZ0)|_BV(UCSZ1);
51
52
UBRRH=0x00;
53
UBRRL=0x33;
54
55
}
56
57
void seriell_int_19200(void) {
58
// USART initialization
59
// Communication Parameters: 8 Data, 1 Stop, No Parity
60
// USART Receiver: On
61
// USART Transmitter: On
62
// USART Mode: Asynchronous
63
// USART Baud rate: 19200
64
UCSRA=0x00;
65
UCSRB=0x18;
66
67
UCSRC |= _BV(URSEL)|_BV(UCSZ0)|_BV(UCSZ1);
68
69
UBRRH=0x00;
70
UBRRL=0x19;
71
}
72
73
void putchar_LIN(uint8_t c)
74
{
75
while ((UCSRA & DATA_REGISTER_EMPTY)==0);
76
UDR=c;
77
}
78
int main (void)
79
{  
80
81
uint8_t c;  
82
uint16_t i;
83
uint16_t a;
84
uint16_t b;
85
86
87
  while (1)
88
89
  {
90
        
91
    for (i=0; i<=0xFF; ++i)
92
     {
93
94
    seriell_int_9600();
95
    c = 0x00;
96
    putchar_LIN(c);
97
98
    seriell_int_19200();
99
    c = 0x55;
100
    putchar_LIN(c);
101
    c = i;
102
    putchar_LIN(c);
103
104
    for (a=0; a<=0xFF; ++a)
105
      {
106
      for (b=0; b<=0xFF; ++b)
107
        {
108
        asm volatile ("nop");
109
        }
110
      }
111
     }
112
113
114
  }
115
116
117
  //never goes here!
118
  return 0;      
119
}

Der UART schaltet nicht zwischen 9600 und 19200 hin und her was aber 
notwenidig ist um das Sync Break zu schicken, das mindestens 13 
Bitzeiten lang sein soll.
auf dem Oszi sehe ich das 0x55 geschrieben wird auch mit 19200 auch das 
3. byte wird geschrieben auch mit 19200 nur das erste (0x00) ist nicht 
mit 9600 geschrieben.

Da scheinbar UCSRC im Debugger nicht rigtig angezeigt wird, stimmt die 
einstellung 1 start 8 daten 1 stop keine parity?
und wieso wird die geschwindigkeit nicht umgeschalten?

THX

von Nick (Gast)


Lesenswert?

noch ne kleine Anmerkung wenn ich im Debugger durchsteppe dann ist das 
ertse Zeichen länger als die nächsten zwei, sobald ich aber RUN mache 
dann sind alle drei gleich lang?????? also 19200

von Peter D. (peda)


Lesenswert?

Das seriell_int_xxx muß natürlich erst warten, bis das Sendenendebit 
gesetzt ist, sonst ziehst Du ja dem laufenden Byte die Baudrate weg.


Peter

von Stefan (Gast)


Lesenswert?

... bin mir aus dem Stegreif gerade nicht sicher ob man mit 8 MHz Takt 
die Baudraten 19200 und 9600 mit ausreichend kleiner Abweichung 
hinbekommt. Sollte mit einem Blick ins Datenblatt überprüft werden

von Nick (Gast)


Lesenswert?

der Tipp mit dem warten ist nicht schlecht da bin ich nicht druaf 
gekommen.
Baudrate sollte kein Problem sein
19200 @8Mhz UBRR = 0x19   0,16%ERR
9600  @8Mhz UBRR = 0x33   0,16%ERR
nach AVR Fp Calc and Timer Tool

ob das schreiben des UCSRC richtig ist weis ich immer noch nicht ;-(
1 Startbit, 8 Datenbits, kein Paritybit, 1 Stoppbit sollte es sein
Ich versuche es ja mit:
1
UCSRA=0x00;
2
UCSRB=0x18;
3
4
UCSRC |= _BV(URSEL)|_BV(UCSZ0)|_BV(UCSZ1);
5
6
UBRRH=0x00;
7
UBRRL=0x19;
was bedeutet das _BV ?


komplett siehts grad so aus:
1
#define PARITY_ERROR (1<<UPE)
2
#define DATA_OVERRUN (1<<OVR)
3
#define DATA_REGISTER_EMPTY (1<<UDRE)
4
#define RX_COMPLETE (1<<RXC)
5
6
// USART1 Receiver buffer
7
#define RX_BUFFER_SIZE1 8
8
9
10
volatile int msg_index=0;            //uart rx index
11
volatile char rx_buffer1[RX_BUFFER_SIZE1];
12
volatile uint16_t i;
13
14
15
void warte (uint16_t i)
16
{
17
  uint16_t b;
18
      for (b=0; b<=i; ++b)
19
        {
20
          static unsigned char volatile dummy;
21
              (void) (dummy = b);
22
          PORTB ^= 1 << PORTB1;
23
        }
24
25
}
26
27
28
29
void seriell_int_9600(void)
30
{
31
while ((UCSRA & DATA_REGISTER_EMPTY)==0);
32
// USART initialization
33
// Communication Parameters: 8 Data, 1 Stop, No Parity
34
// USART Receiver: On
35
// USART Transmitter: On
36
// USART Mode: Asynchronous
37
// USART Baud rate: 9600
38
UCSRA=0x00;
39
UCSRB=0x18;
40
41
UCSRC |= _BV(URSEL)|_BV(UCSZ0)|_BV(UCSZ1);
42
43
UBRRH=0x00;
44
UBRRL=51;
45
46
}
47
48
void seriell_int_19200(void) {
49
while ((UCSRA & DATA_REGISTER_EMPTY)==0);
50
// USART initialization
51
// Communication Parameters: 8 Data, 1 Stop, No Parity
52
// USART Receiver: On
53
// USART Transmitter: On
54
// USART Mode: Asynchronous
55
// USART Baud rate: 19200
56
UCSRA=0x00;
57
UCSRB=0x18;
58
59
UCSRC |= _BV(URSEL)|_BV(UCSZ0)|_BV(UCSZ1);
60
61
UBRRH=0x00;
62
UBRRL=25;
63
}
64
65
void putchar_LIN(uint8_t c)
66
{
67
while ((UCSRA & DATA_REGISTER_EMPTY)==0);
68
UDR=c;
69
while ((UCSRA & DATA_REGISTER_EMPTY)==0);
70
}
71
72
73
int main (void)
74
{  
75
76
uint8_t c;  
77
uint16_t i;
78
PORTB=0x00;
79
DDRB=0xFF;
80
81
// PORTB |= (1 << 0);    /* setzt Bit 0 an PortB auf 1 */
82
// PORTB &= ~(1 << 0);   /* loescht Bit 0 an PortB */
83
84
  while (1)
85
86
  {
87
        
88
    for (i=0; i<=0xFF; ++i)
89
     {
90
    PORTB = 0x01;
91
    warte(0x3fff);
92
93
    seriell_int_9600();
94
    c = 0x00;
95
    putchar_LIN(c);
96
97
        warte(0xff);
98
99
    seriell_int_19200();
100
    c = 0x55;
101
    putchar_LIN(c);
102
103
        warte(0xff);
104
    c = i;
105
    putchar_LIN(c);
106
107
    warte(0x2fff);
108
     
109
    PORTB = 0x00;
110
    warte (0x7fff);
111
    }
112
113
  }
114
115
116
  //never goes here!
117
  return 0;      
118
}

  

von FBI (Gast)


Lesenswert?

_BV ist ein define in einer der Header Dateien von avr-libv
1
#define _BV(bit) (1 << (bit))

CU

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.