Forum: Mikrocontroller und Digitale Elektronik Attiny1616 USART Verständnissproblem


von Theo F. (avr_9595)


Lesenswert?

Werte Community,

Ich habe ein kleines Problem und ersuche eure Hilfe.
Ich bin relativ neu in der avr Welt und versuche mit einem ATTiny1616 zu 
starten. Zunächst möchte ich einfach über den USART etwas senden.
Hierzu habe ich mit Atmel Start den USART eingerichtet.
Anschließend sieht meine main relativ simpel aus:
1
#include <atmel_start.h>
2
#include <usart_basic.h>
3
#include <util/delay.h>
4
5
int main(void)
6
{
7
  /* Initializes MCU, drivers and middleware */
8
  atmel_start_init();
9
10
  /* Replace with your application code */
11
  while (1) {
12
    USART_0_write(55);
13
    _delay_ms(1000);
14
  }
15
}

Leider empfange Ich weder über RS232 oder Oszi irgendetwas auf dem TX 
Port.

Der USART ist wie folgt initalisiert, baud ist 9600:
1
void USART_0_initialization(void)
2
{
3
4
  // Set pin direction to input
5
  PA2_set_dir(PORT_DIR_IN);
6
7
  PA2_set_pull_mode(
8
      // <y> Pull configuration
9
      // <id> pad_pull_config
10
      // <PORT_PULL_OFF"> Off
11
      // <PORT_PULL_UP"> Pull-up
12
      PORT_PULL_OFF);
13
14
  /* set the alternate pin mux */
15
  PORTMUX.CTRLB |= PORTMUX_USART0_bm;
16
17
  // Set pin direction to output
18
19
  PA1_set_level(
20
      // <y> Initial level
21
      // <id> pad_initial_level
22
      // <false"> Low
23
      // <true"> High
24
      false);
25
26
  PA1_set_dir(PORT_DIR_OUT);
27
28
  /* set the alternate pin mux */
29
  PORTMUX.CTRLB |= PORTMUX_USART0_bm;
30
31
  USART_0_init();
32
}

Kann mir jemand dazu kurz weiterhelfen?

von Ingo L. (corrtexx)


Lesenswert?

Tobias D. schrieb:
> Kann mir jemand dazu kurz weiterhelfen?
Vermutlich nicht, da keiner weiß, was in den Funktionen wirklich 
abläuft, da der Registerzugriff einem ja verborgen bleibt.

von Theo F. (avr_9595)


Angehängte Dateien:

Lesenswert?

Ingo L. schrieb:
> Tobias D. schrieb:
>> Kann mir jemand dazu kurz weiterhelfen?
> Vermutlich nicht, da keiner weiß, was in den Funktionen wirklich
> abläuft, da der Registerzugriff einem ja verborgen bleibt.

Hallo Ingo,

deswegen habe ich ja vorher auf Atmel Start hingewiesen.
Die libary die daraus generiert wird ist ja ein " Standard" Teil.

aber um mir weiterhelfen zu können, welche infomrationen brauchst du?
Anbei das projekt gezippt.

von Stefan F. (Gast)


Lesenswert?

Theo F. schrieb:
> deswegen habe ich ja vorher auf Atmel Start hingewiesen.
> Die libary die daraus generiert wird ist ja ein " Standard" Teil.

Das schon, allerdings nutzen das nur wenige Entwickler. Die meisten 
bevorzugen bei 8bit Controllern direkte Registerzugriffe - ist mein 
Endruck.

von Peter D. (peda)


Lesenswert?

Mit den neuen tinyAVR®1 und dem Atmel Start kennen sich wohl die 
wenigsten aus.
Ich hatte bisher keine Notwendigkeit auf die neuen AVR-Familien 
umzusteigen, die sind ja bezüglich der Konfiguration um ein deutliches 
komplizierter.

Theo F. schrieb:
> Anbei das projekt gezippt.

Das USART_0_initialization finde ich darin aber nicht.

Solche Wizzards erzeugen ne ziemliche Menge Holz, da ist schwer 
durchzusehen. Daß dann auch noch der Code in viele Unterverzeichnisse 
verteilt ist, macht die Sache noch schwerer.

