Forum: Mikrocontroller und Digitale Elektronik Problem mit USCRnC Register


von Sefco (Gast)


Lesenswert?

Hallo Zusammen,

ich versuche bei einem Atmega168PA den USART im Master SPI Mode zu 
nutzen. Nach Datenblatt muss man zur Konfiguration das Register UCSR0C 
verwenden. Um die Data Order, die Clock Phase und die Clock Polarity 
einzustellen muss man in diesem Register die Bits 0, 1 und 2 setzten 
(UDORD0, UCPHA0 und UCPOL0). Laut Datenblatt sind Bits 3, 4 und 5 ohne 
Funktion. Bit 6 und 7 ist UMSEL00 und UMSEL01 um den USART in den Master 
SPI Mode zu bringen.

Die iom168pa.h sagt zu diesem Register ab folgendes:

#define UCSR0C  _SFR_MEM8(0xC2)
#define UCPOL0  0
#define UCSZ00  1
#define UCSZ01  2
#define USBS0   3
#define UPM00   4
#define UPM01   5
#define UMSEL00 6
#define UMSEL01 7

Das aktuelle Datenblatt (http://www.atmel.com/devices/ATMEGA168PA.aspx) 
sagt also was anderes, als die aktuelle iom168pa.h (AVR Studio 7).

Was ist hier los?
Wie soll ich denn nun UCPHA und UDORD0 einstellen?

von Felix A. (madifaxle)


Lesenswert?

Die Defines, die in deiner Beschreibung stehen, gehören zum USART im 
seriellen Modus. Suche doch in der h-Datei mal nach UDORD und UCPHA. ich 
wette, die sind auch da.

Nachtrag:
scheinbar doch nicht :-(. Du kannst diese entweder in deinem Programm 
ergänzen oder statt z. B. UDORD das UCSZ01 nutzen.

: Bearbeitet durch User
von Sefco (Gast)


Lesenswert?

Die Bits sind identisch. Wenn man im Datenblatt nach UCSZ01 sucht, 
findet man ganz am Ende UDORD als alternative Bezeichnung. Blöd 
gemacht...

von Sefco (Gast)


Lesenswert?

Kann das sein, dass beim ATmega die "Baud rate" im Datenblatt nicht wie 
angebene 1 bit / sekunde, sondern 2 byte / sekunde ist?

Ich habe eine LED am MOSI und SCK Ausgang und mein interner OSC ist 128 
kHZ.
Ich schaffe es bei einer Baudrate von 1 aber nicht, das die LED für 
jedes Bit eine Sekunde an ist, sondern sie blinkt viel schneller. Es 
sieht aus als würden alle 16 bit in einer Sekunde geschickt...

von Sefco (Gast)


Lesenswert?

Baudrate ist bit / sekunde.

Einstellbar mit einem 16 bit register namens UBRR0.

Wenn ich da bei 128 kHZ eine 63999 reinschreibe, müsste mit 1 bit /s 
übertragen werden.

Jetzt habe ich gerade gesehen: Der Maximalwert ist 4095 laut Datenblatt. 
Also ist meine Datenrate 15,6 bit /s und alles stimmt. So langsam kann 
der uC nicht :D


:D

von spess53 (Gast)


Lesenswert?

Hi

>Kann das sein, dass beim ATmega die "Baud rate" im Datenblatt nicht wie
>angebene 1 bit / sekunde, sondern 2 byte / sekunde ist?

Nein.

>Ich schaffe es bei einer Baudrate von 1 aber nicht, das die LED für
>jedes Bit eine Sekunde an ist, sondern sie blinkt viel schneller.

Wie hast du das berechnet?

MfG Spess

von Sefco (Gast)


Lesenswert?

Datenblatt s.o. Seite 196:

BAUD = f_osc/(2*(UBRR0+1))

von Sefco (Gast)


Lesenswert?

Wieso ist der TXD des USART eigentlich wenn keine Daten gesendet werden 
auf HIGH? Kann man das Umstellen oder ist das eigentlich egal?

von spess53 (Gast)


Lesenswert?

Hi

>Wieso ist der TXD des USART eigentlich wenn keine Daten gesendet werden
>auf HIGH?

Meinst du USART- oder SPI-Mode?

MfG Spess

von Felix A. (madifaxle)


Lesenswert?

Im USART-Mode ist es so (gewesen), damit der Empfänger erkennen kann, 
dass da wer auf der anderen Seite hängt. Im SPI-Modus sollte das nur so 
sein, wenn der Chipselect auf low liegt und du den Mastermode nutzt.

: Bearbeitet durch User
von Sefco (Gast)


Lesenswert?

Ich bin im SPI Modus, aber der USART hat garkeine Chipselect.
Datenblatt: SS Not supported by USART in
MSPIM

Aber mein TXD ist auf HIGH wenn der Sendebuffer leer ist.

von Felix A. (madifaxle)


Lesenswert?

Ah, da nur der Master-SPI-Mode unterstützt wird, gibt es natürlich 
keinen ChipSelect. Damit ist das normal, da MOSI (Master Out Slave In) 
nicht abgeschaltet werden muss. Die Slaves müssen ihren MISO (Master In 
Slave Out) abschalten, wenn diese nicht angewählt sind, um gegeneinander 
Treiben der Slaveausgänge zu vermeiden.

von Sefco (Gast)


Lesenswert?

Ich habe den ATmega168PA auf 128kHz/8= 16 kHz (interner Teiler) laufen.
Ich kann also in Ruhe den Bits zuschauen (per LED).

Aus dem Datenblatt habe ich diesen Code genommen und bearbeitet:
1
unsigned char USART_Receive( void )
2
{
3
nSEL_LOW();
4
5
/* Wait for empty transmit buffer */
6
while ( !( UCSR0A & (1<<UDRE0)) );
7
/* Put data into buffer, sends the data */
8
UDRn = data;
9
/* Wait for empty transmit buffer */
10
while ( !( UCSR0A & (1<<UDRE0)) );
11
12
nSEL_HIGH();
13
}

An nSEL hängt eine LED, die nicht ausgeht, obwohl die Daten noch 
gesendet werden. Das bedeutet, dass UDRE0 niemals 0 wird, obwohl im 
Datenblatt steht

• Bit 5 – UDREn: USART Data Register Empty
The UDREn Flag indicates if the transmit buffer (UDRn) is ready to 
receive new data. If UDREn is one, the
buffer is empty, and therefore ready to be written. The UDREn Flag can 
generate a Data Register Empty
interrupt (see description of the UDRIE bit). UDREn is set after a reset 
to indicate that the Transmitter is ready.

Wieso wird UDRE0 nicht 0, obwohl die Daten noch gesendet werden?

von spess53 (Gast)


Lesenswert?

Hi

>Wieso wird UDRE0 nicht 0, obwohl die Daten noch gesendet werden?

Ersetze doch mal das unsinnige zweite

>while ( !( UCSR0A & (1<<UDRE0)) );

durch

while ( !(UCSR0A & (1<<RXC0)) );

aus dem Datenblatt.

MfG Spess

von Sefco (Gast)


Lesenswert?

>Ersetze doch mal das unsinnige zweite

>while ( !( UCSR0A & (1<<UDRE0)) );

>durch

>while ( !(UCSR0A & (1<<RXC0)) );

>aus dem Datenblatt.

Mein Receiver ist ausgeschaltet.
Ich will lediglich wissen, wann der TX buffer leer ist. Und da finde ich 
das garnicht so unsinnig.

von holger (Gast)


Lesenswert?

>Ich will lediglich wissen, wann der TX buffer leer ist. Und da finde ich
>das garnicht so unsinnig.

Bei SPI über USART hat der TX Buffer zwei Bytes.
Wenn du nur eins schreibst ist UDRE0 sofort wieder bereit
Daten aufzunehmen. D.h. du ziehst die CS Leitung schon
hoch bevor fertig gesendet wurde. Deswegen warten ob ein Byte
empfangen wurde. Denn dann ist das senden sicher beendet.

von Sefco (Gast)


Lesenswert?

>Bei SPI über USART hat der TX Buffer zwei Bytes.

Laut Datenblatt Seite 191 stimmt das nicht. Der Buffer hat nur 1 Byte.

Außerdem habe ich schon 2 Byte reingeschrieben, und er sendet nur das 1. 
Byte.

von holger (Gast)


Lesenswert?

>Laut Datenblatt Seite 191 stimmt das nicht. Der Buffer hat nur 1 Byte.

The USART in MSPIM mode includes (double) buffering of the transmitter.

Das steht bei mir im Datenblatt.

>Außerdem habe ich schon 2 Byte reingeschrieben, und er sendet nur das 1.
>Byte.

Wer weiß was du da schon wieder falsch gemacht hast;)

von spess53 (Gast)


Lesenswert?

Hi

>Laut Datenblatt Seite 191 stimmt das nicht. Der Buffer hat nur 1 Byte.

Ein Byte im Schieberegister und ein Byte im Puffer. Macht 2 Byte. Der 
Receiver hat incl. Schieberegister drei Byte.

MfG Spess

von Sefco (Gast)


Lesenswert?

>Außerdem habe ich schon 2 Byte reingeschrieben, und er sendet nur das 1.
>Byte.
1
UDR0 = 0b0000000010101010;

Das Schreiben von 16 Bit in UDR0 führt bei mir dazu, dass die LED (die 
ja sonst dauer an ist) 4 Mal an und aus geht (10101010). Es wird nur das 
niedrigere Byte gesendet?!

>Wer weiß was du da schon wieder falsch gemacht hast;)

Sag du es mir!

von Sefco (Gast)


Lesenswert?

...weil ich es so machen muss:
1
UDR0 = ((data & 0b1111111100000000)>>8);
2
UDR0 = (data & 0b0000000011111111);

Jetzt klappt es und jetzt klappt auch
1
/* Wait for empty transmit buffer */
2
while ( !(UCSR0A & (1<<UDRE0)) );

Wobei ich sagen muss, dass ich nicht so ganz verstehe, wie innerhalb von 
einem Takt plötzlich das UDR0 Register (was ja definitiv nur 8 bit hat) 
wieder leer ist und ich die nächsten 8 bit reinschreiben kann.

von spess53 (Gast)


Lesenswert?

Hi

>Sag du es mir!

>UDR0 = 0b0000000010101010;

UDR0 ist 8 Bit breit. Also kannst du mit einer Zuweisung nur 8 Bit 
übergeben.
Der Rest verschwindet im Nirwana. Also mit

UDR0 = 0b10101010;
...
UDR0 = 0b00000000;

sendest du zwei Byte.

MfG Spess

von Sefco (Gast)


Lesenswert?

Danke dir Spess!

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.