ATMega UART init und senden

OP #5350072
Lesenswert?

Hallo liebe Gemeinde,

tut mir schon leid dass ich damit komme, aber ich sehe wohl den Wald vor 
lauter Bäumen nicht? Hatte jetzt ein paar Jahre Programmierpause und 
jetzt bekomme ich UART am ATMega644A nicht zum laufen. (Init und senden) 
ich habe die Suche schon durch und auch das Datenblatt.

Es wird was gesendet (gemessen mit einem DSO mit Decoder) aber viel zu 
wenig und auch falsch.

Den Takt habe ich auf den Pin ausgeben lassen und gemessen, es sind die 
eingestellt und eingetragenen 8 Mhz.

Die Einstellung soll 9600 Baud (8,n,1) sein, zur Berechnung beutze ich 
setbaud.h

Hier meine init:

#define F_CPU 8000000UL
#define BAUD 9600UL

#include <util/setbaud.h>

void serial_init()
}
    UBRR0H = UBRRH_VALUE;
    UBRR0L = UBRRL_VALUE;
    UCSR0B |= (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0);
    UCSR0C |= (1<<UCSZ01) | (1<<UCSZ00); //8,n,1
}


und hiermit sende ich in einem timer Interrupt ca. 3Hz

ISR(TIMER0_OVF_vect) //
{

  //cli(); //weitere Interrupts deaktivieren

  PORTB ^= (1<<PB0);  // Toggelt den Ausgänge an PORTB0

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

        UDR0=48;


  //sei(); //alle Interrupts wieder aktivieren
}

Vielen Dank im voraus !
OP #5350922
Lesenswert?

Danke für die Antwort!

Ich habe auch schon den Zahlenwert direkt eingetragen aber es ändert 
nichts.

Um das Problem zu isolieren habe ich jetzt ein Programm wo ich nur immer 
wieder was über die Schnittstelle raus schicke.

Ich bin so langsam am verzweifeln. Am DSO wird der Pin geschaltet, aber 
immer nur ein-zwei lange Flanken und nie die kompletten Daten mit 8,n,1

1
#define F_CPU 8000000UL
2
#define BAUD 9600UL
3

4
#include <avr/io.h>
5
#include <util/setbaud.h>
6
#include <util/delay.h>
7

8

9
void uart_init(void)
10
{
11
  UBRR0L = UBRRL_VALUE;
12
  UBRR0H = UBRRH_VALUE;
13
  UCSR0B |= (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0);
14
  UCSR0C |= (1<<UCSZ01) | (1<<UCSZ00); //8,n,1
15
}
16

17

18
int main(void)
19
{
20
  uart_init();
21
    /* Replace with your application code */
22
    while (1) 
23
    {
24
    while(!(UCSR0A & (1<<UDRE0)))
25
    {
26
      
27
    }
28
    UDR0 = "42";
29
    
30
    _delay_ms(100);
31
    }
32
}
Moderator Persönliche Seite #5350928
Lesenswert?

René K. schrieb:
> UDR0 = "42";

Das ist Quark.

In UDR0 muss ein einzelnes Zeichen und kein String übergeben werden.

Schreibe also:
1
void putc (uint8_t ch)
2
{
3
    while(!(UCSR0A & (1<<UDRE0)))
4
    {
5
        ;
6
    }
7
    UDR0 = ch;
8
}
9

10
int main(void)
11
{
12
    uart_init();
13

14
    while (1) 
15
    {
16
        putc ('4');
17
        putc ('2');
18
        _delay_ms(100);
19
    }
20
}

Das Schreiben einer Funktion puts(), die einen String wie "42" ausgeben 
kann, überlasse ich jetzt einmal Dir.
Gast #5350931
Lesenswert?

Versuch mal...
1
void UartInit (void)
2
{
3
    UCSR0B |= (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);        // UART TX einschalten
4
    UCSR0C |= (3 << UCSZ00);                                      // Asynchron 8N1
5
    UBRR0H = UBRR_VAL >> 8;                                       // Baudrate setzen
6
    UBRR0L = UBRR_VAL & 0xFF;
7
}
OP #5350985
Lesenswert?

Ich habe auch das Gefühl das am DSO liegt, aber ich habe alles schon zig 
mal durchgeschaut....

Aber selbst wenn das DSO nicht richtig decodiert, dann müsste ich doch 
dennoch die 8n1 sehen wenn ich ein Zeichen sende. oder ?

Hier nochmal der aktuelle Code:
1
#define F_CPU 8000000UL
2
#define BAUD 9600UL
3

4
#include <avr/io.h>
5
#include <util/setbaud.h>
6
#include <util/delay.h>
7
#include <stdio.h>
8

9

10

11

12
void uart_init(void)
13
{
14
  //UBRR0L = UBRRL_VALUE;
15
  //UBRR0H = UBRRH_VALUE;
16
  //UCSR0B |= (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0);
17
  //UCSR0C |= (1<<UCSZ01) | (1<<UCSZ00); //8,n,1
18
  
19
UCSR0B |= (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);  // UART TX einschalten
20
UCSR0C |= (1<<UCSZ01) | (1<<UCSZ00);                    // Asynchron 8N1
21
UBRR0H = (UBRR_VALUE>>8);                               // Baudrate setzen
22
UBRR0L = (UBRRL_VALUE & 0xff);
23
}
24

25

26

27
int main(void)
28
{
29
  uart_init();
30

31
    while (1) 
32
    {
33
           while(!(UCSR0A & (1<<UDRE0)))
34
    {
35
        
36
    }
37
    UDR0 = 'L';
38
    
39
    _delay_ms(10);
40
    }
41
}
Angehängte Dateien:
OP #5351007
Lesenswert?

Es funktioniert mit dem einzelnen Zeichen... so was blödes: LSB first 
und am DSO war MSB first.

Aber irgendwie hatte ich das mit den Bits anders in Erinnerung...

Jetzt hoffe ich das ich den anderen Kram noch hinbekomme. Ich muss einen 
String basteln (nur Zahlen) und der soll zyklisch übertragen werden. 
Dieser setzt sich dann aus mehreren Variablen zusammen.

Danke für eure Hilfe bis hierhin!!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren