vklaffehn
21.01.2009, 13:23
Moin!
Ich habe hier ein Phänomen, meine tapfere SW-UART Routine funktioniert 'plötzlich' nicht mehr. Ich habe mal alles rausgeschmissen und nur die senderoutine mit einer Schleife dringelassen, aber irgendwie klappt das alles nicht mehr. -zum Hintergrund muß ich sagen, daß ich vor kurzem auf WinAVR-20080610 und das aktuelle AVR Studio aktualisiert habe, der Code selbst ist unverändert.
Hier mal mein Programm :
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
void txd(uint8_t value)
{
uint8_t bitcnt;
uint8_t delay;
__asm__ __volatile__(
"cli\n\t"
"ldi %0,0x0a\n\t" //;1+8+sb (sb is # of stop bits)
"com %2\n\t" //;Inverte everything
"sec\n\t" //;Start bit
"0:brcc 1f\n\t" //;If carry set
"sbi 0x15,5\n\t" //;send a '0'
"rjmp 2f\n\t" //;else
"1:cbi 0x15,5\n\t" //;send a '1'
"nop\n\t"
"2:rcall 3f\n\t" //;One bit delay
"rcall 3f\n\t"
"lsr %2\n\t" //;Get next bit
"dec %0\n\t" //;If not all bit sent
"brne 0b\n\t" //;send next
"sei\n\t" //;else
"ret\n\t" //; return
"3:ldi %1,19\n\t"
"4:dec %1\n\t"
"brne 4b\n\t"
"ret\n\t"
:"=r"(bitcnt),"=r"(delay),"=r"(value):"2"(value));
}
/*
BaudRate Cycles required b-value Error %
2400 6667 (2) 1107 0
4800 3333 (2) 552 0
9600 1667 (2) 274 0
14400 1111 181 0,2
19200 833 135 0
28800 556 89 0,3
57600 278 42 1
115200 139 19 1,4
*/
int main(void)
{
unsigned char cnt;
DDRC = (1<<PC5);
for (cnt=0;cnt<100;cnt++) txd(10);
return 0;
}
Der Fehler war, daß das Programm immer eine 0 sendete und dann nichts mehr. Als ich dann bei den Operanden am Ende das '):"2"(value)' ergänzte, bekam ich immerhin das korrekte Zeichen, aber nur einmal. Auch mit der Schleife bekomme ich jetzt nur einmal eine 10, danach bleibt das Programm stehen bzw. es kommt ncihts mehr. Bei der Verwendung in meinem ursprünglichen Programm, wo ich den Inhalt eines Arrays senden will, bleibt das Programm zwar nicht stehen, aber der Controller scheint einen Reset zu machen ö.ä., da ich statt des Arrays immer nur den ersten Wert des Arrays bekomme und danach das Programm neu startet, daher vermute ich, daß irgendwas mit den Registern nicht passt, aber ich komm leider einfach nicht dahinter. Vielleicht kann mir einer einen Tipp geben, wieso das jetzt 'auf einmal' nicht mehr funktioniert??
Vielen Dank schonmal!!
MfG Volker
Ich habe hier ein Phänomen, meine tapfere SW-UART Routine funktioniert 'plötzlich' nicht mehr. Ich habe mal alles rausgeschmissen und nur die senderoutine mit einer Schleife dringelassen, aber irgendwie klappt das alles nicht mehr. -zum Hintergrund muß ich sagen, daß ich vor kurzem auf WinAVR-20080610 und das aktuelle AVR Studio aktualisiert habe, der Code selbst ist unverändert.
Hier mal mein Programm :
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
void txd(uint8_t value)
{
uint8_t bitcnt;
uint8_t delay;
__asm__ __volatile__(
"cli\n\t"
"ldi %0,0x0a\n\t" //;1+8+sb (sb is # of stop bits)
"com %2\n\t" //;Inverte everything
"sec\n\t" //;Start bit
"0:brcc 1f\n\t" //;If carry set
"sbi 0x15,5\n\t" //;send a '0'
"rjmp 2f\n\t" //;else
"1:cbi 0x15,5\n\t" //;send a '1'
"nop\n\t"
"2:rcall 3f\n\t" //;One bit delay
"rcall 3f\n\t"
"lsr %2\n\t" //;Get next bit
"dec %0\n\t" //;If not all bit sent
"brne 0b\n\t" //;send next
"sei\n\t" //;else
"ret\n\t" //; return
"3:ldi %1,19\n\t"
"4:dec %1\n\t"
"brne 4b\n\t"
"ret\n\t"
:"=r"(bitcnt),"=r"(delay),"=r"(value):"2"(value));
}
/*
BaudRate Cycles required b-value Error %
2400 6667 (2) 1107 0
4800 3333 (2) 552 0
9600 1667 (2) 274 0
14400 1111 181 0,2
19200 833 135 0
28800 556 89 0,3
57600 278 42 1
115200 139 19 1,4
*/
int main(void)
{
unsigned char cnt;
DDRC = (1<<PC5);
for (cnt=0;cnt<100;cnt++) txd(10);
return 0;
}
Der Fehler war, daß das Programm immer eine 0 sendete und dann nichts mehr. Als ich dann bei den Operanden am Ende das '):"2"(value)' ergänzte, bekam ich immerhin das korrekte Zeichen, aber nur einmal. Auch mit der Schleife bekomme ich jetzt nur einmal eine 10, danach bleibt das Programm stehen bzw. es kommt ncihts mehr. Bei der Verwendung in meinem ursprünglichen Programm, wo ich den Inhalt eines Arrays senden will, bleibt das Programm zwar nicht stehen, aber der Controller scheint einen Reset zu machen ö.ä., da ich statt des Arrays immer nur den ersten Wert des Arrays bekomme und danach das Programm neu startet, daher vermute ich, daß irgendwas mit den Registern nicht passt, aber ich komm leider einfach nicht dahinter. Vielleicht kann mir einer einen Tipp geben, wieso das jetzt 'auf einmal' nicht mehr funktioniert??
Vielen Dank schonmal!!
MfG Volker