Forum: Mikrocontroller und Digitale Elektronik UART mit Atmega16


von padderick (Gast)


Lesenswert?

Hallo Leute,

ich weiss mittlerweile gar nicht mehr mit meinem Problem weiter.

Ich verwende das STK500 mit einem external Chrystal 7,3238Mhz (extra nen 
optimalen RS232 Quarz) und der Jumper auf OCSEL natürlich umgesteckt und 
habe natürlich auch das Fusebit für den externen Takt gesetzt.

Pins vom PD0 und PD1 auf RX und TX sind auch entsprechend gesteckt.
Für die Kommunikation verwende ich 2 Serial to USB Adapter von Digitus, 
die auch tadelfrei beim flashen funktionieren.

Ich habe mir einige Beispiele zum verwenden der UARTs durchgelesen und 
das PDF an der entsprechende stelle vom Atm16.

Aber egal was ich mache, es kommt zu gar keinem Datenaustausch. Dazu 
verwende ich die Codestücke aus dem avr-gcc-tutorial zum Thema UART.

Zur simulation im AVR studio(neuste version am Montag installiert):
Ist ja schön das man da die ganzen Register sehen kann, weniger schön 
ist es aber das speziell das UCSRC sich nicht beschreiben lassen will.
UBRR und das UCSRB funktionieren noch tadellos.
(Baudraten 9600 und 19200 ausprobiert)

ich verwende dafür:
1
void uart_init(void)
2
{
3
  UBRRH = UBRR_VAL >> 8;
4
  UBRRL = UBRR_VAL & 0xFF;
5
 
6
  UCSRB |= (1<<TXEN);  // UART TX einschalten
7
  UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);  // Asynchron 8N1 
8
}
Da UCSRC und UBRRH die selbe I/O location haben, muss man sich ja 
zwischen URSEL = 1/0 entscheiden um die jeweiligen Register zu selecten, 
soweit schon klar.
Nach dieser Befehlszeile bleibt das Register jedoch unberührt.
Wenn ich die entsprechenden Flags manuell im UCSRC beschreibe, so werden 
dieselben auch im UBRRH gesetzt O_o, blöder simulationsfehler ?

naja soweit so schlecht...UDR wehrt sich ebenfalls

ich denke mal es liegt schon an dem UCSRC/UBRRH Problem, das 
entsprechend auch das UDR nicht gesetzt werden will.
hierfür verwende ich:
1
    while (!(UCSRA & (1<<UDRE))) 
2
    {
3
    }
4
 
5
    UDR = 'x';
Ich möchte lediglich ein Zeichen bekommen im hterm

Was läuft hier nun Falsch ?


Ultra Dank im Voraus

von spess53 (Gast)


Lesenswert?

Hi

Im 4er Studio gibt es unter Known Issues zum Simulator folgende 
Hinweise:

The USART's UBRRH and UCSRC registers share the same I/O address. 
Writing to one of the registers will cause both registers to contain the 
new value, regardless of the value of URSEL. Reading these registers do 
not work as described in the datasheet.

When writing to UCSRC, the value will be copied to UBRRH unless bit 7 is 
also set in in the same write operation. This behaviour is erroneous on 
devices that have separate locations for these registers. Another 
workaround is to write UBRRH after UCSRC

MfG Spess

von Martin V. (oldmax)


Lesenswert?

Hi
Bisher hab ich mit der Initialisierung, die du hier in den Tutorials 
findest, immer eine Verbindung bekommen. Ist zwar kein C, aber die 
Initialisierung ist analog aufgebaut. Bis auf den Unterschied mit der 
Freigabe für Senden. (UCSRB ist mit UCSRC in der Reihenfolge getauscht.)
Wenn das nix bringt, die üblichen Verdächtigen-
                                 TX Sender geht auf RX Empfänger...
1
 
2
    ldi     temp, HIGH(UBRR_VAL)
3
    out     UBRRH, temp
4
    ldi     temp, LOW(UBRR_VAL)
5
    out     UBRRL, temp
6
 
7
    ; Frame-Format: 8 Bit
8
 
9
    ldi     temp, (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0)
10
    out     UCSRC, temp
11
 
12
    sbi     UCSRB,TXEN                  ; TX aktivieren

Gruß oldmax

: Bearbeitet durch User
von spess53 (Gast)


Lesenswert?

Hi

>Bisher hab ich mit der Initialisierung, die du hier in den Tutorials
>findest, immer eine Verbindung bekommen.

Für AVRs die jünger als ca. 10 Jahre sind bekommst du damit eine 
Fehlermeldung.

MfG Spess

von Martin V. (oldmax)


Lesenswert?

Hi
@Spess53
Nun, seit 10 jahren bin ich noch nicht mit Controllern beschäftigt und 
sogesehen würd mich schon interessieren, wo der Fehler steckt, den du 
hier siehst. Mag ja sein, das die Generation µC die ich verwende zu den 
älteren Generationen gehört, die sich damit noch begnügt haben. Auch 
Studio 4 stört sich nicht daran. Mit Studio 6 hab ich noch nicht 
begonnen, weil mir die Version 4 völlig ausreicht. Und nein, ich wende 
das nicht beruflich an, nur um ein paar unsinnige Antworten zu blocken.
gruß oldmax

: Bearbeitet durch User
von spess53 (Gast)


Lesenswert?

Hi

>Nun, seit 10 jahren bin ich noch nicht mit Controllern beschäftigt und
>sogesehen würd mich schon interessieren, wo der Fehler steckt, den du
>hier siehst.

Das URSEL-Bit gibt es nur bei den 'alten' AVRs. Z.B. ATMega8/16/32. Bei 
den Nachfolgern mit erweitertem IO-Bereich (ATMega88/164/...) ist das 
nicht mehr existent. Also wenn du deinen o.g. Code auf einen ATMega88 
los lässt wird der Assembler meckern. Zu recht.

MfG Spess

von Martin V. (oldmax)


Lesenswert?

Hi
Ok, wieder etwas dazugelernt. Werd ich mir für den 88er merken, denn der 
liegt schon bereit. Ansonsten hab ich eben "nur" die 8er und 16er 
gequält. gruß oldmax

von spess53 (Gast)


Lesenswert?

Hi

>Werd ich mir für den 88er merken, denn der liegt schon bereit.

Dann behalte gleich noch im Hinterkopf, das beim ATMega88 z.b. die 
USART-Register im erweitertem IO-Bereich liegen. Da ist dann lds/sts und 
nicht mehr in/out angesagt.

MfG Spess

von padderick (Gast)


Lesenswert?

Habs heute nochmal versucht und mit :
1
/*
2
 * LEDBlink.c
3
 *
4
 * Created: 11.12.2013 19:45:19
5
 *  Author: padderick
6
 */ 
7
8
#define F_CPU 7372800UL
9
#define BAUD 9600UL
10
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runde
11
#include <avr/io.h>
12
#include <stdlib.h>
13
#include <util/delay.h>
14
#include <util/setbaud.h>
15
16
17
int main(void)
18
{
19
  UBRRH = UBRR_VAL >> 8;
20
  UBRRL = UBRR_VAL & 0xFF;
21
  UCSRB |= (1<<TXEN);  // UART TX einschalten
22
  UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);  // Asynchron 8N1
23
  DDRA = 0xFF;
24
  PORTA = 0b01010101;
25
    for(;;)
26
    {
27
   //_delay_ms(125);
28
   PORTA = PORTA + 1;
29
       while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich                   */
30
       {
31
       }   
32
       UDR |= PORTA;
33
34
   }
35
}

Habs einfach nochmal von neu aufgezogen, im Endeffekt weis ich nicht wo 
der Fehler vorher war. Trotzdem viele dank ;)

von rumus001 (Gast)


Lesenswert?

Habe das gleiche Problem, und so sieht ein Schnipsel des Codes aus:

--------------------------------------------------------------------
ldi r16, (1<<URSEL)|(0<<UMSEL)|(1<<USBS)|(1<<UCSZ1)|(0<<UCSZ0)
out UCSRC,r16
--------------------------------------------------------------------
Der Controller ist ATmega16 (16PI)
Entwickelt wird auf dem Studio 6.

Im Simulationsmodus kann ich beobachten wie der Register 16 einen Wert 
0x8C
bekommt, dies ist auch so richtig. Nach der Zeile "out UCSRC, r16" wird
aber der Register UCSRC nicht mit 0x8C beschrieben sondern bleibt wie 
gehabt auf Null (bzw. 0x00)

Dies ist übrigends ein Beispiel aus dem ATmega16 Datasheet auf der Seite 
150,
ich verstehe aber leider nicht was ich falsch mache.

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.