Forum: Mikrocontroller und Digitale Elektronik ATtiny3217 UART Schnittstelle


von Droid E. (eedroid)


Lesenswert?

Hallo,

ich versuche gerade zum ersten Mal die UART Schnittstelle von einem 
ATtiny3217 in Betrieb zu nehmen. Ich bekomme wie gewollt im Sekundentakt 
meine Daten, allerdings bekomme ich immer eine 0 anstatt einen 
fortlaufen Zählerwert.

Verwendete Hardware:
- ATtiny3217 xplained pro
- RS485 xplained pro
- USB auf Seriell Adapter
https://www.amazon.de/gp/product/B007VZY4CW/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1

Verwendete Software
HTerm
Port: COM5; Baud: 9600; Data: 8 Bit; Stop: 1; Parity: Even

Zuerst natürlich die Stellungen von der Brücken auf der RS485 Platine:
To configure the RS-485 board for this application example:
1. Install jumper between pins 2 and 3 on J101.
- This enables the TE pin to manage both DE and RE for Half-Duplex 
operation.
2. Install jumper between pins 3 and 4 on J102.
- This removes the Profibus Termination for A/B.
3. Install jumper between pins 1 and 2 on J103.
- This removes the Profibus Termination for Z/Y.
4. Install jumpers on J106 and J107.

Als zweiten Schritt die Verbindung zwischen dem RS485 und dem USB 
Adapter, hier habe ich folgende Verdrahtung 
Adapter[RS485+]:XPRO[PIN2(B)] und Adapter[RS485-]:XPRO[PIN3(A)].

UART Initialisierung:
1
#define F_CPU 3333333
2
#define USART0_BAUD_RATE(BAUD_RATE) ((float)(F_CPU * 64 / (16 * (float)BAUD_RATE)) + 0.5)
3
4
void uart_init()
5
{
6
    USART0.BAUD = (uint16_t)USART0_BAUD_RATE(9600);
7
8
    USART0.CTRLA =
9
        (0 << USART_RXCIE_bp)   /* Receive Complete Interrupt */
10
      | (0 << USART_TXCIE_bp)   /* Transmit Complete Interrupt */
11
      | (0 << USART_DREIE_bp)   /* Data Register Empty Interrupt */
12
      | (0 << USART_RXSIE_bp)   /* Receiver Start Frame Interrupt */
13
      | (0 << USART_LBME_bp)    /* Loop-back Mode Enable */
14
      | (0 << USART_ABEIE_bp)   /* Auto-baud Error Interrupt Enable */
15
      | USART_RS485_OFF_gc;     /* RS485 Mode disabled */
16
17
    USART0.CTRLB =
18
        (0 << USART_RXEN_bp)    /* Reciever enable: disabled */
19
      | (1 << USART_TXEN_bp)    /* Transmitter enable: enabled */
20
      | (0 << USART_SFDEN_bp)   /* Start Frame Detection */
21
      | (0 << USART_ODME_bp)    /* Open Drain Mode */
22
      | USART_RXMODE_NORMAL_gc  /* Normal mode */
23
      | (0 << USART_MPCM_bp);   /* Multi-processor Communication Mode */
24
25
    USART0.CTRLC =
26
        USART_CMODE_ASYNCHRONOUS_gc /* Asynchronous Mode */
27
        | USART_PMODE_EVEN_gc       /* Even Parity */
28
        | USART_SBMODE_1BIT_gc      /* 1 stop bit */
29
        | USART_CHSIZE_8BIT_gc;     /* Character size: 8 bit */
30
}

UART Zeichen senden
1
void uart_send(char c)
2
{
3
    while (!(USART0.STATUS & USART_DREIF_bm))
4
        ;
5
6
    USART0.TXDATAL = c;
7
}

Hauptroutine main
1
int main(void)
2
{
3
    char counter = 0;
4
    PORTB.DIR |= PIN4_bm;
5
    PORTB.OUT |= PIN4_bm;
6
7
    // UART XDIR
8
    PORTB.DIR |= PIN7_bm;
9
    PORTB.OUT |= PIN7_bm;
10
11
    uart_init();
12
    
13
    while (1)
14
    {
15
        PORTB.OUT |= PIN4_bm;
16
        _delay_ms(1000);
17
18
        PORTB.OUT &= ~PIN4_bm;
19
        _delay_ms(500);
20
21
        PORTB.OUT &= ~PIN7_bm;
22
        uart_send(++counter);
23
        PORTB.OUT |= PIN7_bm;
24
    }
25
26
    return 0;
27
}

