PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Frage zu Endloschleifen und Bitmanipulatoren [gelöst]



exile
08.06.2005, 10:11
Hallo allerseits,

da ich neu in der AVR-Programmierung bin, sind mit noch einigen Grundprinzipien unklar.

Frage 1:
Aus welchem Grund liefert mir (1<<0x00) eine 1 also 0x01? Dies bedeutet doch, dass 0x00 um eine stelle nach links geshiftet wird, wobei fehlende Vorgänger mit 0 aufgefüllt werden. Nach meiner Logik sollte in diesem Beispiel die 0x00 wieder resultieren.

Frage 2:
Ich habe ein Beispielprogramm für UART mit Interrrupts getestet. Es funktioniert prinzipiell:



#include <avr/interrupt.h>
#include <avr/signal.h>
#include <libusart.h>

volatile unsigned char data;

SIGNAL (SIG_UART_RECV) {
data = UDR;
if (data == '0') {
PORTB = 0x00;
USART_transmit_string("LED off");
USART_transmit('\n');
}
if (data == '1') {
PORTB = 0xff;
USART_transmit_string("LED on");
USART_transmit('\n');
}
}
int main (void) {
USART_Init();
DDRB = 0xff;
sei ();

USART_transmit('\n');
USART_transmit_string("Begruessungstext");
USART_transmit('\n');

for (;;) {}
}


Das Problem ist jetzt, dass mein AVR die ganze Zeit "Begruessungstext" mir übermittelt, als wäre diese Zeile in der Endlosschleife.
Ich bitte um Hilfe und entschuldige meine Unwissenheit 8-[ .
Danke im Vorraus.

PicNick
08.06.2005, 10:24
Frage 1:
Aus welchem Grund liefert mir (1<<0x00) eine 1 also 0x01?

Diese expression bewirkt, daß die Zahl 1 um Null Bits nach links geschoben wird. das ergibt, klaro, wieder eins.

frage 2 muß ich mir erst anschauen

PicNick
08.06.2005, 10:40
Frage 2 kann ich nicht beantworten.
Du müßtest die .LSS datei oder (.LST) posten

exile
08.06.2005, 11:07
Danke für die schnelle Antwort!
Mir sind die Dateien mit der Endung .LSS oder .LST nicht bekannt. Ich compiliere auf einem Linuxsystem und kann nur die Dateien .hex .map und .elf anbieten, wobei .elf wohl unleserlich und die .hex recht kryptisch ist =).

In der libusart.h sind folgende Funktionen definiert:


#include <avr/io.h>

#define F_CPU 8000000
#define USART_BAUD_RATE 9600
#define USART_BAUD_SELECT (F_CPU/(USART_BAUD_RATE*16l)-1)

void USART_Init(void) {
UCSRB = (1<<RXCIE) | (1<<TXCIE) | (1<<RXEN) | (1<<TXEN);
// UCSRB = (1<<RXEN) | (1<<TXEN);
UBRRL = (unsigned char) USART_BAUD_SELECT;
}

void USART_transmit (unsigned char c) {
while (!(UCSRA & (1<<UDRE))) {}
UDR = c;
}

unsigned char USART_receive (void) {
while(!(UCSRA & (1<<RXC))) {}
return UDR;
}

void USART_transmit_string (unsigned char *string) {
while (!(UCSRA & (1<<UDRE))) {}
while ( *string)
USART_transmit (*string++);
}

PicNick
08.06.2005, 11:14
Hex könnten wir mal versuchen. ( ich brauch den effektiven Code)

UND: welcher Controller ist das ?

exile
08.06.2005, 11:26
Das ganze läuft auf einem ATMega16.

