Forum: Mikrocontroller und Digitale Elektronik ATMega324P serielle Schnittstelle möchte nicht


von Sebastian (Gast)


Lesenswert?

Hallo!

Ich möchte mit einem ATMega324P testweise einfach nur kontinuierlich ein 
Zeichen an meinen PC senden. Es ist zusätzlich ein externer Quarz mit 
14,7456MHz verbaut, ebenso ein MAX3232 um den Pegel für die Übertragung 
zu verstärken.
Nach etlichen Versuchen hab ich es leider nicht hinbekommen. 
Einstellungen sollten soweit korrekt sein. Möglicherweise kann mir hier 
ja jemand helfen und mir den/die Fehler nennen. Die blinkende LED am 
Programmende soll nur dazu dienen, um zu sehen, ob das Programm richtig 
drauf ist. :) Bin leider ein ziemlicher Anfänger, was die Programmierung 
der Atmels angeht.. Hier ist mein Code:

1
#include <avr/io.h>
2
#include<stdlib.h>
3
#include<stdio.h>
4
#include<util/delay.h>
5
#include <string.h>
6
7
#define LED PA2
8
#define set_bit(byte,bit) (byte) |= (1<<(bit))
9
#define clear_bit(byte,bit) (byte) &= ~(1<<(bit))
10
11
#ifndef F_CPU
12
#define F_CPU 14745600UL //CPU Frequency Hz
13
#endif
14
#define UART_BAUD_RATE 9600 //kHz
15
// Hilfsmakro zur UBRR-Berechnung 
16
#define UART_UBRR_CALC(UART_BAUD_RATE,F_CPU) ((F_CPU)/((UART_BAUD_RATE)*16L)-1)
17
18
19
int main( void )
20
{
21
blink();
22
  /* Set baud rate */
23
  UBRR0H = (uint8_t)( UART_UBRR_CALC( UART_BAUD_RATE, F_CPU ) >> 8 );
24
  UBRR0L = (uint8_t)UART_UBRR_CALC( UART_BAUD_RATE, F_CPU );
25
  
26
  /* Enable receiver and transmitter */
27
  UCSR0B = (1<<RXEN0)|(1<<TXEN0);
28
  
29
  /* Set frame format: 8data, 2stop bit */
30
  UCSR0C = (1<<USBS0)|(3<<UCSZ00);
31
  
32
  UCSR0A = (0<<U2X0);
33
34
  unsigned char zeichen = 't';
35
36
  while (1)
37
  {
38
    _delay_ms(50);
39
    //warten bis letztes Zeichen gesendet
40
    UDR0 = zeichen;
41
    loop_until_bit_is_set(UCSR0A, UDRE0);
42
    
43
  }
44
  
45
  return 0;
46
}
47
48
49
50
/* Blinkende LED an Pin PA2 */
51
52
53
void blink()
54
{
55
  set_bit(DDRA,LED);
56
  while(1)
57
  {
58
    set_bit(PORTA,LED);
59
    _delay_ms(200);
60
    clear_bit(PORTA,LED);
61
    _delay_ms(200);
62
  }
63
}


Vielen Dank!!

Gruß,
Sebastian

von Oliver (Gast)


Lesenswert?

>Die blinkende LED am
>Programmende soll nur dazu dienen, um zu sehen, ob das Programm richtig
>drauf ist. :)

Aus dem Funktionsaufruf blink() am Programmanfang kehrt das Programm 
aber nie mehr zurück ;-)

Der Rest danach wird nie ausgeführt.

Oliver

von Sebastian (Gast)


Lesenswert?

ups, stimmt.. ändert aber nix an der Funktion. Geht auch nicht, wenn ich 
den Teil rausnehme.

von seven (Gast)


Lesenswert?

- blink() steht unter main
- blink is ne endlosschleife ?

von Sebastian (Gast)


Lesenswert?

Blink ist erstmal völlig egal, das habe ich bereits komplett entfernt. 
Der Rest funktioniert aber nach wie vor nicht.

von Hc Z. (mizch)


Lesenswert?

Hast Du denn schon geprüft, ob die Harware OK ist (Echotest bei 
verbundenem RxD/TxD am µC-Sockel)?

Was genau bedeutet "geht nicht"?  Hast Du mit dem Oszi am TxD-Pin 
geprüft, dass sich da nichts tut?

