Forum: Mikrocontroller und Digitale Elektronik empfange keine Daten über uart


von Johannes (Gast)


Lesenswert?

Hi,
ich möchte über Bluetooth Daten empfangen und versenden. Allerdings 
funktioniert das mit dem Senden nicht.
1
#define F_CPU 16000000
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include <util/delay.h>
5
6
#define USART_BAUDRATE 9600
7
#define MYUBRR F_CPU/16/USART_BAUDRATE-1
8
9
void USART_Init(unsigned int ubrr);
10
void USART_Transmit(unsigned int uart_data);
11
void TIMER_Init();
12
13
14
volatile uint8_t uart_data;
15
16
17
18
void USART_Init(unsigned int ubrr)
19
{
20
  /*Set baud rate*/
21
  UBRR0H = (unsigned char)(ubrr >> 8);
22
  UBRR0L = (unsigned char)(ubrr);
23
  /* Enable receiver and transmitter  & Interrupts for RX & TX*/
24
  UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0) | (1 << TXCIE0);
25
  /* Set frame format: 8data, 1stop bit */
26
  UCSR0C = (1 << UCSZ00) | (1 << UCSZ01);
27
}
28
29
void TIMER_Init(){
30
  /*Set the Timer Mode to CTC*/
31
  TCCR0A = (1 << WGM01);
32
  /* Set the value to count*/
33
  OCR0A = 0xF9;
34
  /*Set the ISR COMPA vect*/
35
  TIMSK0 |= (1 << OCIE0A);
36
  /*set prescaler to 256 and start the timer*/
37
  TCCR0B = (1 << CS02);
38
}
39
40
void USART_Transmit(unsigned int uart_data)
41
{
42
  /* Wait for empty transmit buffer */
43
  while (!( UCSR0A & (1<<UDRE0)));
44
  /* Put data into buffer, sends teh data*/
45
  UDR0 = uart_data;
46
}
47
48
49
int main(void)
50
{
51
  /*(LED)*/
52
  DDRB |= (1 << PORTB5);
53
  PORTB |= (1 << PORTB5);
54
  USART_Init(MYUBRR);
55
  _delay_ms(10);
56
  TIMER_Init();
57
  /*enable Interrupts*/
58
  sei();
59
  
60
  while (1){
61
    if(uart_data) USART_Transmit(uart_data);
62
  }
63
}
64
65
ISR(USART_RX_vect) //Receive Interrupt
66
{
67
  PORTB ^= (1 << PORTB5); //LED
68
  /* Wait for data to be received */
69
  while(!(UCSR0A & (1<<RXC0)));
70
  uart_data = UDR0;
71
}
72
73
ISR(USART_TX_vect) //Transmit Interrupt
74
{
75
  //PORTB ^= (1 << PORTB5);  // LED
76
  uart_data = 0x00;
77
}
78
79
80
81
ISR(TIMER0_COMPA_vect)
82
{
83
  static unsigned int timer_counter = 0;
84
  if(++timer_counter >= 250){//1000ms
85
    timer_counter = 0;
86
  } 
87
}

ich möchte zunächst einfach das empfangene Zeichen wieder zurücksenden. 
Dies funktioniert auch, allerdings wird es immer wieder gesendet und 
hört nicht mehr auf.

Eigentlich bin ich der Meinung, dass ich nach dem Datenblatt gegangen 
bin. Aber anscheinend habe ich irgendwo noch einen bock drinn.

Wäre nett, wenn ihr mal drüber gucken könntet und den Fehler bemerkt.

Johannes

von public (Gast)


Lesenswert?

Hallo Johannes,

welcher Controller wird denn da verwendet? (Ich schätze irgend ein AVR)

Ein Blick in die Glaskugel verrät:

(1) globale Variable uart_data? bitte Kapseln! (schreibe dir get und set 
Funktionen auf diese Variable, dabei nicht mit sei() und cli() sparen, 
also sauber den zugriff auf diese Variable auftrennen, stichwort: 
schreiben während des lesens?)

(2) Muss in den Interruptroutinen nicht das Flag gelöscht/gesetzt 
werden?

(3) kann es sein, dass die RX-ISR ständig aufgerufen wird und du deshalb 
in der while-schleife ständig ein TRUE in deiner if-abfrage generierst? 
und klar es gibt auch eine TX-ISR, aber dazu siehe (2)

bests grüße
public

von uart (Gast)


Lesenswert?

ISR(USART_TX_vect) wird wohl nie aufgerufen, und damit wird  uart_data = 
0x00 nie ausgeführt.

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.