Hier die hex datei:
:100000000C942A000C9445000C9445000C94450077
:100010000C9445000C9445000C9445000C9445004C
:100020000C9445000C9445000C9445000C94AD00D4
:100030000C9445000C9445000C9445000C9445002C
:100040000C9445000C9445000C9445000C9445001C
:100050000C94450011241FBECFE5D4E0DEBFCDBF18
:1000600010E0A0E6B0E0E2E1F2E002C005900D92FF
:10007000AA38B107D9F710E0AAE8B0E001C01D9294
:10008000AB38B107E1F70C94F4000C940000CF9367
:10009000DF93CDB7DEB788ED80932A0083E38093AA
:1000A0002900DF91CF910895CF93DF93CDB7DEB7CD
:1000B00021970FB6F894DEBF0FBECDBF8983809124
:1000C0002B00992780729070009709F4F8CF8981EE
:1000D00080932C0021960FB6F894DEBF0FBECDBFE3
:1000E000DF91CF910895CF93DF93CDB7DEB78091A5
:1000F0002B0088230CF0FBCF80912C009927DF91F7
:10010000CF910895CF93DF93CDB7DEB722970FB687
:10011000F894DEBF0FBECDBF89839A8380912B00F8
:10012000992780729070009709F4F8CFE981FA81DD
:100130008081882349F0E981FA8180813196E983C1
:10014000FA830E945400F2CF22960FB6F894DEBFD5
:100150000FBECDBFDF91CF9108951F920F920FB6C2
:100160000F9211242F933F934F935F936F937F933D
:100170008F939F93AF93BF93EF93FF93CF93DF93AF
:10018000CDB7DEB780912C0080938A0080918A00E1
:10019000803349F41092380080E690E00E9482009B
:1001A0008AE00E94540080918A00813351F48FEFDD
:1001B0008093380088E690E00E9482008AE00E94E6
:1001C0005400DF91CF91FF91EF91BF91AF919F913B
:1001D0008F917F916F915F914F913F912F910F90F0
:1001E0000FBE0F901F901895CFE5D4E0DEBFCDBFB6
:1001F0000E9447008FEF8093370078948AE00E9436
:1002000054008FE690E00E9482008AE00E94540031
:02021000FFCF1E
:100212004C4544206F6666004C4544206F6E004D8D
:100222006F696E2C20736F6C6C2069636820426961
:0A023200657220686F6C656E3F0076
:00000001FF


RESPEKT wenn du damit was anfangen kannst! =)

PicNick
08.06.2005, 11:36
Die fragliche main-routine übersetzt er folgendermaßen



int main (void) {

L_$01E8:
01E8 LDI YL,$5F ; set stack
01EA LDI YH,$04
01EC OUT SPH,YH
01EE OUT SPL,YL

USART_Init();
01F0 CALL L_$008E
DDRB = 0xff;
01F4 LDI r24,$FF
01F6 STS DDRB,r24
sei ();
01FA SEI
USART_transmit('\n');
01FC LDI r24,$0A
01FE CALL L_$00A8
USART_transmit_string("Begruessungstext");
0202 LDI r24,$6F
0204 LDI r25,$00
0206 CALL L_$0104
USART_transmit('\n');
020A LDI r24,$0A
020C CALL L_$00A8
for (;;) {}
L_$0210:
0210 RJMP L_$0210


}
0212 4C 45 44 20 6F 66 66 00 LED off.
021A 4C 45 44 20 6F 6E 00 4D LED on.M
0222 6F 69 6E 2C 20 73 6F 6C oin\, sol
022A 6C 20 69 63 68 20 42 69 l ich Bi
0232 65 72 20 68 6F 6C 65 6E er holen
023A


und hinten hat der die dauerschleife for (;; )
L_$0210:
0210 RJMP L_$0210

das ist alles pipifein.

Was dich quält, ist der Watchdog, der immer wieder einen reset auslöst.
(und daher wieder von vorn beginnt)

den kannst du bei den fuses abdrehen (WDEN oder so ähnlich)

hat eigentlich mit dem Programm garnix zu tun. Auf die Idee hätt ich auch gleich kommen können. aber was soll's

exile
08.06.2005, 11:42
Jetzt ist alles klar. Werde die fuses-bits umstellen.

Vielen dank für mühe!

regards
martin