Forum: Mikrocontroller und Digitale Elektronik USART1 beim ATMega644P


von Zaphod (Gast)


Lesenswert?

Ich versuche gerade, mit den USART1 beim ATMega644P zu verwenden. 
Eigentlich dachte ich ja, das ist ganz einfach, ich kopiere mir den Code 
vom USART0 und ändere einfach die 0 in eine 1:
1
// Initialisuerung, es soll nur TX verwendet werden
2
uint16_t UBRR0_value=(F_CPU/8L/57600)-1;
3
UCSR1A |= (1 << U2X0);
4
UBRR1H = UBRR0_value >> 8;
5
UBRR1L = UBRR0_value;
6
UCSR1B |= (1 << TXEN1);
7
8
// Daten senden
9
if ((UCSR1A & (1<<UDRE0))!=0)
10
{
11
   UDR1 = value;
12
}

Allerdings: der Ausgang ist ständig auf High-Pegel und sendet auch nix. 
Was habe ich übersehen?

von Reiner_Gast (Gast)


Lesenswert?

Das Bauraten Register ist ein 16-Bit Register. Dazu steht im Datenblatt 
geschrieben:

8.6. Accessing 16-bit Registers
The AVR data bus is 8 bits wide, and so accessing 16-bit registers 
requires atomic operations. These
registers must be byte-accessed using two read or write operations. 
16-bit registers are connected to the
8-bit bus and a temporary register using a 16-bit bus.
For a write operation, the low byte of the 16-bit register must be 
written before the high byte. The low byte
is then written into the temporary register. When the high byte of the 
16-bit register is written, the
temporary register is copied into the low byte of the 16-bit register in 
the same clock cycle.

Und so ganz komplett ist die Tauschaktion "0" gegen "1" wohl auch nicht:
UCSR1A |= (1 << U2X0);
if ((UCSR1A & (1<<UDRE0))!=0)
{
   UDR1 = value;
}

von S. Landolt (Gast)


Lesenswert?

> Was habe ich übersehen?

Einige Nullen. Zumindest
> if ((UCSR1A & (1<<UDRE0))!=0)
ist Unsinn. Mehr kann ich ohne das vollständige Programm nicht sagen.

von S. Landolt (Gast)


Lesenswert?

PS:

> ist Unsinn

Doch nicht ganz, die Bits sitzen ja an derselben Stelle. Also doch das 
komplette Programm zeigen.

von H.Joachim S. (crazyhorse)


Lesenswert?

Zaphod schrieb:
> Was habe ich übersehen?

UCSR1C

von Zaphod (Gast)


Lesenswert?

Ok, das Programm sieht jetzt so aus:
1
void serial_init()
2
{
3
// Set baud rate
4
#if BAUD_RATE < 57600
5
   uint16_t UBRR0_value = ((F_CPU / (8L * BAUD_RATE)) - 1)/2 ;
6
   UCSR0A &= ~(1 << U2X0); // baud doubler off  - Only needed on Uno XXX
7
#else
8
   uint16_t UBRR0_value=(F_CPU/8L/BAUD_RATE)-1; // ((F_CPU / (4L * BAUD_RATE)) - 1)/2;
9
   UCSR0A |= (1 << U2X0);  // baud doubler on for high baud rates, i.e. 115200
10
#endif
11
   UBRR0H = UBRR0_value >> 8;
12
   UBRR0L = UBRR0_value;
13
14
   // enable rx, tx, and interrupt on complete reception of a byte
15
   UCSR0B |= (1<<RXEN0 | 1<<TXEN0);
16
17
18
  // Set baud rate
19
#if BAUD_RATE < 57600
20
   UCSR1A &= ~(1 << U2X1); // baud doubler off  - Only needed on Uno XXX
21
#else
22
   UCSR1A |= (1 << U2X1);  // baud doubler on for high baud rates, i.e. 115200
23
#endif
24
   UBRR1H = UBRR0_value >> 8;
25
   UBRR1L = UBRR0_value;
26
27
   // enable tx
28
   UCSR1B |= (1 << TXEN1);
29
  // defaults to 8-bit, no parity, 1 stop bit
30
}
31
32
33
void serial_write_tx1(const uint8_t value)
34
{
35
  if ((UCSR1A & (1<<UDRE1))!=0)
36
  {
37
     UDR1 = value;
38
  }
39
}

USART0 soll RX und TX können, USART1 nur TX. Dass serial_write_tx1() ein 
Byte verliert, wenn das Senden gerade nicht geht, ist gewollt.

Was ich mich frage: muss ich den TX1 pin nicht noch irgendwie von GPIO 
auf UART umschalten?

von Karl M. (Gast)


Lesenswert?

Zaphod schrieb:
> Ok, das Programm sieht jetzt so aus:

> void serial_write_tx1(const uint8_t value)
> {
>   if ((UCSR1A & (1<<UDRE1))!=0)
>   {
>      UDR1 = value;
>   }
> }
>
> USART0 soll RX und TX können, USART1 nur TX. Dass serial_write_tx1() ein
> Byte verliert, wenn das Senden gerade nicht geht, ist gewollt.
Warum?

> Was ich mich frage: muss ich den TX1 pin nicht noch irgendwie von GPIO
> auf UART umschalten?
Nein,
ich initialisere die UsartX Pins trotzdem und setze den RXn 
(Input-)Pullup auf an.

So kann einen einen USB-TTL-Wandler an- und abstecken ohne Probleme.

von S. Landolt (Gast)


Lesenswert?

M.E. sollte das Gezeigte funktionieren. Am richtigen Pin geschaut?

von Zaphod (Gast)


Lesenswert?

S. Landolt schrieb:
> M.E. sollte das Gezeigte funktionieren. Am richtigen Pin geschaut?

PD3 / Pin 12 beim TQFN-Package - sollte passen :-/

von S. Landolt (Gast)


Lesenswert?

Also bei mir läuft das, mit einem selbstgebastelten main sowie einem 
kleinen Delay in demselben.

von S. Landolt (Gast)


Lesenswert?

Verzeihen Sie die Frage, aber - ist es wirklich ein ...P?

von Karl M. (Gast)


Lesenswert?

S. Landolt schrieb:
> Verzeihen Sie die Frage, aber - ist es wirklich ein ...P?

Gute Frage, ich möchte es noch etwas klarer sagen:

der ATMega644 hat nur einen Usart, hingegen der ATMega644P hat zwei 
Usart.

Ja das kann es auch geben!

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.