Hallo zusammen.
Ich nutze das STK500 mit AVR Studio und dem ATmega16 drauf. Den UART
Port vom Controller habe ich direkt mit der Spare RS232 Schnittstelle
des STK500 verbunden. Nun will ich einfach Zeichen senden über UART,
aber das funktioniert einfach nicht! Es kommen immer andere Zeichen an!
Habe auch schon verzweifelt im Forum nach einer Lösung gesucht, aber
nichts gefunden, was mir da weiter hilft.
1
#include<avr/io.h>
2
#define FOSC 4000000// Clock Speed
3
#define BAUD 9600
4
#define MYUBRR FOSC/16/BAUD-1
5
6
7
voidUSART_Transmit(unsignedchardata)
8
{
9
/* Wait for empty transmit buffer */
10
while(!(UCSRA&(1<<UDRE)))
11
;
12
/* Put data into buffer, sends the data */
13
UDR=data;
14
}
15
16
voidUSART_Init(unsignedintubrr)
17
{
18
/* Set baud rate */
19
UBRRH=(unsignedchar)(ubrr>>8);
20
UBRRL=(unsignedchar)ubrr;
21
/* Enable receiver and transmitter */
22
UCSRB=(1<<RXEN)|(1<<TXEN);
23
/* Set frame format: 8data, 2stop bit */
24
UCSRC=(1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
25
}
26
27
intmain(void)
28
{
29
USART_Init(MYUBRR);
30
USART_Transmit(0x48);
31
USART_Transmit(0x61);
32
USART_Transmit(0x6C);
33
USART_Transmit(0x6C);
34
USART_Transmit(0x6F);
35
}
Einstellungen:
Frequency: 4000000
SUT_CKSEL: Int. RC Osc. 4 MHz; Start-up time 6 CK + 64ms
Fuses: High 0x99 Low 0xE3
Über UART kommen folgende Zeichen nun an: C8 E1 E1 EC EF
Was mache ich da genau falsch? Fehlt mir da irgendwo eine Einstellung im
AVR Studio? Hoffe mir kann irgendwer sagen, was ich falsch machen, denn
ich finde das Problem einfach nicht.
MFG
Matthias
Moin,
als erstes ist mir in der Definition für die Baudrate ein Formelfehler
aufgefallen, versuche mal:
#define MYUBRR (FOSC/(16*BAUD) - 1);
dann willst du als Format 8N2 verwenden.
Beim Atmega8 sieht dies so aus, sonst schau eben ins Datenblatt:
// Format: 8N2
UCSRC = (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0) | (1<<USBS);
Da du den Wert MYUBRR definiert hast, kannst dir die Übergaben sparen:
Beispiel:
void USART_Transmit()
{
/* Wait for empty transmit buffer */
while ( !( UCSRA & (1<<UDRE)) )
;
/* Put data into buffer, sends the data */
UDR = data;
}
int main( void )
{
USART_Init ();
USART_Transmit(0x48);
USART_Transmit(0x61);
USART_Transmit(0x6C);
USART_Transmit(0x6C);
USART_Transmit(0x6F);
}
So müsste es klappen.
Gruß Mike
Es gaebe da noch eine Moeglichkeit die Sache anders zu testen, ist aber
nur bei konstanter Temp und konstanter Spannung eine echte Option.
In mehreren Testlaeufen den Wert fuer FOSC um jeweils 1% zu aendern also
40400000, dann 40800000, natuerlich auch in die andere Richtung 3960000
usw. Wenn das Programm ansonsten richtig ist, dann wird der UART
ploetzlich funktionieren. Die Tests weiter in dieselbe Richtung
fortfuehren, bis er nicht mehr funktioniert. Den mittleren funktionial
Wert nehmen, also z.B. 3920000. Soweit die Spannung sich nicht aendert
(also keine Batterie!), sollte das dann funktionieren.
Es gibt einige interne Oscillatoren, die hinreichend genau sind fuer
eine serielle Schnittstellen, der Osc des AVR gehoert nicht dazu ! :-(
Aehnliche Teile mit genauerem Osc waeren z.B. die Teile von Silabs oder
die LPC900 von NXP. Beide sind mit einem schnellen 51-er core bestueckt.
Nur so zur Info.
Wie Peter also schon gesagt hat, ein externer Osc muss dran, mindestens
wenn die Kommunikation ueber Spannung und Temperaturaenderungen
zuverlaessig sein soll.
Robert Teufel
Partner in Silicon Valley gesucht?
Ich stehe gerne zur Verfuegung.
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
Meine ARM/Cortex Webseite: http://www.lpc2000.com
Mhm, dann werde ich mir wohl mal einen besorgen und anschließen bzw.
kann ich die Frequenz nicht sogar vom STK500 holen?
Wenn ich übrigens MYUBRR nicht übergebe, dann führt das zu einer Warnung
und das ganze funktioniert dann gar nicht mehr.
Zumindest brauche ich mich jetzt nicht mehr wundern, wieso der Code aus
dem Datenblatt nicht funktioniert.
Hallo,
40400000
es gehen größere Sprünge zum Test bei üblichen PC-UARTS.
Mit 3600000, 3800000, 4000000, 4200000, 4400000 usw, habe ich bisher
immer schnell die Mitte gefunden.
Mein einer Mega32 schwingt auf ca. 4,4MHz, der Mega16 auf 4,3MHz.
Nutze ich öfter, wenn ich zum Debug mal schnell meinen Debug-UART nutze.
Der gefundene Mittelwert bleibt im Zimmer auch "ewig" stabil genug.
@ Robert Teufel (robertteufel): 40 400 000
Wo hast Du den 40MHz AVR her??? ;-))
Gruß aus Berlin
Michael
Happy
#define FOSC 4160000// Clock Speed
damit geht es :) Ist zwar keine saubere Lösung, aber zumindest weiß ich
nun, dass mein Code nicht falsch ist.
Werde mir morgen dann mal einen Quarz besorgen.
DANKE!!!
Wenn ich micht richtig erinnere, haben die alten ATmega verschiedene
Calibrationsbyte für die verschiedenen RC-Frequenzen.
Beim Reset wird aber nur der Wert für 1MHz automatisch geladen.
Wenn man unbedingt den RC verwenden will, muß man also den Programmer
anweisen, daß er das Calibrationsbyte für 4MHz in den Flash oder EEPROM
lädt und dann nach dem Reset dort auslesen und setzen.
Die aktuellen ATmega164P laufen immer mit 8MHz und können per Vorteiler
runter gesetzt werden (default Vorteiler 8 = 1MHz).
Peter