: Bearbeitet durch User
von Theo F. (avr_9595)


Lesenswert?

Peter D. schrieb:
> Das USART_0_initialization finde ich darin aber nicht.

Sollte eigentlich zu finden sein. Mein Problem ist, dass ich den Attiny 
auch für diverse QTouch Projekte nutzen will und spätestens da halte ich 
atmel start für sinnvoll.
Kann wirklich keiner weiterhelfen?

von Veit D. (devil-elec)


Lesenswert?

Hallo,

wenn ich versuche dein Projekt zu kompilieren erhalte ich folgende 
Fehlermeldungen:
1
Severity  Code  Description  Project  File  Line
2
Error    address 0x80380e of USART0.elf section `.data' is not within region `data'  USART0    1
3
Error    address 0x80380e of USART0.elf section `.data' is not within region `data'  USART0    1
4
Error    address 0x803814 of USART0.elf section `.bss' is not within region `data'  USART0    1
5
Error    address 0x803814 of USART0.elf section `.bss' is not within region `data'  USART0    1
6
Error    ld returned 1 exit status  USART0  collect2.exe  0
7
Error    recipe for target 'USART0.elf' failed  USART0  C:\Users\Devil\Documents\USART0\USART0\Debug\Makefile  247

Atmel Start ist eigentlich nur zur Controller Konfiguration gedacht. 
Hast darin ein usart Example gefunden? Ich würde mich erstmal an die App 
Notes halten. Auf der Dokuseite vom ATtiny1616 wirst du dann unter 
anderem eine "TB3216 - Getting Started with USART" finden.

: Bearbeitet durch User
von c-hater (Gast)


Lesenswert?

Peter D. schrieb:

> Ich hatte bisher keine Notwendigkeit auf die neuen AVR-Familien
> umzusteigen, die sind ja bezüglich der Konfiguration um ein deutliches
> komplizierter.

Eigentlich nicht komplizierter, zumindest nicht viel.

Im Wesentlichen halt nur etwas anders. Andere Register (weil effektiv 
die XMega-Peripherie) und andere Namenskonventionen für die Symbole. Das 
einzige, was die Sache substantiell tatsächlich etwas komplizierter 
macht, ist das Portmapping. Das gab's aber teilweise auch schon bei den 
"Classic-Tinys", z.B. beim 441/841.

von Theo F. (avr_9595)


Lesenswert?

Veit D. schrieb:
> "TB3216 - Getting Started with USART"

So ich habe mich an die Getting started anleitung gehalten, dennoch kein 
signal..

1
#define USART0_BAUD_RATE(BAUD_RATE) ((float)(3333333 * 64 / (16 *(float)BAUD_RATE)) + 0.5)
2
#define F_CPU 3333333
3
4
#include <avr/io.h>
5
#include <util/delay.h>
6
#include <string.h>
7
8
9
void USART0_init(void);
10
void USART0_sendChar (char c);
11
void USART0_sendString(const char *str);
12
13
14
void USART0_sendChar(char c)
15
{
16
  while (!(USART0.STATUS & USART_DREIF_bm))
17
  {
18
    ;
19
  }
20
  USART0.TXDATAL=c;
21
}
22
void USART0_init (void)
23
{
24
    USART0_CTRLB|=(1<<6);/*Transmitter enable*/
25
    PORTA_DIR|=(1<<1);/*Tx als ouput*/
26
    PORTMUX_CTRLB|=(1<<0); /*BIT0 gesetzt für alternative pins */
27
    USART0.BAUD = (uint16_t)USART0_BAUD_RATE(9600);
28
}
29
void USART0_sendString(const char *str)
30
{
31
  for(size_t i = 0; i < strlen(str); i++)
32
  {
33
    USART0_sendChar(str[i]);
34
  }
35
}
36
37
38
int main(void)
39
{
40
  USART0_init();  
41
    /* Replace with your application code */
42
    while (1) 
43
    {
44
    USART0_sendString("Hello World!\r\n");
45
    _delay_ms(500);
46
    }
47
}

: Bearbeitet durch User
von S. Landolt (Gast)


Lesenswert?

