AVR ATmega32 - UART-Problem

OP #3161484
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
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?
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

Eine eigene Frage? Dieser Thread ist über 13 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.