DU(!) denkst zu kompliziert. Der AVR und sein Maschinencode/Assembler ist einfacher. Der macht, was DU(!) ihm aufzwingst.oben bereits alle Operationen genannt. Mit den vier CALLs kannst Du die Adresse einer Subroutine anspringen, mit RET zurückkehren.
Um die Übergabe irgendwelcher Parameter oder Ergebnisse mußt Du Dich selbst kümmern.
;************************************************************************* ; Issues a start condition and sends address and transfer direction. ; return 0 = device accessible, 1= failed to access device ; ; extern unsigned char i2c_start(unsigned char addr); ; addr = r24, return = r25(=0):r24 ;************************************************************************* .global i2c_start .func i2c_start i2c_start: sbi SDA_DDR,SDA ;force SDA low rcall i2c_delay_T2 ;delay T/2 rcall i2c_write ;write address ret .endfunc
Wo steht denn das der Übergabe Parameter in R24 geschrieben wird? Woher weiß ich das denn?
CodeBox Assembler;************************************************************************* ; Issues a start condition and sends address and transfer direction. ; return 0 = device accessible, 1= failed to access device ; ; extern unsigned char i2c_start(unsigned char addr) ; ; addr = r24, return = r25(=0):r24 ;*************************************************************************
Der AVR kennt keine Variablen - er hat nur seine Speicherzellen. In den Rechenregistern, salopp gesagt auch in den I/O-Registern, im SRAM, im Eeprom, im Flash.Ich sehe nirgends eine Zuweisung..
ldi tmp , ( 1<<WGM12 | ( 1<<CS12 | 1<<CS10 ) ) ; Normal Mode -> CTC out TCCR1B , tmp ; Register beschreiben ldi tmp , 1<<OCIE1A ; Output Compare Match Enable out TIMSK , tmp ; Timer Interrupt Register beschreiben ldi tmp , 255 ; Output Compare Match Wert out OCR1AL , tmp ; .. Register beschreiben ldi tmp , 100 ; Output Compare Match Wert out OCR1AH , tmp ; .. Register beschreiben sei ; Interrupts freigeben mainLoop: rjmp mainLoop ;########################################################## ; Timer Interrupt - Compare Match A ;########################################################## timer0CmpInt: eor eorReg, tmp andi eorReg , 1<<1 out PORTB , eorReg reti
ldi tmp , 100 ; Output Compare Match Wert
Offensichtlich versuchst Du von Assembler aus eine C-Funktion aufzurufen. Dann mußt Du Dich natürlich an die C-Konventionen halten. Der erste Byte-Parameter wird immer in R24 übergeben, der Rückgabewert steht in R24:R25.Wo steht denn das der Übergabe Parameter in R24 geschrieben wird? Woher weiß ich das denn? Ich sehe nirgends eine Zuweisung..
Offensichtlich versuchst Du von Assembler aus eine C-Funktion aufzurufen. Dann mußt Du Dich natürlich an die C-Konventionen halten. Der erste Byte-Parameter wird immer in R24 übergeben, der Rückgabewert steht in R24:R25.
Es gibt eine AN von Atmel, in der das beschrieben ist, heißt, wenn ich mich recht erinnere: Mixing Assembly and C.
Wo "hier"?Aber sobald ich hier einen Wert >99 rein schreibe, kackt irgendwas ab???
Das habe ich mich auch gefragt. Wollte einfach nur mal eine Led toggeln, es war aber der Fall das die ganze Zeit der ganze Port beteidigt war. Daher habe ich irgendwie versucht nur das eine Bit zu maksieren.. Hat wie du angemerkt hast nicht wirklich geklappt.Aber was soll Deine komische ISR machen?
Dein tmp-Register war ja (zuletzt) mit 100=0x64=&B01100100 beladen.
;########################################################## ; Timer Interrupt - Compare Match A ;########################################################## timer0CmpInt: ldi tmp, 1 eor toggleBit, tmp out PORTB , toggleBit reti
Okay.. Hatte ich auch erst dran gedacht.. Danke!Hmmmm....
Druckfehler. Sollte eigentlich b2 heissen, wenn man sich die abfolge der bytes anschaut.
73 de addi
Naja, Du hattest diese komische Routine geschrieben, Du solltest also ein Ziel damit gehabt haben.Ist eigentlich viel einfacher..
Was willst du mir damit jetzt sagen? Sollte ich vorher die Daten auf dem Stack sichern? Das war jetzt ja nur ein Test um zu sehen wie man ein Bit toggelt..OR manipuliert das SREG, außerdem werden zwei Rechenregister verändert.
Da Dein Hauptprogramm nie weiß, wann/ob der IRQ zuschlägt, sind diese Register (also auch das SREG) nie verwendbar.
Klar kannst Du (bei reinem Assemblercode) Rechenregister für eine oder alle ISRs reservieren, ansonsten mußt Du Dich aber um das retten der Inhalte kümmern.
Wenn Du Rechenregister reservierst, mußt DU das im gesamten restlichen Programm beachten.