> Zunächst möchte ich einfach über den USART etwas senden.
Dann würde ich jetzt (zähneknirschend) doch einen Schritt zurückgehen 
und an PA2 eine LED blinken lassen.

(ich kenne den ATtiny1616 nicht, aber vom ATmega4809 bzw. AVR128DA 
schließend (also Xmega-Architektur) sieht das Programm okay aus)

von Peter D. (peda)


Lesenswert?

Theo F. schrieb:
> So ich habe mich an die Getting started anleitung gehalten, dennoch kein
> signal..

D.h. welche Spannung liegt an PA0?
Der Code sieht soweit o.k. aus.
Hast Du keine LED auf der Platine, die man zum Debuggen nehmen kann?

Hier mal ne einfache UART in SW:
1
void sputchar( uint8_t c )
2
{
3
  c = ~c;
4
  STX_PORT &= ~(1<<STX_BIT);            // start bit
5
  for (uint8_t i = 10; i; i--) {        // 10 bits
6
    _delay_us( 1e6 / BAUD );            // bit duration
7
    if (c & 1)
8
      STX_PORT &= ~(1<<STX_BIT);        // data bit 0
9
    else
10
      STX_PORT |= 1<<STX_BIT;           // data bit 1 or stop bit
11
    c >>= 1;
12
  }
13
}
STX_PORT, STX_BIT sind entsprechend zu definieren und den Pin als 
Ausgang setzen.

von Theo F. (avr_9595)


Lesenswert?

Peter D. schrieb:
> D.h. welche Spannung liegt an PA0?

Anliegende Spannung ist GND Potential.

von S. Landolt (Gast)


Lesenswert?

PA0? Es geht doch um PA2.

von Theo F. (avr_9595)


Lesenswert?

S. Landolt schrieb:
> PA0? Es geht doch um PA2.

Tut mir leid, ich habe das überlesen und denke meinem Vorredner geht es 
da ebenso. Ja an PA2 liegt GND

von S. Landolt (Gast)


Lesenswert?

> Ja an PA2 liegt GND
Also klappt schon die Initialisierung nicht. Es sei denn, es liegt ein 
Verdrahtungsfehler vor (der sich mit der blinkenden LED feststellen 
ließe). Wie sieht es ohne Umlenkung, also mit PB2 als TxD, aus?

von Georg M. (g_m)


Lesenswert?

Theo F. schrieb:
>
1
> void USART0_init (void)
2
> {
3
>     USART0_CTRLB|=(1<<6);/*Transmitter enable*/
4
>     PORTA_DIR|=(1<<1);/*Tx als ouput*/
5
>     PORTMUX_CTRLB|=(1<<0); /*BIT0 gesetzt für alternative pins */
6
>     USART0.BAUD = (uint16_t)USART0_BAUD_RATE(9600);
7
> }
8
>

Kann man das mit dem PORTMUX später machen, wenn alles richtig 
funktoniert?
1
void USART0_init(void)
2
{
3
 PORTB.DIR &= ~PIN3_bm;
4
 PORTB.DIR |= PIN2_bm;
5
6
 USART0.BAUD = (uint16_t)USART0_BAUD_RATE(9600);
7
 USART0.CTRLB |= USART_TXEN_bm;
8
}

von Peter D. (peda)


Angehängte Dateien:

Lesenswert?

Theo F. schrieb:
> S. Landolt schrieb:
>> PA0? Es geht doch um PA2.
>
> Tut mir leid, ich habe das überlesen und denke meinem Vorredner geht es
> da ebenso. Ja an PA2 liegt GND

Lt. Datenblatt aber PA1.

von S. Landolt (Gast)


Lesenswert?

> Lt. Datenblatt aber PA1.
In der Tat - da war die Verwirrung komplett. Entschuldigung.

von A. B. (Gast)


Angehängte Dateien:

Lesenswert?

Danke für das USART0.zip

In AtmelStudio7 kompiliert das Projekt mit avr-gcc9.3.0 und iotn1616.h 
von 
https://raw.githubusercontent.com/stateos/IntrOS-ATtiny817-Xplained-Mini/master/avr/iotn1616.h

