Forum: Mikrocontroller und Digitale Elektronik Uart Atmega 8


von Anonym (Gast)


Lesenswert?

Hallo,

ich habe ein Problem mit dem Uart, auf dem PC etwas empfangen kann ich 
zwar, jedoch scheint beim AVR auf dem Pollin-Evaluations-Board nichts 
anzukommen.

Wenn ich TX an RX halte, empfange ich jedes Zeichen wieder. Theoretisch 
müsste alles funktionieren.

Wenn ich jedoch eine Drahtbrücke auf der IC-Fassung einsetze, empfange 
ich nicht jedes Zeichen doppelt. Desweiteren kann ich nur etwas 
empfangen, wenn ich einen Programmer in die ISP-Buchse eingesteckt habe.


1
#define F_CPU       16000000UL
2
#define BAUD        9600UL
3
#define UBRR_BAUD   ((F_CPU)/(BAUD*16UL))-1
4
5
#include <avr/io.h>
6
#include <util/delay.h>
7
#include <stdlib.h>
8
#include <avr/interrupt.h> 
9
10
11
12
void init_uart(void)
13
{
14
  // Baudrate einstellen
15
  UBRRH = (uint8_t) (UBRR_BAUD>>8);
16
  UBRRL = (uint8_t) (UBRR_BAUD);
17
  // Aktivieren von receiver und transmitter
18
  UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
19
20
  // Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit
21
  UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
22
}
23
24
25
26
27
int uart_putc(unsigned char c)
28
{
29
  while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
30
  {
31
  }
32
  
33
  UDR = c;                      /* sende Zeichen */
34
35
  return 0;
36
}
37
38
39
/* puts ist unabhaengig vom Controllertyp */
40
41
void uart_puts (char *s)
42
{
43
  while (*s)
44
  {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" */
45
    uart_putc(*s);
46
    s++;
47
  }
48
}
49
50
uint8_t uart_getc(void)
51
{
52
  while (!(UCSRA & (1<<RXC)))   // warten bis Zeichen verfuegbar
53
  ;
54
  return UDR;                   // Zeichen aus UDR an Aufrufer zurueckgeben
55
}
56
57
58
59
int main(void)
60
{
61
  sei();
62
  //DDRD|=(1<<PD7);
63
  init_uart();
64
  uart_puts("Bereit....");
65
  uint8_t c =uart_getc();
66
  uart_puts("Etwas Empfangen!");
67
  return 0;
68
}

Der Code ist zu 90% aus dem Tutorial. Das Problem ist nun, dass ich 
niemals  "Etwas Empfangen!" empfange.

von Stefan E. (sternst)


Lesenswert?

Anonym schrieb:
> Desweiteren kann ich nur etwas
> empfangen, wenn ich einen Programmer in die ISP-Buchse eingesteckt habe.

Masse-Verbindung vergessen?


1
  UCSRB = ... (1<<RXCIE);
+ keine ISR (sondern Polling) => kein Empfangen möglich

von Anonym (Gast)


Lesenswert?

Ich habe noch vergessen zu erwähnen, dass ich hiermit:
> Desweiteren kann ich nur etwas
> empfangen, wenn ich einen Programmer in die ISP-Buchse eingesteckt habe.

das "Bereit" meine.

das "Etwas Empfangen" erhielt ich noch nie.

Stefan Ernst schrieb:
> UCSRB = ... (1<<RXCIE);+ keine ISR (sondern Polling) => kein Empfangen möglich

Das heißt RXCIE muss ich nicht setzen , kann ich aber?

von Norbert (Gast)


Lesenswert?

Anonym schrieb:
> Ich habe noch vergessen zu erwähnen, dass ich hiermit:
>> Desweiteren kann ich nur etwas
>> empfangen, wenn ich einen Programmer in die ISP-Buchse eingesteckt habe.
>
> das "Bereit" meine.
>
> das "Etwas Empfangen" erhielt ich noch nie.
>
> Stefan Ernst schrieb:
>> UCSRB = ... (1<<RXCIE);+ keine ISR (sondern Polling) => kein Empfangen möglich
>
> Das heißt RXCIE muss ich nicht setzen , kann ich aber?

RXCIE: Receive complete interrupt enable.
Wenn du keine Interrupt Routine dafür bereitstellst, dann gibt es unter 
Umständen nach einem empfangenen Zeichen sofort einen Reset.

von Anonym (Gast)


Lesenswert?

Habe entsprechende Stelle rausgenommen,

macht aber immer noch keinen Unterschied.

von Dietrich L. (dietrichl)


Lesenswert?

Anonym schrieb:
> #define F_CPU       16000000UL

