Hi Leuti ich hab mal wieder ein echtes Problem ich hab ein C programm
was nicht funktionieren will, weis auch warum find aber keine lösung in
Assembler funktioniert das Programm. Jetzt will ich das Stück halt in
Inline Assembler schreiben leider komm ich da absolut nicht klar. kann
mir einer das mal schnell Übersetzte wär das möglich wäre super.
Quellcode:
EEWrite:
out EEARH,adressH ;Output address
out EEARL,adressL ;Output adress
out EEDR,data ;Output data
sbi EECR,2 ;set EEPROM Write EnabLED
sbi EECR,1 ;set EEPROM Write EnabLED
waitEEW:
sbic EECR,1 ;wait for Handshake
rjmp waitEEW
ret
und das in Inline-Assembler wäre echt klasse.
Gruß Renaldo
Das Problem mit dem C-Code ist, dass er das Timing nicht einhält, wenn
er nicht mit Optmimierung compiliert wird. Aber genau dafür gibt es
ja auch <avr/eeprom.h>.
Renaldo B. wrote:
> danke aber fuktioniert so auch nicht,>> Naja will das ja nicht direct in Assembler in Inline-Assembler haben um> dies zu testen weist.
Dann hast du einen anderen Bug im Programm.
Dein Assembler-Code weicht übrigens stark von dem Verfahren ab, welches
Atmel in Datenblatt als Referenzcode angibt.
Der Vollstänigkeit halber eine 1:1 Übersetzung in Inline-ASM für C
Das _attribute_ ((noinline)) ist nötig, damit GCC nicht auf die
Optimierungsidee kommt, die Funktion als Inline-Funktion in den
main-Code zu setze.
Durch das manuell eingefügte 'ret' im Assemblerteil wäre das tödlich für
das Programm.
Das Listing (Ausschnitt) sieht anschliessend so aus:
1
0000005c <EEPROM_write>:
2
3
#define TEST
4
5
void __attribute__ ((noinline)) EEPROM_write(unsigned int uiAddress, unsigned char data)
mhh naja ich hab das problem jetzt ziemlich stark einschränken können!
Lösung Vorschlag ist so das Fuktutioniert aber so soll das nun doch
nicht werden.
void EEPROM_write(unsigned int uiAddress, unsigned char ucData)
{
while(EECR & (1<<EEWE));
EEAR= uiAddress;
EEDR = ucData;
// EECR |= (1<<EEMWE); // EEMWE == bit2 lt. avr/iom8.h
// EECR |= (1<<EEWE); // EEWE == bit1
asm volatile (
"sbi 0x1c,2" "\r\n"
"sbi 0x1c,1" "\r\n"
);
}
Hier ist der Fehler im Programm aus irgend einem Grund rafft er das
nicht!!
EECR |= (1<<EEMWE); // EEMWE == bit2 lt. avr/iom8.h
EECR |= (1<<EEWE); // EEWE == bit1
Weis einer warum er das nicht rafft ? ergibt meiner meinung nach keinen
sinn!
Was "rafft er nicht"? Wird falscher Code für die Zeilen
EECR |= (1<<EEMWE); // EEMWE == bit2 lt. avr/iom8.h
EECR |= (1<<EEWE); // EEWE == bit1
produziert? Wenn ja, welcher? Und nach deiner Änderung zu asm()-Variante
funktioniert es?
Wenn ja, dann: Welchen GCC hast du? Bei mir wird durch WinAVR 20070122
(GCC 4.1.1) bei beiden Varianten der gleiche Code produziert.
Einstellungen im Makefile s. Anhang (Optimierung: s)
Mein Listing (test.lss, Ausschnitt):
1
void EEPROM_write(unsigned int uiAddress, unsigned char ucData)
ICh danke euch für eure Hilfe wir wissen warum es nicht geht es liegt am
Compeiler wir hätten uns noch dusselig suchen können fals es
Interressiert ich benutze das myAVR Workpad