Hallo,
ich habe einen ATtiny, wo ich einen Qaurz mit 8Mhz drann habe.
Desweiteren habe ich einen Prescaler von 64.
Da dieser Quarz nicht optimal für UART ist, ist mir bewusst, allerdings
brauche ich auch 8Mhz, damit ich genau Timer-INterrupts erstellen kann.
Meine Frage bezieht sich auf den Prescaler. Wird der bei der Berechnung
von UBBR mit einbezogen? Die Gleichung ist ja
UBRR = (fOSC / (16*BAUD) ) - 1
ist fosc jetzt 8000000 oder 125000?
Habe für den Uart eine Baud-Rate von 9600 genommen (fosc = 8Mhz),
allerdings wird nichts richtiges empfangen.
Marc
Marc schrieb:> ich habe einen ATtiny, wo ich einen Qaurz mit 8Mhz drann habe.> Desweiteren habe ich einen Prescaler von 64.> Da dieser Quarz nicht optimal für UART ist, ist mir bewusst, allerdings> brauche ich auch 8Mhz, damit ich genau Timer-INterrupts erstellen kann.
Was für ein Prescaler ist das? Systemtakt oder Timer? Wenn's der
Timer-Prescaler ist, wird der Takt der UART davon nicht beeinflußt.
Wenn's hingegen der Systemtakt ist, dann natürlich schon. Allerdings
ergäbe das keinen Sinn, da dann auch für den Timer nur 125kHz verfügbar
wären, womit deine Begründung für den 8MHz Quarz obsolet wäre...
für den Systemtakt gibt es beim ATTiny nur die CKDIV8-Fuse.
8 MHz intern/extern/Quarz ergeben 1 MHz, oder 8 MHz
Systemtakt, je nach Fuse-Setting.
Die CKDIV8-Fuse muss in deinem Fall AUSGESCHALTET werden.
Bei den klassischen ATTinys gibt es nur den 2313 mit UART.
- Ist wohl zuviel verlangt, dass du den µC-Typ mal nennst...
Der Prescaler 64 ist also ein Rätsel für alle, die helfen
sollen.
Erste Frage:
(CKDIV8) Hast du 1 MHz, oder 8 MHz Systemtakt?
Ansonsten hängt UBRR H/L direkt am Systemtakt,
bei 1 MHz:
UBRR = (fOSC / (16*BAUD) ) - 1 =
UBRR = 1 MHz / (16 * 9600) - 1 =
UBRR = 1.000.000 / 153.600 = 6,5
UBRR = geht nicht, 6 zu klein, 7 zu groß!
bei 8 MHz:
UBRR = (fOSC / (16*BAUD) ) - 1 =
UBRR = 8 MHz / (16 * 9600) - 1 =
UBRR = 8.000.000 / 153.600 - 1 = 52,0833 - 1
UBRR = 51 -> 9615 Bd - kein Problem! OK!
Und wenn du zu blöd bist die CKDIV8-Fuse abzuschalten,
kannst du bei 1 MHz noch den Double-Speed-Mode wählen,
dazu ist das U2X-Bit im UCSRA-Register zu setzen.
(Schaffst du das????)
Dann gilt:
bei 1 MHz:
UBRR = (fOSC / (8*BAUD) ) - 1 =
UBRR = 1 MHz / (8 * 9600) - 1 =
UBRR = 1.000.000 / 76.800 - 1 = 13,0208333 - 1
UBRR = 12 -> 9615 Bd - kein Problem! OK!
Jakob schrieb:> Die CKDIV8-Fuse muss in deinem Fall AUSGESCHALTET werden.
Naja, theoretisch muss sie "eingeschaltet" werden, im weitesten Sinne
:-D Denn viele, war damals (tm) bei mir genauso:
0 = Bit nicht gesetzt = programmed / eingeschaltet
1 = Bit gesetzt = unprogrammed / ausgeschaltet
Das sorgt schon ab und wann für Verunreinigungen. ;-)
Marc schrieb:> Habe für den Uart eine Baud-Rate von 9600 genommen (fosc = 8Mhz),> allerdings wird nichts richtiges empfangen.> Marc
Hi,
da gibt es unter Umständen andere Probs noch, wenn nichts
empfangen/gesendet wird:
"... Die Originaldokumentation für den Attiny 2313 (2543L-AVR-08/10)
macht auf Seiten 129 bis 133 UART Controlregisterdefinitionen, die nicht
stimmen, so dass die Assemblierung im Studio4 fehlschlägt. "UCSRC not
defined on this target "
Im Attiny 4313 gibt es in der "def.inc" den klärenden Hinweis auf
Kompatibilität.
ser in out init:
ldi temp, bdrt ;Baudrate setzen
out UBRR, temp ; .equ UBRR=UBRRL;for compatibility
ldi temp, 0x18 ;(1<<RXEN)+(1<<TXEN)
out UCR, temp ; .equ UCR=UCSRB;for compatibility
ret
;
tx: ;RS232-Ausgaberoutine
sbis UCSRA, UDRE ; .equ USR=UCSRA;for compatibility
rjmp senden
out UDR, temp
ret
ciao
gustav
P.S.: verwende bei 4 MHZ als Baudratenteilerkonstante 25 bei 9k6
Jakob schrieb:> - Ist wohl zuviel verlangt, dass du den µC-Typ mal nennst...
Nein, zu viel ist es nicht verlangt, aber es ging ja nicht primär um
Uart, sondern darum, mit welchem Takt der Controller läuft.
Jakob schrieb:> Und wenn du zu blöd bist
danke
while ( !( UCSRA & (1<<UDRE)) );/* Wait for empty transmit buffer */
51
UDR = data; /* Put data into buffer, sends the data */
52
}
53
54
ISR (TIMER0_COMPA_vect)
55
{
56
static uint16_t milliseconds = 0;
57
milliseconds++;
58
if(milliseconds >= 1000)
59
{
60
milliseconds = 0;
61
senduart = 1;
62
PORTB ^= ( 1 << PB0 ); /* Toggle PB0 */
63
}
64
}
In der Timer ISR lasse ich eine LED Toggeln. Dies läuft auch jede
Sekunde. Allerdings funktioniert das mit dem UART noch nicht.
Benutze dazu das Programm HTerm, Es kommt zwar was an, aber bei jedem
Senden 0x00 und 0xC0.
Die Fuses sind: Extended: oxFF; High: 0x9F; Low: 0xEC
DraconiX schrieb:> 0 = Bit nicht gesetzt = programmed / eingeschaltet> 1 = Bit gesetzt = unprogrammed / ausgeschaltet
CKDIV8 habe ich nicht gesetzt (nach deiner Aussage dann ja
eingeschaltet), jedoch stimmt dann ja meine Berechnung für den Timer
nicht, bzw. dann ist da noch ein anderer Fehler drinn, da die ISR wie
berechnet jede millisekunde ausgeführt wird
mach mal dein senduart volatile, das ist vermutlich nicht die
Fehlerursache, ist aber notwendig, damit es nicht irgendwann doch hängt.
Und dann häng doch einfach ein Scope an den TxD Pin und sieh dir die
Breite der Bits an. Damit kannst du sofort die Baudrate errechnen und
bekommst einen Hinweis, wo es nicht passt.
Marc schrieb:> #define UBBR_UART (FOSC/ (16*BAUD_UART))-1
Da der Compiler per Definition mit 16 Bit Integer rechnet, kommst hier
nicht das gewünschte Ergebnis.
Ein Blick in das .lss File zeigt dir, was passiert ist.
Die Frage nach dem µC könnte z.B. helfen, um für Ratschläge
das Handbuch-Kapitel zu nennen.
- Naja, manche müssen aus dem µC-Typ ein grooooßes Geheimnis
machen. Oder lesen nicht gern?
CKDIV8 ist bei Auslieferung GESETZT, d.h. AKTIV.
Ob NULL, oder EINS das aktivierende Logik-Potential ist, KÖNNTE
man auch im Handbuch nachlesen.
Ändert man nichts am Auslieferungszustand, arbeitet der µC halt
mit 1/8 der wirksamen Frequenz...
Symbolische Rechnung ist schön, kann aber auch zu unbrauchbaren
Ergebnissen führen:
bei 1 MHz:
UBRR = (fOSC / (16*BAUD) ) - 1 =
UBRR = 1 MHz / (16 * 9600) - 1 =
UBRR = 1.000.000 / 153.600 - 1 = 5 (Ganzzahl)
Test:
BAUD = (fOSC / (UBRR + 1)) / 16 = 10.417 = 8,5% daneben!
Funktioniert nicht.
Das Standardvorgehen ist das UART mit einer Konstante, zB 0x55, senden
zu lassen und mit einem Oszilloskop die Baudrate zu messen. Dann muss
man viel weniger raten.
Hi
>Das Standardvorgehen ist das UART mit einer Konstante, zB 0x55, senden>zu lassen und mit einem Oszilloskop die Baudrate zu messen.
Wieso ist das 'Standard'? Ich brauche dafür lediglich IO-Frequenz und
Baudrate.
MfG Spess
Hi
>Weil man nahezu gar nichts ueberlegen muss.
Aber man muss mit dem Oszi umgehen können. Sonst kommt noch größerer
Mist als beim Rechnen heraus. Abgesehen davon besitzt nicht jeder einen
Oszi.
MfG spess
spess53 schrieb:> Wieso ist das 'Standard'? Ich brauche dafür lediglich IO-Frequenz und> Baudrate.
Weil die IO-Frequenz nicht konstant ist.
AVR wird mit einem für UART Betrieb etwas zu ungenauen internem
Oszillator ausgeliefert, den man erst per Fuse auf Quarz (so vorhanden)
umstellen muss.