Sind die Fuses auch entsprechend eingestellt?
Und natürlich: sind Quarz bzw. Takt vorhanden, d.h. µC läuft "im 
Prinzip"? -> Test mit LED

Gruß Dietrich

von Carsten H. (blaubaer77)


Lesenswert?

In Deinem Programm fehlt die Endlosschleife. main() wird einmal 
durchlaufen und dann ist Schluß.


Gruß Carsten...

PS: hab gerade gesehen in uart_getc(void) ist eine Warteschleife.
Das funktioniert aber dann auch nur ein Mal.

von Anonym (Gast)


Lesenswert?

Dietrich L. schrieb:
> Anonym schrieb:
>> #define F_CPU       16000000UL
>
> Sind die Fuses auch entsprechend eingestellt?
> Und natürlich: sind Quarz bzw. Takt vorhanden, d.h. µC läuft "im
> Prinzip"? -> Test mit LED
>
> Gruß Dietrich

Ich bekomme immer ein "Bereit" vom µC, sobald er startet bzw. resettet 
wird.

Fuses sind wohl auch richtig eingestellt.

Low:0xef
High:0xd9

von Carsten H. (blaubaer77)


Lesenswert?

Ist denn der Jumper JP1 gesteckt auf dem Board? Sonst ist die RX-Leitung 
nicht zum Prozessor durchgeschaltet.

von Hubert G. (hubertg)


Lesenswert?

Bei mir funktioniert es, muss wohl doch ein HW-Fehler sein.

von Anonym (Gast)


Lesenswert?

Carsten H. schrieb:
> Ist denn der Jumper JP1 gesteckt auf dem Board? Sonst ist die RX-Leitung
> nicht zum Prozessor durchgeschaltet.

JP1 und JP2 sind gesteckt

Hubert G. schrieb:
> Bei mir funktioniert es, muss wohl doch ein HW-Fehler sein.

Hmm... Okay.  Vielen Dank.

von Hubert G. (hubertg)


Lesenswert?

Es liegt nur am |(1<<RXCIE) das nicht hingehört.
Schau mal ob du das richtige File ladest.
Ein HW-Fehler ist natürlich immer noch möglich.

von Anonym (Gast)


Lesenswert?

Hubert G. schrieb:
> Es liegt nur am |(1<<RXCIE) das nicht hingehört.
> Schau mal ob du das richtige File ladest.
> Ein HW-Fehler ist natürlich immer noch möglich.

Ne das passt alles.

Was ich noch sonderbar finde ist halt, dass ich nur Empfange wenn der 
ISP-Programmer eingesteckt ist.

von Carsten H. (blaubaer77)


Lesenswert?

Ziehst Du den Programmer komplett vom Board ab oder nur das USB-Kabel 
vom Programmer?

von Anonym (Gast)


Lesenswert?

Carsten H. schrieb:
> Ziehst Du den Programmer komplett vom Board ab oder nur das USB-Kabel
> vom Programmer?

Macht keinen Unterschied, sobald USB-Kabel einzeln oder der Programmer 
komplett entfernt ist , empfange ich nichts mehr

von Hubert G. (hubertg)


Lesenswert?

Dann fehlt dir die GND-Verbindung vom Board zum PC.
Das das ganze nur einmal funktioniert ist schon klar?

von Carsten H. (blaubaer77)


Lesenswert?

Das klingt irgendwie nach einem Problem mit der Reset-Leitung.
Ein stromloser Programmer könnte die Reset-Leitung über seine 
Clamp-Dioden runter ziehen, aber wenn der Programmer vom Board ab ist 
und es trotzdem nicht geht, könnte es ein Problem auf dem Board sein.
Welche Spannung liegt denn am Reset-Pin, wenn der Programmer ab ist?

von Anonym (Gast)


Lesenswert?

Hubert G. schrieb:
> Dann fehlt dir die GND-Verbindung vom Board zum PC.
> Das das ganze nur einmal funktioniert ist schon klar?

Das kann gut sein, da der COM-Port bei meinem Mainboard ein 
Pfostenstecker war und ich mir so selbst einen Adapter zu D-Sub bauen, 
musste, ich schaue direkt nach ob ich vielleicht etwas vergessen habe.


Vielen Dank schon mal!

von Anonym (Gast)


Lesenswert?

Hab mich wohl zu früh gefreut, es läuft leider immer noch nicht richtig.

Die GND-Leitung musste ich zwar nachbessern, es hat aber leider nichts 
verändert.

von Anonym (Gast)


Lesenswert?

Also zumindest empfängt er jetzt ohne Programmer, also ein Teilerfolg ;D

von Anonym (Gast)


Lesenswert?

