Forum: Mikrocontroller und Digitale Elektronik attiny87 UART probleme


von Mario M. (mario105)


Angehängte Dateien:

Lesenswert?

1
#define F_CPU    8000000UL
2
#define  BAUDRATE  19200
3
#define  PRESCALE  16
4
5
#include <avr/io.h>
6
#include <avr/interrupt.h>
7
8
uint16_t BIT_TIME = ((F_CPU / BAUDRATE / PRESCALE)-1);  //Bitrate definieren
9
10
/*******************************************/
11
void UART_INIT (void)
12
{
13
  LINBRRH  |= (unsigned char)(((unsigned short)BIT_TIME)>>8);
14
  LINBRRL  |= (unsigned char) ((unsigned short)BIT_TIME);
15
16
  LINCR  |= (1<<LENA);    //UART enablen
17
18
  LINCR  |= (1<<LCMD2);    //
19
  LINCR  |= (1<<LCMD1);    //full duplex
20
  LINCR  |= (1<<LCMD0);      //
21
}
22
/*******************************************/
23
unsigned char UART_RX (void)
24
{   
25
  while (LINSIR & (1 << LBUSY));
26
  return LINDAT;
27
  while ((LINSIR & (1<<LRXOK)));
28
}
29
void UART_TX (unsigned char data)
30
{
31
    while (LINSIR & (1 << LBUSY));
32
  LINDAT  = data;
33
  while (!(LINSIR & (1<<LTXOK)));  
34
}
35
void TX_UART (void)
36
{
37
  UART_TX (0xFF);
38
}
39
/*******************************************/
40
int main (void)
41
{
42
  PORTA &= ~(1<<PA1);          //TX
43
  
44
  UART_INIT();
45
46
  sei();
47
48
    while(1)
49
    {
50
    }
51
}
52
ISR(LIN_TC_vect)
53
{
54
cli();
55
56
  TX_UART();
57
58
sei();
59
}

Hallo liebe Forengemeinde,

ich hoffe ihr könnt mir helfen. Ich benutze einen attiny87 im UART mode. 
Oben ist der jeweilige code und im Bild sieht mann das Ergebnis am 
TX-pin. Mein Problem ist folgendes: Wie im Bild ersichtlich, geb ich 
ist mein ganzes Signal 1,14 ms lang. Das LOW vorne (start bit vom UART) 
ist jedoch 104 µs lang. Im Datenblatt steht das standardmäßig 8,N,1 
vorhanden ist. Das Problem ist jedoch, dass ich dort 11 Bit habe, 
anstatt 10. Normal ist ja Startbit - 8 Datenbit - 1 Stopbit.
Guck ich mir am PC an was ankommt ist alles i.O., jedoch muss ich genau 
werden und wirklich die einzelne Bitlänge von 100µs haben, also 
komplette Signallänge von 1000µs und nicht 1100µs.
Hat jemand von euch schon mit dem 87er gearbeitet und kennt nen Trick? 
Mit nem Mega ist das alles kein Thema, aber mit dem tiny hab ich echt 
Schwierigkeiten. Falls Fragen kommen, ich muss den tiny verwenden (hat 
persönliche Gründe).

Wäre echt Dankbar über jegliche Hilfestellung.

Gruß,
Mario

von Uwe (de0508)


Lesenswert?

Hallo,
1
unsigned char UART_RX (void)
2
{   
3
  while (LINSIR & (1 << LBUSY));
4
  return LINDAT;
5
  while ((LINSIR & (1<<LRXOK)));
6
}

ist dir klar, dass bei diesen Code nur die ersten zwei beiden 
Anweisungen ausgeführt werden.

von g457 (Gast)


Lesenswert?

> Das LOW vorne (start bit vom UART) ist jedoch 104 µs lang.

Das LOW heisst Startsymbol (auch Startbit) und ist (genau) ∗doppel∗t so 
lang als wie erwartet.

Hast Du irrgendwo was mit Prescaler durcheinandergewürfelt? Oder der 
Baudrate? Bei 19200 Bd/s kommst Du nicht auf die erhofften 100µs/Symbol 
sondern auf etwa 52µs.

von Uwe (de0508)


Lesenswert?

Hallo,

ich habs gefunden:

Abschnitt "15.5.6.1 Baud rate" Generator im Datenblatt

The baud rate is defined to be the transfer rate in bits per second 
(bps):
• BAUD: Baud rate (in bps),
• fclki/o: System I/O clock frequency,
• LDIV[11:0]: Contents of LINBRRH & LINBRRL registers - (0-4095), the 
pre-scaler receives
clki/o as input clock.
• LBT[5:0]: Least significant bits of - LINBTR register- (0-63) is the 
number of samplings in a
LIN or UART bit (default value 32).

Also ist der Teiler 32, es gilt RTFM.

von Mario M. (mario105)


Lesenswert?

Hey

@g457

Danke für deine Antwort. Da haste Recht, bei 19200 baud hätte ich ca. 
52µs, was dementsprechend die doppelte Länge von 104µs des Startbits 
ausmacht (warum auch immer). Werde gleich versuchen das in Ordnung zu 
bringen.

@Uwe S.

Danke auch dir. Ich probiers mit dem defaultwert von 32 aus, versuche 
alle andere mit anzupassen und meld mich danach noch mal.

MfG,
Mario

von Uwe (de0508)


Lesenswert?

Hallo Mario,

wenn Du nach dem Datenblatt arbeitest, resp. programmierst, funktioniert 
ein Programm richtig.

Trial and error ist nicht notwendig, nur die Verifizierung des 
Ergebnisses.

Da ich den attiny87 nur aus dem Datenblatt und 10 Minuten lesen kenne 
und mir die Uartbefehlsabfolgen angesehen habe, musst Du auch hier noch 
nachbessern:
1
unsigned char UART_RX (void) {..}
2
void UART_TX (unsigned char data) {..}

Dies Code in |ISR(LIN_TC_vect)| ist auch unüblich, warum machst Du so 
etwas ?
1
ISR(LIN_TC_vect) {
2
cli(); 
3
  TX_UART();
4
sei(); }

von Julian W. (julian-w) Benutzerseite


Lesenswert?

falsches Forum...

von Uwe (de0508)


Lesenswert?

Julian W.  kannst Du das erklären ?

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.