Während ich den Beitrag geschrieben habe, habe ich bei HTerm die Option 
"Show Errors gesehen", Zack: alles rot!?

Vielen Dank für Eure Hilfe!

von wendelsberg (Gast)


Lesenswert?

Droid E. schrieb:
> void uart_send(char c)

Du sendest je ein Byte mit dem Zaehlwert, also 0x00, dann 0x01 usw.
Sieh in der Tabelle nach, was das fue ASCII Zeichen sind.

wendelsberg

von wendelsberg (Gast)


Lesenswert?

Droid E. schrieb:
> Ich bekomme wie gewollt im Sekundentakt

Nein.

wendelsberg

von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

Droid E. schrieb:

> #define USART0_BAUD_RATE(BAUD_RATE) ((float)(F_CPU * 64 / (16 *
> (float)BAUD_RATE)) + 0.5)


F_CPU * 64 ist bereits größer als der Datentyp int auf dem AVR.
Besser wäre m.E.

 (float)(F_CPU)*64.0 / ...

Grüßle
Volker

von Droid E. (eedroid)


Lesenswert?

wendelsberg schrieb:
> Droid E. schrieb:
>> void uart_send(char c)
>
> Du sendest je ein Byte mit dem Zaehlwert, also 0x00, dann 0x01 usw.
> Sieh in der Tabelle nach, was das fue ASCII Zeichen sind.
>
> wendelsberg

Hallo Wendelsberg,

ich verstehe leider deinen Einwand hier nicht. Der Zähler ist als "char" 
doch genau ein Byte, wo ist das Problem?

von Droid E. (eedroid)


Lesenswert?

Volker B. schrieb:
> Droid E. schrieb:
>
>> #define USART0_BAUD_RATE(BAUD_RATE) ((float)(F_CPU * 64 / (16 *
>> (float)BAUD_RATE)) + 0.5)
>
>
> F_CPU * 64 ist bereits größer als der Datentyp int auf dem AVR.
> Besser wäre m.E.
>
>  (float)(F_CPU)*64.0 / ...
>
> Grüßle
> Volker

Hallo Volker, ich habe nun den errechneten Wert von 1389 direkt in das 
Register geschrieben:
1
USART0.BAUD = 1389;

Problem besteht leider immer noch.

von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

Droid E. schrieb:

> Problem besteht leider immer noch.

Wenn mich nicht alles täuscht, musst Du den TxD-Pin auch noch explizit 
als Ausgang konfigurieren.

Grüßle
Volker

von S. Landolt (Gast)


Lesenswert?

Wird es vielleicht besser, wenn counter mit 'A' startet statt mit 0?

von Droid E. (eedroid)


Lesenswert?

S. Landolt schrieb:
> Wird es vielleicht besser, wenn counter mit 'A' startet statt mit 0?

Ich übertrage anstatt eines Counters, jetzt einfach nur 'A'
1
//uart_send(++counter);
2
uart_send('A');

Und außerdem zeigt HTerm die empfangenen Werte als ASCII  Hex  Dec / 
Bin an. In allen steht immer eine Null und außerdem zeigt HTerm auch an 
das der empfangende Datensatz einen Fehler an.

von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

Datenblatt lesen und Punkt 2. beachten...

> 24.3.1 Initialization
> For setting the USART in Full-Duplex mode, the following initialization
> sequence is recommended:
> 1. Set the TxD pin value high, and optionally set the XCK pin low (OUT[n]  > in 
PORTx.OUT).
> 2. Set the TxD and optionally the XCK pin as an output (DIR[n] in
> PORTx.DIR).
> 3. Set the baud rate (in the USARTn.BAUD register) and frame format.
> 4. Set the mode of operation (enables XCK pin output in Synchronous mode).
> 5. Enable the transmitter or the receiver, depending on the usage.

Grüßle
Volker

von Droid E. (eedroid)


Lesenswert?

Volker B. schrieb:
> Wenn mich nicht alles täuscht, musst Du den TxD-Pin auch noch explizit
> als Ausgang konfigurieren.
>
> Grüßle
> Volker


Hallo Volker,

ich habe vor dem Aufruf von uart_init jetzt folgendes hinzugefügt:

[code]
PORTB.DIRSET = PIN2_bm; // TX
PORTB.DIRCLR = PIN3_bm; // RX
PORTB.DIR |= PIN7_bm;   // XDIR
[code]

Leider immer noch keine Besserung.

