Ich versuche momentan - auf einem ATmega8 - mit einem Software-UART
Daten von einem anderen ATmega8 zu empfangen und auf PortC auszugeben,
allerdings kommt nur Kauderwelsch raus.
Die Baudrate ist genau ein Timer durchlauf mit Vorteiler 1024, bei 16
MHz Takt. Also sehr sehr langsam.
Hier der Code:
void init_SoftUART(void)
{
MCUCR |= (1<<ISC01); //Bei Fallender Flanke.
GICR |= (1<<INT0); //INT0 aktivieren.
GIFR = (1<<INTF0); //Interrupt Flag zur sicherheit löschen.
//Timer2 für Software-UART.
TCCR2 = (1<<CS02) | (1<<CS00); //Vorteiler auf 1024.
}
ISR (INT0_vect)
{
TCNT2 = 170; //Timer2 auf die Mitte der Bits sezten.
GICR &= ~(1<<INT0); //INT0 deaktivieren.
TIFR = (1<<TOV2);
TIMSK |= (1<<TOIE2); //Timer2 interrupt aktivieren.
}
ISR (TIMER2_OVF_vect)
{
static int8_t curBit = -1;
static uint8_t receiveByte = 0;
static uint8_t curByte = 0;
switch (curBit) {
case -1:
break;
case 8:
curBit = -2;
PORTC = receiveByte;
UARTreceiveBytes[curByte] = receiveByte;
receiveByte = 0;
curByte = !curByte;
GICR |= (1<<INT0); //INT0 aktivieren.
TIMSK &= ~(1<<TOIE2); //Timer2 interrupt deaktivieren.
break;
default:
receiveByte >>= 1;
if (PINB &= (1<<PD2)) {
receiveByte |= (1<<7);
}
break;
}
curBit++;
}
Könnt ihr mir helfen oder müsst ihr noch mehr wissen?
Ach ja: Das senden Funktioniert einwandfrei, hab ich mit einem Oszi
überprüft.
Mento schrieb:
> Ja, das "=" Zeichen hab ich irgendwie übersehen, allerdings funktioniert> es ohne es auch noch nicht.
Beim Wiederaktivieren des INT0 Interrupts muss auch das entsprechende
Flag gelöscht werden.
Wenn es dann immer noch nicht geht, poste bitte mal, was genau gesendet
und was genau statt dessen empfangen wird.
PS: Wieso ist eigentlich 170 die Mitte?
Es funktioniert noch immer nicht. Das mit 170 war zu Testzwecken,
ursprünglich ist dort 128 gestanden und steht auch jetzt wieder dort.
Hier noch der aktuelle Code:
1
voidinit_SoftUART(void)
2
{
3
MCUCR|=(1<<ISC01);//Bei Fallender Flanke.
4
GICR|=(1<<INT0);//INT0 aktivieren.
5
GIFR=(1<<INTF0);//Interrupt Flag zur sicherheit löschen.
Mento schrieb:
> Es werden jeweils zwei Bytes versandt, das erste gibt die Art der> Nachricht an und das zweite die Daten.
Ich will nicht wissen, was die Daten bedeuten (das ist völlig
irrelevant), ich will wissen, wie die Daten aussehen.
Was wird empfangen, wenn du 0x55 sendest?
Was wird empfangen, wenn du 0xf0 sendest?
Was wird empfangen, wenn du 0x0f sendest?
Tut mir leid, ich hab dich falsch verstanden.
Hier die Ergebnisse (ich hab jeweils viermal gesendet, und jedes mal ist
etwas anderes herausgekommen):
Bei 0x55:
100011
011111
000111
111111
Bei 0xF0:
001111
100011
011111
110001
Bei 0x0F:
100011
100001
111000
001111
Ich glaub aber nicht, dass du daraus schlau wirst.
Ich hab nur immer die ersten 6 Bits da PortC nicht mehr Pins hat.
Hallöchen,
was soll das
curByte = !curByte;
bewirken? Eine logische Negation deines Emfangszählers!?!
Und
(PINB & (1<<PD2))
ist zwar nicht verkehrt, aber Port B und ein Pin von Port D sollte man
nicht mischen!
Außerdem, kann es sein, dass deine SoftUART am Port D angeschlossen ist?
Gruß
Ich hab es jetzt hinbekommen, es waren mehrere Sachen falsch. Unter
anderem das mit PinB statt PinD und auch der Vorteiler des Timers da ich
zuerst Timer0 verwendet hatte, bei welchem der Vorteiler anders ist als
beim Timer2.
Hier der Code, falls es irgendjemanden interessiert:
1
voidinit_SoftUART(void)
2
{
3
MCUCR|=(1<<ISC01);//Bei Fallender Flanke.
4
GICR|=(1<<INT0);//INT0 aktivieren.
5
GIFR=(1<<INTF0);//Interrupt Flag zur sicherheit löschen.
6
7
//Timer2 für Software-UART.
8
TCCR2=(1<<CS22)|(1<<CS21)|(1<<CS20);//Vorteiler auf 1024.
Hallo,
nochmal die Frage:
Was soll das
curByte = !curByte;
bewirken? Eine logische Negation deines Emfangszählers!?!
Ich halte diese Zeile für falsch, mindestens aber gefährlich da
'curByte' static ist und als Arrayindex benutzt wird.
Meines Wissens ist !0 im C "Quasi" Standard nicht eindeutig definiert
außer, das es nicht Null ist. Es kann also 0x01 oder 0xFF oder sonstwas
sein, ganz nach belieben des Compilers.
Oder liege ich falsch, mal so an die wahren C Experten gerichtet?
Gruß
Gast schrieb:
> Ich halte diese Zeile für falsch, mindestens aber gefährlich da> 'curByte' static ist und als Arrayindex benutzt wird.
Sie ist weder falsch noch gefährlich. Sie sorgt dafür, dass immer
abwechselnd UARTreceiveBytes[0] und UARTreceiveBytes[1] beschrieben
werden.
> Meines Wissens ist !0 im C "Quasi" Standard nicht eindeutig definiert> außer, das es nicht Null ist.
Ich weiß ja nicht, was bei dir dieses "Quasi" ist, aber im richtigen
Standard ist das Ergebnis des !-Operators eindeutig definiert.
Zitat C-Standard ISO99:
1
The result of the logical negation operator ! is 0 if the value of
2
its operand compares unequal to 0, 1 if the value of its operand