Kein Grund, überhaupt nicht zu funktionieren, aber eine Bemerkung:
1
    UDR0 = zeichen;
2
    loop_until_bit_is_set(UCSR0A, UDRE0);
Diese Zeilen sollten vertauscht werden.  Das Programm kann was Anderes 
tun, während ein Zeichen gesendet wird, statt dumpf zu warten, bis es 
akzeptiert ist.  Und von der Logik her ist es auch besser so: erst wenn 
UDREx gesetzt ist, darf nach UDR geschrieben werden (was in Deinem Fall 
aber auch so gewährleistet ist).

von LordZiu (Gast)


Lesenswert?

Noch Sachen zum checken:

Der externe Quarz ist auch in den Fuses gesetzt? -> wär gut
Ist CKDIV8 gesetzt (teilt im Controller den Takt durch 8)? -> wär 
schlecht
Ist der Baudratenfehler kleiner 1%?

von Peter D. (peda)


Lesenswert?

Probier einfach mal ein funktionierendes Beispiel:

Beitrag "AVR-GCC: UART mit FIFO"


Peter

von Sebastian (Gast)


Lesenswert?

Hi,
danke schonmal für die vielen Antworten.
Einen Oszi hab ich hier zuhaus leider nicht. Ich werds morgen mal im 
Labor messen, wenns geht.
Baudratenfehler ist kleiner als 1%, wo finde ich das, ob der externe 
Quarz gesetzt ist?
Zu dem "funktionierenden" Beispiel: habs versucht, da fehlen Bezüge.. 
warum auch immer, der scheint die main.h und uarto.h nicht zu finden 
(obwohl die da sind). Kommt ne Fehlermeldung a la main.c:22: undefined 
reference to `init_uart0'... und noch einige mehr dieser Art. Die sind 
ja eigentlich in der headerdatei deklariert..

von LordZiu (Gast)


Lesenswert?

Schau mal in die AVR Checkliste, gleich der zweite Punkt. Da wird 
beschrieben, welche Fuses du setzen musst.

von LordZiu (Gast)


Lesenswert?

AVR Checkliste meinte ich

von Peter D. (peda)


Lesenswert?

Sebastian schrieb:
> Zu dem "funktionierenden" Beispiel: habs versucht, da fehlen Bezüge..
> warum auch immer, der scheint die main.h und uarto.h nicht zu finden
> (obwohl die da sind). Kommt ne Fehlermeldung a la main.c:22: undefined
> reference to `init_uart0'... und noch einige mehr dieser Art.

Wie lautet die erste Warn-/Fehlermeldung exakt?

Welche Toolchain/OS benutzt Du?

Unter Unix kann die Großschreibung ein Problem sein.
Nenne mal alle Files in klein um.


Peter

von Sebastian (Gast)


Lesenswert?

Hi,
danke schonmal für den Tip mit den Fuses. Da ist bei mir folgendes 
Eingestellt (nach Auslesen angezeigt):

BODLEVEL: Brown-Out detection disabled
OCDEN: disabled
JTAGEN: disabled
SPIEN: enabled
WDTON: disabled
EESAVE: enabled
BOOTSZ: Bootflash size=2048 words start address=$3800
BOOTRST: disabled
CKDIV8: disabled
CKOUT: disabled
SUT_CKSEL: ext. Crystal Osc. 8.0-   MHz startup time: 16K CK +65ms


sollte der CKSEL nicht einfach nur auf ext. clock stehen? z.b. ext. 
clock start-up time 6CK + 0ms?

von Hc Z. (mizch)


Lesenswert?

> sollte der CKSEL nicht einfach nur auf ext. clock stehen? z.b. ext.
> clock start-up time 6CK + 0ms?

Esterner Clock ist nicht geeignet, wenn Du einen Quarz angeschlossen 
hast.  Und mit der höheren Startup Time gibst Du dem Anschwingen mehr 
Zeit, bis der Oszillator stabil sein muss.  Weniger würde wohl auch 
gehen, aber ich sehe nicht, dass Du das brauchst.

von Sebastian (Gast)


Lesenswert?

Hallo,
so, ich war grad mal im Labor und hab alles durchgemessen. Fehler 
gefunden. Der MAX3232 hat keinen Saft bekommen.. das war das ganze 
Problem. Nun läufts (vorerst) so, wie es soll.

Nochmals vielen Dank an alle!!

Gruß,
Sebastian

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.