Testen kann ich leider nicht, weil ich den tiny1616 nicht besitze. 
USART0.lss und USART0.elf im Anhang.

Mein erster Eindruck:
Für mich ist das ein kompliziertes C-Programm in pseudo c++-style.

von Pandur S. (jetztnicht)


Lesenswert?

also, das Ganze ist doch eher einfach. Eine Library bringt eigentlich 
nichts, Flupp - in die Tonne

- Rxpin als Input  (DDRx)
- TxPin als Output (DDRx)
- PortControlRegister setzen (Baud, Parity, 2x, ..)
- Baudrate setzen. (BRRH & BRRL)
- auf UART Schreiben (UDRx)

Und dann mit dem Oszilloskop schauen. Dann ist vielleicht die Baudrate 
noch falsch.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

ich habs mal von meinem ATmega4808 rübergebrochen auf den ATtiny1616. 
Usart.0 erstmal auf Standard Pins PB2/PB3 und zusätzlich blinkt an PC0 
eine Led oder dergleichen. Wenn Theo nicht an den Fuse gefummelt hat, 
taktet der interne 20MHz RC mit Default Prescaler 6, was besagte 3,33MHz 
ergibt. Das muss funktionieren wenn alles normal angeklemmt ist. Wenn 
das und die anderen Codes nicht funktionieren, dann liegt der Fehler 
außerhalb unseres Sichtbereiches. Spätestens dann solltest du den 
Blinktakt vermessen. Ub sollten min. 3,3V sein, Abblockkondensatoren 
sind hoffentlich dran.
1
#define F_CPU 3333333UL
2
3
#include <avr/io.h>
4
#include <util/delay.h>
5
#include <string.h>
6
7
void USART0_init(void);
8
void USART0_sendChar(char c);
9
void USART0_sendString(const char *str);
10
11
const uint32_t UART_BAUD_RATE = 9600UL;       // gewünschte Baudrate          
12
13
constexpr uint16_t calcUBRR (const uint32_t baudrate)
14
{
15
  return ( ( (64.0*F_CPU)/(16UL*baudrate) ) +0.5 );
16
}
17
18
19
int main(void)
20
{
21
  USART0_init();
22
  
23
  PORTC_DIR = PIN0_bm;
24
  
25
    while (1) 
26
    {
27
      USART0_sendString("Hello World!\r\n");
28
      PORTC_OUTTGL = PIN0_bm;
29
      _delay_ms(1000);
30
    }
31
}
32
33
34
void USART0_init(void)
35
{
36
  PORTB.DIR &= ~PIN3_bm;    // USART0 RxD
37
  PORTB.DIR |= PIN2_bm;      // USART0 TxD
38
    
39
  USART0.BAUD = calcUBRR(UART_BAUD_RATE);
40
41
  USART0.CTRLB |= USART_TXEN_bm;
42
}
43
44
void USART0_sendChar(char c)
45
{
46
  while (!(USART0.STATUS & USART_DREIF_bm))
47
  {
48
    ;
49
  }
50
  USART0.TXDATAL = c;
51
}
52
53
void USART0_sendString(const char *str)
54
{
55
  for(size_t i = 0; i < strlen(str); i++)
56
  {
57
    USART0_sendChar(str[i]);
58
  }
59
}

von Peter D. (peda)


Lesenswert?

Da er sich nicht mehr meldet, wird er vermutlich nun an PA1 gemessen 
haben.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

ich vermute er war nur am falschen Pin. Es gibt 4 Gehäusevarianten und 
laut Tabelle 5.1 alles an verschiedenen Pins. Reine Spekulation. 
Irgendeine kleine Rückmeldung wäre schon schön.

: Bearbeitet durch User
von Bert (Gast)


Lesenswert?

c-hater schrieb:
> Eigentlich nicht komplizierter, zumindest nicht viel.

Nö eigentlich eher gleich bis einfacher. UART quasi gleich, bei I2C z.B. 
wird einem besser unter die Arme gegriffen. Aber es gibt auch eine 
Verschlechterung: Grundsätzlich ist in Peripherie-Interruptroutinen das 
entsprechende Interruptflag manuell zurück zu setzen!

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.