Ich glaube ich bin der Lösung schon näher gekommen, vielleicht gibt es 
jetzt noch ein paar Ideen um die Sache abzuschließen.

Also ich habe den Code wie folgt abgeändert:
1
int main(void)
2
{
3
  init_uart();
4
  uart_puts("Bereit....");
5
  while(1)
6
  {
7
if(UDR!=0)
8
    uart_putc(UDR);
9
  }
10
  return 0;
11
}

Nun sieht es so aus:

µC:"Bereit.."
Eingabe

von Anonym (Gast)


Lesenswert?

Ich glaube ich bin der Lösung schon näher gekommen, vielleicht gibt es
jetzt noch ein paar Ideen um die Sache abzuschließen.

Also ich habe den Code wie folgt abgeändert:
int main(void)
{
  init_uart();
  uart_puts("Bereit....");
  while(1)
  {
    if(UDR!=0)
    uart_putc(UDR);
  }
  return 0;
}

Nun sieht es so aus:

µC:"Bereit....
Eingabe: (Beispielsweise:)"k")
µC:"kkkkkkkkk,usw......"


Ps: Sorry für den Doppelpost

von Anonym (Gast)


Lesenswert?

Sorry , aber ich weiß nicht wie ich alte Beiträge löschen kann, aber das 
hier ist der richtige Code
1
int main(void)
2
{
3
  init_uart();
4
  uart_puts("Bereit....");
5
  while(1)
6
  {
7
    uart_putc(UDR);
8
  }
9
  return 0;
10
}

von Anonym (Gast)


Lesenswert?

Ich weiß wirklich nicht wieso aber wenn ich UDR=0; in die while-Schleife 
von uart_getc() hinzufüge, funktioniert alles prächtig.

von Hubert G. (hubertg)


Lesenswert?

So sieht mein Code aus:
1
#define F_CPU       16000000UL
2
#define BAUD        9600UL
3
#define UBRR_BAUD   ((F_CPU)/(BAUD*16UL))-1
4
5
#include <avr/io.h>
6
#include <util/delay.h>
7
#include <stdlib.h>
8
#include <avr/interrupt.h> 
9
10
11
12
void init_uart(void)
13
{
14
  // Baudrate einstellen
15
  UBRRH = (unsigned char) (UBRR_BAUD>>8);
16
  UBRRL = (unsigned char) (UBRR_BAUD);
17
  // Aktivieren von receiver und transmitter
18
  UCSRB = (1<<RXEN)|(1<<TXEN);
19
20
  // Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit
21
  UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
22
}
23
24
25
26
27
int uart_putc(unsigned char c)
28
{
29
  while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
30
  {
31
  }
32
  
33
  UDR = c;                      /* sende Zeichen */
34
35
  return 0;
36
}
37
38
39
/* puts ist unabhaengig vom Controllertyp */
40
41
void uart_puts (char *s)
42
{
43
  while (*s)
44
  {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" */
45
    uart_putc(*s);
46
    s++;
47
  }
48
}
49
50
uint8_t uart_getc(void)
51
{
52
  while (!(UCSRA & (1<<RXC)))   // warten bis Zeichen verfuegbar
53
  ;
54
  return UDR;                   // Zeichen aus UDR an Aufrufer zurueckgeben
55
}
56
57
58
59
int main(void)
60
{
61
62
  sei();
63
  //DDRD|=(1<<PD7);
64
  init_uart();
65
  uart_puts("Bereit....");
66
  for(;;){
67
  
68
  unsigned char c =uart_getc();
69
  uart_putc(c);
70
  uart_puts("  ");
71
  uart_puts("Etwas Empfangen!");
72
  uart_puts("  ");
73
 } 
74
}

Es wird jeder eingegebene Buchstabe vom µC an das Terminal 
zurückgeschickt.

von Anonym (Gast)


Lesenswert?

Funktioniert bei mir leider nicht nur wenn ich den Code

1
uint8_t uart_getc(void)
2
{
3
  while (!(UCSRA & (1<<RXC)))   // warten bis Zeichen verfuegbar
4
  ;
5
  return UDR;                   // Zeichen aus UDR an Aufrufer zurueckgeben
6
}


so abändere:
1
uint8_t uart_getc(void)
2
{
3
  while (!(UCSRA & (1<<RXC)))   // warten bis Zeichen verfuegbar
4
  {
5
  UDR = 0;
6
  }
7
  return UDR;                   // Zeichen aus UDR an Aufrufer zurueckgeben
8
}

von Hubert G. (hubertg)


Lesenswert?

Womit kompilierst du, mit welcher Version?

von Anonym (Gast)


Lesenswert?

Sorry für die Verspätung


Atmel Studio 6(Version 6.0.1996)

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.