Forum: Compiler & IDEs Atmega644P will nicht empfangen UART


von Sören T. (stimmy)


Lesenswert?

Hallo,
ich veruche mit meinem Atmega644p etwas per UART zu empfangen.
Ich habe dafür ein kleines Programm geschreiben, mit dem ich auf dem 
Pollin Board die beiden LEDs und den Summer schalten kann.

Hauptdatei:
1
#define F_CPU 16000000UL
2
3
#include <avr/io.h>
4
#include <util/delay.h>
5
#include "uart_timmy.h"
6
7
int beep(void)
8
{
9
  for(int i=1; i < 750; i++)
10
  {
11
    PORTD |= (1<<PD7);
12
    _delay_us(130);
13
    PORTD &= ~(1<<PD7);
14
    _delay_us(130);
15
  }
16
  return 0;
17
}
18
19
int main(void)
20
{
21
  DDRD = ((1<<PD7)|(1<<PD6)|(1<<PD5));
22
  uart_init();
23
  uint8_t c;
24
    
25
  
26
  uart_puts("----------------\r\n");
27
  uart_puts("UART TEST      |\r\n");
28
  uart_puts("----------------\r\n");
29
  uart_puts("\r\n");
30
  uart_puts("a drucken fur LED1 an\r\n");
31
  uart_puts("y drucken fur LED1 aus\r\n");
32
  uart_puts("\r\n");
33
  uart_puts("s drucken fur LED2 an\r\n");
34
  uart_puts("x drucken fur LED2 aus\r\n");
35
  uart_puts("\r\n");
36
  uart_puts("d drucken fur BEEP\r\n");
37
  uart_puts("\r\n");
38
  
39
  beep();PORTD |= (1<<PD6);PORTD |= (1<<PD5);
40
  
41
  while(1)
42
    {        
43
      c = uart_getc();
44
      uart_putc(c);
45
      switch (c)
46
      {
47
        case 'a': PORTD |= (1<<PD6);
48
          break;
49
        case 'y': PORTD &= ~(1<<PD6);
50
          break;
51
          
52
        case 's': PORTD |= (1<<PD5);
53
          break;
54
        case 'x': PORTD &= ~(1<<PD5);
55
          break;
56
          
57
        case 'd': beep();
58
        
59
      }
60
  }    
61
}

uart.c
1
#include <avr/io.h>
2
#include "uart.h"
3
4
5
void uart_init(void)
6
{
7
   UBRR0H=(uint8_t)((F_CPU / (16 * BAUD)) - 1)>>8;
8
   UBRR0L=(uint8_t)(F_CPU / (16 * BAUD)) - 1;
9
 
10
   UCSR0C = (1<<UCSZ01) | (1<<UCSZ00);    // Asynchron 8N1
11
   UCSR0B = (1<<TXEN0) | (1<<RXEN0);      // tx & rx enable
12
}
13
14
15
16
int uart_putc(unsigned char c)
17
{
18
    while (!(UCSR0A & (1<<UDRE0)))  /* warten bis Senden moeglich */
19
    {
20
    }                             
21
 
22
    UDR0 = c;                      /* sende Zeichen */
23
    return 0;
24
}
25
 
26
 
27
/* puts ist unabhaengig vom Controllertyp */
28
void uart_puts (char *s)
29
{
30
    while (*s)
31
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" */
32
        uart_putc(*s);
33
        s++;
34
    }
35
}
36
37
char uart_getc(void)
38
{
39
    while (!(UCSR0A & (1<<RXC0)));   // warten bis Zeichen verfuegbar
40
    return UDR0;                   // Zeichen aus UDR an Aufrufer zurueckgeben
41
}
42
43
void uart_gets( char* Buffer, uint8_t MaxLen )
44
{
45
  uint8_t NextChar;
46
  uint8_t StringLen = 0;
47
 
48
  NextChar = uart_getc();         // Warte auf und empfange das nächste Zeichen
49
 
50
                                  // Sammle solange Zeichen, bis:
51
                                  // * entweder das String Ende Zeichen kam
52
                                  // * oder das aufnehmende Array voll ist
53
  while( NextChar != '\n' && StringLen < MaxLen - 1 ) {
54
    *Buffer++ = NextChar;
55
    StringLen++;
56
    NextChar = uart_getc();
57
  }
58
 
59
                                  // Noch ein '\0' anhängen um einen Standard
60
                                  // C-String daraus zu machen
61
  *Buffer = '\0';
62
}
63
  
64
  // Passende Größe des Arrays wählen!
65
  // char Line[40];      // String mit maximal 39 zeichen 
66
  // uart_gets( Line, sizeof( Line ) );

Das was er senden soll kommt auch auf dem Pc an.
Er macht auch seine Ausgaben vor der Dauerschleife passend.
Habe direkt die Codes aus dem Tutorial genommen und die getc auch noch 
mal mit der aus dem Datenblatt verglichen.

Er empfangt nix und sendet deswegen auch kein char zurück geschweige 
denn, dass er etwas schaltet.

Hat einer ne Idee warum er rumnzickt?

von Karl H. (kbuchegg)


Lesenswert?

Welches Terminalprogramm benutzt du auf dem PC?

Eine fiese Falle ist zb, wenn auf dem PC Hardware-Handshake 
eingeschaltet ist. Bei den heute üblichen minimal beschalteten RS232 
Kabeln bedeutet das nämlich, dass der PC keine Sendefreigabe hat. D.h. 
nicht der AVR empfängt nichts, sondern der PC sendet gar nicht.

Lässt sich mit einer LED (+330 Ohm) an der Sendeleitung vom PC zum AVR 
leicht kontrollieren, ob da überhaupt was kommt.

von Sören T. (stimmy)


Lesenswert?

@kbuchegg: Da kommt man aber nur durch Erfahrung drauf ;)
Jetzt läuft es einwandfrei!

Vielen Dank!

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.