von Droid E. (eedroid)


Angehängte Dateien:

Lesenswert?

Anbei noch ein Screenshot von HTerm, weil der Haken "Show Errors" 
angewählt ist, wird alles Rot dargestellt.

Beitrag #6603355 wurde vom Autor gelöscht.
von Droid E. (eedroid)


Lesenswert?

Volker B. schrieb:
> Datenblatt lesen und Punkt 2. beachten...

Full-Duplex?

von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

Droid E. schrieb:

> ich habe vor dem Aufruf von uart_init jetzt folgendes hinzugefügt:
>
> [code]
> PORTB.DIRSET = PIN2_bm; // TX
> PORTB.DIRCLR = PIN3_bm; // RX
> PORTB.DIR |= PIN7_bm;   // XDIR
> [code]

RxD sollte nach dem Reset bereits als Eingang konfiguriert sein. XDIR 
nutzt Du nicht, muss also auch nicht initialisiert werden.

Da das Ausgangsregister des TxD-Pins mit 0 initialisiert ist, empfängt 
Dein PC ein Startbit, sobald Du TxD als Ausgang konfigurierts. Also 
besser den Pin zuerst auf 1 setzten, wie's das Datenblatt vorschlägt.

Grüßle
Volker

von S. Landolt (Gast)


Lesenswert?

Die Hardware ist mir unbekannt, aber könnte es sein, dass da eine 
Invertierung des Signals fehlt?

von Droid E. (eedroid)


Lesenswert?

Volker B. schrieb:
> Da das Ausgangsregister des TxD-Pins mit 0 initialisiert ist, empfängt
> Dein PC ein Startbit, sobald Du TxD als Ausgang konfigurierts. Also
> besser den Pin zuerst auf 1 setzten, wie's das Datenblatt vorschlägt.
>
> Grüßle
> Volker

Es tut mir leid, aber im Moment kann ich dir nicht folgen! Wann und wie 
sollte ich denn jetzt die entsprechenden Register setzen?

von Droid E. (eedroid)


Lesenswert?

S. Landolt schrieb:
> Die Hardware ist mir unbekannt, aber könnte es sein, dass da eine
> Invertierung des Signals fehlt?

Hallo Landolt,

wie gehe ich dabei vor? Bzw. wie macht man das denn sonst?

von c-hater (Gast)


Lesenswert?

Droid E. schrieb:

> Anbei noch ein Screenshot von HTerm, weil der Haken "Show Errors"
> angewählt ist, wird alles Rot dargestellt.

Das bedeutet, dass die PC-UART bei jedem einzelnen Byte irgendwelche 
Empfangsfehler gemeldet hat. Da die empfangenen Inhalte durchgängig Null 
sind, könnte man darauf tippen, dass die Baudrate des Sender viel zu 
gering ist, in Wirklichkeit also nur das Startbit 10 mal abgetastet 
wurde, wobei die 10te Abtastung einen Frame-Error ausgelöst hat, denn 
das Stopbit hätte als 1 abgetastet werden müssen.

Sehr wahrscheinlich hast du also bei der Initialisierung der 
Baudrate-Registers auf AVR-Seite nicht berücksichtigt, dass das Teil bei 
den modernen AVR8-UARTs einen fraktionalen Teiler mit 6 binären 
Nachkommastellen darstellt, deine Baudrate also jetzt um den Faktor 64 
zu gering ist...

von S. Landolt (Gast)


Lesenswert?

> wie gehe ich dabei vor?
Ich hätte jetzt als Schnellschuss den TxD-Pin per Software invertiert; 
das sollte zumindest weitere Erkenntnis bringen.

von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

S. Landolt schrieb:
> Die Hardware ist mir unbekannt, aber könnte es sein, dass da eine
> Invertierung des Signals fehlt?

