ATtiny3217 UART Schnittstelle

OP #6603232
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!
OP #6603321
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.
OP #6603337
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.
(Firma: L-E-A) #6603340
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
OP #6603351
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.
Beitrag #6603355 wurde von einem Moderator gelöscht.
(Firma: L-E-A) #6603360
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
OP #6603371
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?
Gast #6603376
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...
(Firma: L-E-A) #6603381
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.
OP #6603408
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)]
OP #6603424
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.
Angehängte Dateien:
(Firma: L-E-A) #6603467
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
Gast #6603489
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 
...
Gast #6603497
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
(Firma: L-E-A) #6603498
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren