Forum: Mikrocontroller und Digitale Elektronik Attiny1616 USART Verständnissproblem


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Theo F. (avr_9595)


Bewertung
0 lesenswert
nicht 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:
#include <atmel_start.h>
#include <usart_basic.h>
#include <util/delay.h>

int main(void)
{
  /* Initializes MCU, drivers and middleware */
  atmel_start_init();

  /* Replace with your application code */
  while (1) {
    USART_0_write(55);
    _delay_ms(1000);
  }
}


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

Der USART ist wie folgt initalisiert, baud ist 9600:
void USART_0_initialization(void)
{

  // Set pin direction to input
  PA2_set_dir(PORT_DIR_IN);

  PA2_set_pull_mode(
      // <y> Pull configuration
      // <id> pad_pull_config
      // <PORT_PULL_OFF"> Off
      // <PORT_PULL_UP"> Pull-up
      PORT_PULL_OFF);

  /* set the alternate pin mux */
  PORTMUX.CTRLB |= PORTMUX_USART0_bm;

  // Set pin direction to output

  PA1_set_level(
      // <y> Initial level
      // <id> pad_initial_level
      // <false"> Low
      // <true"> High
      false);

  PA1_set_dir(PORT_DIR_OUT);

  /* set the alternate pin mux */
  PORTMUX.CTRLB |= PORTMUX_USART0_bm;

  USART_0_init();
}

Kann mir jemand dazu kurz weiterhelfen?

von Ingo L. (corrtexx)


Bewertung
0 lesenswert
nicht 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:

Bewertung
0 lesenswert
nicht 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. (stefanus)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,

wenn ich versuche dein Projekt zu kompilieren erhalte ich folgende 
Fehlermeldungen:
Severity  Code  Description  Project  File  Line
Error    address 0x80380e of USART0.elf section `.data' is not within region `data'  USART0    1
Error    address 0x80380e of USART0.elf section `.data' is not within region `data'  USART0    1
Error    address 0x803814 of USART0.elf section `.bss' is not within region `data'  USART0    1
Error    address 0x803814 of USART0.elf section `.bss' is not within region `data'  USART0    1
Error    ld returned 1 exit status  USART0  collect2.exe  0
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)


Bewertung
-1 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Veit D. schrieb:
> "TB3216 - Getting Started with USART"

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

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

#include <avr/io.h>
#include <util/delay.h>
#include <string.h>


void USART0_init(void);
void USART0_sendChar (char c);
void USART0_sendString(const char *str);


void USART0_sendChar(char c)
{
  while (!(USART0.STATUS & USART_DREIF_bm))
  {
    ;
  }
  USART0.TXDATAL=c;
}
void USART0_init (void)
{
    USART0_CTRLB|=(1<<6);/*Transmitter enable*/
    PORTA_DIR|=(1<<1);/*Tx als ouput*/
    PORTMUX_CTRLB|=(1<<0); /*BIT0 gesetzt für alternative pins */
    USART0.BAUD = (uint16_t)USART0_BAUD_RATE(9600);
}
void USART0_sendString(const char *str)
{
  for(size_t i = 0; i < strlen(str); i++)
  {
    USART0_sendChar(str[i]);
  }
}


int main(void)
{
  USART0_init();  
    /* Replace with your application code */
    while (1) 
    {
    USART0_sendString("Hello World!\r\n");
    _delay_ms(500);
    }
}

: Bearbeitet durch User
von S. Landolt (Gast)


Bewertung
1 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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:
void sputchar( uint8_t c )
{
  c = ~c;
  STX_PORT &= ~(1<<STX_BIT);            // start bit
  for (uint8_t i = 10; i; i--) {        // 10 bits
    _delay_us( 1e6 / BAUD );            // bit duration
    if (c & 1)
      STX_PORT &= ~(1<<STX_BIT);        // data bit 0
    else
      STX_PORT |= 1<<STX_BIT;           // data bit 1 or stop bit
    c >>= 1;
  }
}
STX_PORT, STX_BIT sind entsprechend zu definieren und den Pin als 
Ausgang setzen.

von Theo F. (avr_9595)


Bewertung
0 lesenswert
nicht lesenswert
Peter D. schrieb:
> D.h. welche Spannung liegt an PA0?

Anliegende Spannung ist GND Potential.

von S. Landolt (Gast)


Bewertung
0 lesenswert
nicht lesenswert
PA0? Es geht doch um PA2.

von Theo F. (avr_9595)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


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

Kann man das mit dem PORTMUX später machen, wenn alles richtig 
funktoniert?
void USART0_init(void)
{
 PORTB.DIR &= ~PIN3_bm;
 PORTB.DIR |= PIN2_bm;

 USART0.BAUD = (uint16_t)USART0_BAUD_RATE(9600);
 USART0.CTRLB |= USART_TXEN_bm;
}

von Peter D. (peda)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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)


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

von A. B. (Firma: uc++) (mitschreiberin)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

: Bearbeitet durch User
von Joggel E. (jetztnicht)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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.
#define F_CPU 3333333UL

#include <avr/io.h>
#include <util/delay.h>
#include <string.h>

void USART0_init(void);
void USART0_sendChar(char c);
void USART0_sendString(const char *str);

const uint32_t UART_BAUD_RATE = 9600UL;       // gewünschte Baudrate          

constexpr uint16_t calcUBRR (const uint32_t baudrate)
{
  return ( ( (64.0*F_CPU)/(16UL*baudrate) ) +0.5 );
}


int main(void)
{
  USART0_init();
  
  PORTC_DIR = PIN0_bm;
  
    while (1) 
    {
      USART0_sendString("Hello World!\r\n");
      PORTC_OUTTGL = PIN0_bm;
      _delay_ms(1000);
    }
}


void USART0_init(void)
{
  PORTB.DIR &= ~PIN3_bm;    // USART0 RxD
  PORTB.DIR |= PIN2_bm;      // USART0 TxD
    
  USART0.BAUD = calcUBRR(UART_BAUD_RATE);

  USART0.CTRLB |= USART_TXEN_bm;
}

void USART0_sendChar(char c)
{
  while (!(USART0.STATUS & USART_DREIF_bm))
  {
    ;
  }
  USART0.TXDATAL = c;
}

void USART0_sendString(const char *str)
{
  for(size_t i = 0; i < strlen(str); i++)
  {
    USART0_sendChar(str[i]);
  }
}

von Peter D. (peda)


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

von Veit D. (devil-elec)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.