Gute Idee. Ich sehe jetzt erst, dass der TO RS485 verwenden will. Warum 
er dann den USART wie folgt konfiguriert, verstehe ich nicht wirklich 
:-(

> USART0.CTRLA =
(...)
> USART_RS485_OFF_gc;     /* RS485 Mode disabled */

Vielleicht sollte er erst mal mit RS232 anfangen...

Grüßle
Volker.

von S. Landolt (Gast)


Lesenswert?

Hallo c-hater,
was ist denn an
> USART0.BAUD = 1389;
falsch?

von c-hater (Gast)


Lesenswert?

S. Landolt schrieb:

>> USART0.BAUD = 1389;
> falsch?

Was war CLK_PER?

von Droid E. (eedroid)


Lesenswert?

Volker B. schrieb:
> Vielleicht sollte er erst mal mit RS232 anfangen...

Wie genau müssen denn jetzt die Register konfiguriert werden?

von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

Droid E. schrieb:
> Volker B. schrieb:
>> Vielleicht sollte er erst mal mit RS232 anfangen...
>
> Wie genau müssen denn jetzt die Register konfiguriert werden?

Zeig' zuerst mal Deinen Aufbau. Wie sind ATtiny und PC verbunden?
Mir wird's so langsam zu blöde...

Grüßle
Volker

von c-hater (Gast)


Lesenswert?

Droid E. schrieb:

> Wie genau müssen denn jetzt die Register konfiguriert werden?

Ich bevorzuge: Richtig (im Sinne der jeweiligen Anwendung).

von Droid E. (eedroid)


Lesenswert?

Volker B. schrieb:
> Zeig' zuerst mal Deinen Aufbau. Wie sind ATtiny und PC verbunden?
> Mir wird's so langsam zu blöde...
>
> Grüßle
> Volker

Hallo Volker,

meinst du folgenden Teil:

Verwendete Hardware:
- ATtiny3217 xplained pro
- RS485 xplained pro
- USB auf Seriell Adapter
https://www.amazon.de/gp/product/B007VZY4CW/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1

Verwendete Software
HTerm
Port: COM5; Baud: 9600; Data: 8 Bit; Stop: 1; Parity: Even

Adapter[RS485+] mit XPRO[PIN2(B)] und Adapter[RS485-] mit XPRO[PIN3(A)]

von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

Droid E. schrieb:

> Adapter[RS485+] mit XPRO[PIN2(B)] und Adapter[RS485-] mit XPRO[PIN3(A)]

Mach' ein Foto. Deine "Prosa" sagt mir nichts!

Grüßle
Volker

von S. Landolt (Gast)


Lesenswert?

Zugegeben, ich habe keine Ahnung, wieviel es bringen könnte, aber wollen 
Sie nicht doch eben mal schnell diese Invertierung versuchen, kostet ja 
keine Minute? PORTB.PIN2CTRL=0x80?

von Droid E. (eedroid)


Angehängte Dateien:

Lesenswert?

S. Landolt schrieb:
> Zugegeben, ich habe keine Ahnung, wieviel es bringen könnte, aber wollen
> Sie nicht doch eben mal schnell diese Invertierung versuchen, kostet ja
> keine Minute? PORTB.PIN2CTRL=0x80?

Was auch immer du möchtest ;)

Ich bekomme in der tat jetzt ein 'A' allerdings immer mit einer Null 
abwechselnd und außerdem verstehe ich nicht warum HTerm mir diese alle 
mit Fehler anzeigt.

: Bearbeitet durch User
von S. Landolt (Gast)


Lesenswert?

Schön, wenigstens ein Stückchen weiter. Ich darf mich verabschieden, 
schönes Wochenende!

von Droid E. (eedroid)


Angehängte Dateien:

Lesenswert?

> Mach' ein Foto. Deine "Prosa" sagt mir nichts!
>
> Grüßle
> Volker

Wenn das nicht ausreicht kann ich auch gerne ein Foto ohne Verkabelung 
senden, auch gerne von der Rückseite.

von Droid E. (eedroid)


Lesenswert?

S. Landolt schrieb:
> Schön, wenigstens ein Stückchen weiter. Ich darf mich verabschieden,
> schönes Wochenende!

