Forum: Mikrocontroller und Digitale Elektronik UART AT90CAN128 Einstieg


von Anfänger (Gast)


Lesenswert?

Guten Tag,

ich habe als Anfang zum Einstieg in die Programmierung mit seriellen 
Schnittstellen versucht, ein Zeichen vom Controller an den PC zu senden.
1
#include <avr/io.h>
2
3
#define F_CPU 16000000UL  // Systemtakt in Hz - Definition als unsigned long beachten
4
#define BAUD 9600L      // Baudrate
5
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
6
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
7
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
8
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
9
#error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
10
#endif
11
#include "util/delay.h"
12
13
int main(void)
14
{
15
   UBRR0H = UBRR_VAL >> 8;
16
   UBRR0L = UBRR_VAL & 0xFF;
17
18
   UCSR0C=(1<<UMSEL0)|(1<<UCSZ00)|(1<<UCSZ01);
19
   UCSR0A= (1<<TXC0);
20
  
21
  while(!(UCSR0A & (1<<UDRE0)))
22
  {
23
    
24
  }
25
26
    UDR0= 'z';
27
  while(1)
28
    {
29
        
30
    }
31
}

Erst einmal muss ich gestehen, dass ich nicht genau weiß, welche 
Taktfrequenz ich nehmen soll. Ob die 16MHz oder die 32768kHz?!

Jedenfalls wird mir auf meinem HyperTerminal stets eine Anreihung 
kryptischer Zeichen ausgegeben.

Ausprobiert habe ich (erfolglos) das benutzen von 2 StoppBits und das 
Setzen einer Delay nach der Ausgabe des Zeichens. Die Einstellungen im 
HyperTerminal sind wie im Tutorial gesetzt.

Ich bedanke mich schonmal für Hilfestellungen.

von holger (Gast)


Lesenswert?

Als erstes solltest du den UART auf asynchron stellen.
Als zweites frage ich mich wie du überhaupt was senden
kannst wenn der Transmitter nicht Enabled ist?

von Anfänger (Gast)


Lesenswert?

1
#include <avr/io.h>
2
3
#define F_CPU 32768000UL  // Systemtakt in Hz - Definition als unsigned long beachten
4
#define BAUD 9600UL      // Baudrate
5
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
6
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
7
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
8
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
9
#error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
10
#endif
11
#include "util/delay.h"
12
13
int main(void)
14
{
15
   UBRR0H = UBRR_VAL >> 8;
16
   UBRR0L = UBRR_VAL & 0xFF;
17
18
   UCSR0C=(0<<UMSEL0)|(1<<UCSZ00)|(1<<UCSZ01); //Asynchroner Mode, 8-bit
19
   UCSR0B= (1<<TXEN0);  //Transmitter einschalten
20
  
21
  while(!(UCSR0A & (1<<UDRE0)))
22
  {
23
    
24
  }
25
    
26
 UDR0= 'h';
27
28
  while(1)
29
    {
30
31
    }
32
}

So danke erstmal, keine Ahnung wie mir das passieren konnte :/

Mitllerweile habe ich herausgefunden, dass der Frequenztakt den 32768kHz 
entspricht. Trotzdem warden nun zwar einzelne Zeichen gesendet, 
allerdings wieder nur Dreiecke o.Ä.
Lediglich einmal kam auch wirklich der richtige Buchstabe raus.

von Pepe (Gast)


Lesenswert?

Hallo.
Die F_CPU ist viel zu hoch. Zum einen kann der AT90CAN128 doch nur 16MHz 
und wenn ich richtig sehe wären es bei Dir 32,7MHz. Geht also schon mal 
vom Prozessor nicht.
Welchen Quarz hast Du denn eingebaut ? F_CPU muss dem tatsächlichen Takt 
entsprechen.

Pepe.

von Anfänger (Gast)


Lesenswert?

Alles klar, war ein Denkfehler: ich dachte die 32768kHz sind kleiner als 
die 16MHz...jetzt funktionier alles, danke :)

von Anfänger (Gast)


Lesenswert?

Sooo täglich grüßt das Murmeltier und nach erfolgreichem Senden von 
Daten an den PC wollte ich es nun mit dem Empfangen versuchen
1
uint8_t uart_getc(void)
2
{
3
  while (!(UCSR0A & (1<<RXC0)));   // warten bis Zeichen verfuegbar
4
    
5
  return UDR0;                   // Zeichen aus UDR an Aufrufer zurueckgeben
6
  }
7
  
8
9
int main(void)
10
{
11
  UBRR0H = UBRR_VAL >> 8;
12
  UBRR0L = UBRR_VAL & 0xFF;
13
14
  UCSR0C=(0<<UMSEL0)|(1<<UCSZ00)|(1<<UCSZ01); 
15
  UCSR0B= (1<<TXEN0)|(1<<RXEN0);              
16
  
17
18
  while(1)
19
  {
20
21
        if ( (UCSR0A & (1<<RXC0)) )
22
        {
23
          uint8_t c;
24
          c = uart_getc();
25
          DDRC = 0xFF; 
26
          PORTC = c;
27
        }
28
        else
29
        {
30
    
31
        }
32
33
  }
34
}
Die Kommunikation scheint auch zu funktionieren, allerdings reagiert der 
Controller auf jede mögliche Eingabe. So springen z.B. die LED's schon 
beim Drücken der Leertaste hin und her.
Eigentlich wollte ich durch Eingaben wie "0b101100111" ein Muster mit 
den LED's (alle am Port C)erzeugen, aber auch das kommt nur Falsches an.

Die Einstellungen im HyperTerminal: kein Handshaking, 8-bit, keine 
Parität, ein StopBit. Leider finde ich auch im Internet kein 
vergleichbares Problem...

Vielen Dank schonmal!

von Anfänger (Gast)


Lesenswert?

Achja, der obere Teil, sprich Includes etc. ist identisch mit dem Code 
weiter oben!

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.