AVR ATmega32 - UART-Problem

OP #3161484
Lesenswert?

Hallo zusammen,

mit meinem NET-IO möchte ich per UART/RS232 kommunizieren. Abweichend 
zur Bestückung lass ich ihn mit internem Takt auf 1 MHz laufen.

Quellcode (kopiert aus Beitrag "ATmega32 UART init." 
nachdem ein anderer auch schon nicht ging):
1
#include <avr/io.h>
2
 
3
int main(void)
4
{
5
  UBRRH = (unsigned char)(6>>8);
6
  UBRRL = (unsigned char) 6;  // 9600 Baud
7
 
8
  UCSRB=(1<<TXEN);
9
  UCSRC=(1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0);
10
 
11
  while(1)
12
  {
13
    while (!(UCSRA&(1<<UDRE)))
14
    {
15
    }.
16
    UDR = 'a';
17
    while (!(UCSRA&(1<<UDRE)))
18
    {
19
    }
20
    UDR = 'b';
21
  }
22
}
Es sollte nun ständig a und b senden, hex also 0x61 und 0x62. Bei mir in 
hterm kommen aber nur 0xC1 und 0xC2 an.

Kann mir jemand einen Tipp geben, in welcher Richtung ich den Fehler 
suchen muss?
OP #3171552
Lesenswert?

Hey,

da bin ich wieder mit einem neuen Problem.

Hier erstmal mein Quelltext:
1
#include "compiler.h"
2

3
void USART_Init( unsigned int baud );
4
unsigned char USART_Receive( void );
5
void USART_Transmit( unsigned char data );
6

7
unsigned char uart_empfangen;
8
unsigned char uart_empfangen_char;
9

10
void USART_Init( unsigned int baud )
11
{
12
  // Set baud rate 
13
  UBRRH = (unsigned char)(baud>>8);
14
  UBRRL = (unsigned char)baud;
15
  // Enable receiver and transmitter 
16
  UCSRB = (1<<RXEN)|(1<<TXEN)|(1 << RXCIE);
17
  
18
  // Set frame format: 8data, 1stop bit 
19

20
  UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);  
21
  uart_empfangen = 0x00;
22
}
23

24
unsigned char USART_Receive( void )
25
{
26
  // Wait for data to be received 
27
  while ( !(UCSRA & (1<<RXC)) )
28
  ;
29
  // Get and return received data from buffer 
30
  return UDR;
31
}
32
void USART_Transmit( unsigned char data )
33
{
34
  // Wait for empty transmit buffer 
35
  while ( !( UCSRA & (1<<UDRE)) )
36
  ;
37
  // Put data into buffer, sends the data 
38
  UDR = data;
39
}
40

41

42
ISR(_VECTOR(14)) {
43
    
44
  uart_empfangen_char = UDR;
45
  uart_empfangen = 0x01;
46
  
47
}
48

49

50
int main(void)
51
{
52
  unsigned char i;
53
  
54
  USART_Init(103);// Extern 16 MHz
55

56

57
  // Enable global interrupts
58
  sei();
59
  
60

61
  while (1) {
62
  
63
    if (uart_empfangen != 0x00) {
64
      uart_empfangen = 0x00;
65
      for (i = 0; i <= 254; i++)
66
        USART_Transmit (i);
67
    }  
68
    
69
  /*  if ( (UCSRA & (1<<RXC)) )    {
70
      d = UDR;
71
      for (i = 65; i <= 69; i++)
72
      USART_Transmit (i);      
73
      
74
    }    
75
  */
76
  }
77
}

Problem: Senden und Empfangen via Pollen hat funktioniert, nur per 
Interrupt mag es nicht.

Ich hab es auch schon mit div. Prüfschleifen/Port-Toggeln probiert und 
dabei rausgefunden, dass die Interrupt-Routine angesprungen wird, jedoch 
das Löschen des Interrupts nicht funktioniert.

Laut Datenblatt und diversen Beispielen sollte dafür ja ein Lesen von 
UDR ausreichen, ist bei mir jedoch nicht der Fall.

Kann mir jemand das Brett vorm Kopf wegnehmen oder spinnt mein Net-IO?
#3171581
Lesenswert?

1
ISR(_VECTOR(14)) {
Was soll das? Warum nimmst du nicht wie jeder normale Mensch die dafür 
vorgesehen Namen? Dann hättest du auch nicht wie jetzt den falschen 
Vektor erwischt.

Reinhard S. schrieb:
> Ich hab es auch schon mit div. Prüfschleifen/Port-Toggeln probiert und
> dabei rausgefunden, dass die Interrupt-Routine angesprungen wird,

Sicher nicht.

Reinhard S. schrieb:
> jedoch
> das Löschen des Interrupts nicht funktioniert.

Weil eben die ISR (und damit das UDR-Lesen) überhaupt nicht ausgeführt 
wird. Im Moment landet dein Programm bei einem empfangenen Byte in einer
Endlos-Softreset-Schleife.


PS: Und über "volatile" musst du dich auch mal informieren.

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