:(

von S. Landolt (Gast)


Lesenswert?

Sie haben das richtig verstanden, dieses 'PORTB.PIN2CTRL=0x80' gehört in 
die Initialisierung?

Jetzt muss ich endgültig weg.

von Droid E. (eedroid)


Lesenswert?

S. Landolt schrieb:
> Sie haben das richtig verstanden, dieses 'PORTB.PIN2CTRL=0x80' gehört in
> die Initialisierung?
>
> Jetzt muss ich endgültig weg.

Warum kommt dann immer das 'A' und eine 0 abwechselnd?

von Droid E. (eedroid)


Angehängte Dateien:

Lesenswert?

>> Adapter[RS485+] mit XPRO[PIN2(B)] und Adapter[RS485-] mit XPRO[PIN3(A)]
>
> Mach' ein Foto. Deine "Prosa" sagt mir nichts!
>
> Grüßle
> Volker

So,

nun ein Foto von
- Vorderseite
- Rückseite
- Adapter

von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

Droid E. schrieb:

> nun ein Foto von
> - Vorderseite
> - Rückseite
> - Adapter

OK, Du willst also via RS485 kommunizieren. Warum schreibst Du das nicht 
explizit?

Kannst Du mir dann bitte erklären, warum Du in der MCU den RS485-Modus 
deaktivierst (letzte Zeile)?

>    USART0.CTRLA =
>        (0 << USART_RXCIE_bp)   /* Receive Complete Interrupt */
>     | (0 << USART_TXCIE_bp)   /* Transmit Complete Interrupt */
>     | (0 << USART_DREIE_bp)   /* Data Register Empty Interrupt */
>     | (0 << USART_RXSIE_bp)   /* Receiver Start Frame Interrupt */
>     | (0 << USART_LBME_bp)    /* Loop-back Mode Enable */
>     | (0 << USART_ABEIE_bp)   /* Auto-baud Error Interrupt Enable */
>     | USART_RS485_OFF_gc;     /* RS485 Mode disabled */

Liest Du eigentlich die Kommentare, die Du in Deinen eigenen Code 
schreibst oder sind das Write-Only-Kommentare?

Dann zur Verdrahtung. A gehört auf + und B auf -
Wenn man's andersherum macht, gibt's Probleme, wie Du ja selber bereits 
festgestellt hat. Die Invertierung des Signals ist keine wirklich gute 
Idee. Hinweis: Einfach mal ins Datenblatt der verbauten 
RS485-Transceiver gucken. Wenn man nach Trial&Error verdrahtet, sollte 
man auch den Error-Fall erkennen können.

Dann sollte die Masse der RS485-Busteilnehmer ebenfalls verbunden 
werden.

Auch sollte sichergestellt sein, dass der Bus im Ruhezustand im 
inaktivem Zustand ist. Dazu sollte eines der Interfaces am Bus mit 
entsprechenden Widerständen beschaltet werden. Such' mal unter den 
Stichworten "RS485" und "Bias". Ob das eine der von Dir verwendeten 
Baugruppen macht, weiß ich nicht und ich recherchiere das auch nicht für 
Dich.

Grüßle
Volker

: Bearbeitet durch User
von S. Landolt (Gast)


Lesenswert?

> Die Invertierung des Signals ist keine wirklich gute Idee
Sollte ja auch keine dauerhafte Lösung sein, sondern nur zur Abklärung 
dienen. Bevor da wieder jemand von Faktor 64 oder CLK_PER schwadroniert 
...

von Uwe (Gast)


Lesenswert?

Hi,
jetzt muss ich mal dumm fragen, dein
>- RS485 xplained pro soll ja Halbduplex laufen. Erzeugt das Modul das Dir Signal 
selber oder müsste das von deinem AVR kommen? Irgendwer muss es jedenfalls 
erzeugen. Sollte es der Adapter selber machen könnte die Zeile
>     | USART_RS485_OFF_gc;     /* RS485 Mode disabled */
sogar Sinn machen, wobei ich mir da jetzt erstmal das DB reinziehen 
müsste.
Viel Erfolg, Uwe

von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

S. Landolt schrieb:
>> Die Invertierung des Signals ist keine wirklich gute Idee
> Sollte ja auch keine dauerhafte Lösung sein,

Stimmt, ich wäre nicht auf die Idee gekommen, dass jemand RS485 so 
merkwürdig verdrahtet.

> (...) sondern nur zur Abklärung
> dienen. Bevor da wieder jemand von Faktor 64 oder CLK_PER schwadroniert
> ...

Ja, unser lieber Hassknecht... ;-)

Grüßle
Volker

von Droid E. (eedroid)


Lesenswert?

Volker B. schrieb:
> Stimmt, ich wäre nicht auf die Idee gekommen, dass jemand RS485 so
> merkwürdig verdrahtet.

Ich wollte mich noch bei euch allen dafür bedanken dass ihr mir geholfen 
habt, ich hoffe das ich der Community in Zukunft ebenfalls helfen kann, 
danke und Daumen hoch :)

: Bearbeitet durch User
von Spess53 (Gast)


Lesenswert?

Hi

Beitrag "Re: ATtiny3217 UART Schnittstelle"

Da sind nur 2 Letungen angeschlossen. RS485 erfordert aber noch eine 
Masseleitung.

AN-1057 Ten Ways to Bulletproof RS-485 Interfaces (Texas):

A typical mistake is to connect two nodes with only two
wires.

MfG Spess

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.