ATtiny3217 UART Schnittstelle

OP #6603232
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
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?
OP
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
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)
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
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)
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
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
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...
Gast
> wie gehe ich dabei vor?
Ich hätte jetzt als Schnellschuss den TxD-Pin per Software invertiert; 
das sollte zumindest weitere Erkenntnis bringen.
(Firma: L-E-A)
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
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)]
Gast
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?
OP
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)
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
> 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
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)
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

Eine eigene Frage? Dieser Thread ist über 5 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.