Hallo ich verwende fastavr als Compiler und möchte mit dem Interrupt Urxc eine bestimmte aktion durchführen. Also das etwas passiert wenn etwas an die Serielle Schnittstelle gesendet wird habe ich schon hinbekommen allerdings scheint das Programm stehen zu bleiben nachdem der Interrupt Ausgelößt wurde. Was kann ich machen damit er wieder ins Hauptprogramm zurückkehrt?
:-) hehe ja hast recht hätt ich auch mal drauf kommen können das zu posten ;-) also so sieht es aus: '///////////////////////////////////////////////////////// '/// FastAVR Basic Compiler for AVR by MICRODESIGN /// '/// Name of Your project '///////////////////////////////////////////////////////// $Device= 4433 ' used device $Stack = 32 ' stack depth $Clock = 4 ' adjust for used crystal $Source=On ' basic source in Asm $Lcd = PORTB.0, RS = PORTD.3, EN =PORTD.4, 16,2 $Baud = 9600 Dim serial As String*8 Dim a As Integer Dim b As Integer Dim c As Integer Dim d As Integer Dim e As Integer Dim f As Integer Dim g As Integer Dim h As Integer Declare Sub main() Declare Interrupt Urxc() Enable Interrupts Enable Urxc DefLcdChar 0, &h07, &h05, &h07, &h00, &h00, &h00, &h00, &h00 DDRD=&HFF PORTD.2=1 Sub main() Do Start Adc a = (Adc(0)/2)-276 b = (Adc(1)/2)-278 c = (Adc(2)/2)-278 d = (Adc(3)/2)-276 'Locate 1,1 'Lcd Adc(0) 'Locate 2,1 'Lcd Adc(1) Stop Adc Cls Locate 1,1 Lcd "T1:" Locate 1,4 Lcd a Locate 1,6 Lcd Chr(0) Lcd "C" Locate 1,9 Lcd "T2:" Locate 1,12 Lcd b Locate 1,14 Lcd Chr(0) Lcd "C" Locate 2,1 Lcd "T3:" Locate 2,4 Lcd c Locate 2,6 Lcd Chr(0) Lcd "C" Locate 2,9 Lcd "T4:" Locate 2,12 Lcd d Locate 2,14 Lcd Chr(0) Lcd "C" WaitMs 150 Loop End Sub Interrupt Urxc() Start Adc e=Adc(0) f=Adc(1) g=Adc(2) h=Adc(3) Stop Adc Print e Print f Print g Print h End Interrupt main() Achso noch eine kleine Anmerkung der Interrupt lässt sich genau ein mal auslösen. Dann bleibt das Programm stehen...
liegt es vielleicht daran, dass Du das UDR-Byte nicht ausliest, und deswegen kein neues Empfangen kannst bzw. kein neues Interrupt ausgelöst wird? Ich Kenne mich mit dem Compiler leider nicht aus, aber da es Basic sehr ähnlich sieht, vermute ich, dass da irgendeine Anweisung zum Auslesen des UDR fehlt...
das kann es eigentlich nicht sein, da fehlendes Lesen von UDR bewirkt, dass das RXC nicht gelöscht wird, also nach reti + 1 Befehl direkt wieder ein Rx-Int erfolgen würde. Mit Basic kenne ich mich aber überhaupt nicht aus, vielleicht mal im Simulator laufen lassen?
Hallo Kenne mich mit FastAvr zwar nicht aus, aber probiere mal "save all" bei der Interrupt Routine. Vielleicht war es das ja MFG Dieter Hilfe: When the Interrupt routine is more complex, use Save 2, Save 3 or Save All.
Natürlich liegst Du mit reti + 1 richtig, nur weiss man ja nicht, wie der Compiler das Problem löst. Vielleicht liegt es auch daran, dass die Interruptroutine ziemlich lang, mehrfach aufgerufen wird und leider zu einem Stack-Überlauf führt. Abhilfe wäre ja: Entgegennahme des Interrupt, Flag setzen, im Hauptprogramm auf Flag reagieren und ADC-Kram ausführen. Hauptprogramm würde die ganze Zeit nach dem Flag gucken und bei gesetztem die ADC-Sachen machen, Flag löschen und somit Interrupt wieder zulassen. Simulator wäre eine Möglichkeit, ASM-Datei posten eine weitere... Gruß Rahul
Ok ich werde eure Vorschläge mal Testen sollte das nichts bringen kann ich die ASM datei mal Posten soweit aber schonmal Danke :-)
Hier nun der ASM Code ich hab es jetzt so gemacht das in der interrupt routine eine Variable gesetzt wird die dann im Hauptprogramm abgefragt wird. Ausserdem lässt der Controller noch eine LED blinken wenn die AD werte über die Serielle Schnittstelle gesendet werden. Es scheint so zu sein, als ob die Interrupt routine ständig ausgeführt wird ich weiß aber nicht warum... So hier nun der Inhalt der ASM Datei: .include "C:\FASTAVR\inc\4433DEF.INC" ; .DSEG serset: .byte 1 serial: .byte 9 a: .byte 2 b: .byte 2 c: .byte 2 d: .byte 2 .CSEG .ORG 0 rjmp _Reset .ORG INT0addr reti .ORG INT1addr reti .ORG ICP1addr reti .ORG OC1Aaddr reti .ORG OVF1addr reti .ORG OVF0addr reti .ORG SPIaddr reti .ORG URXCaddr rjmp IntN8 _Reset: ldi yl,low(RAMEND) out SPL,yl sbiw yl,32 ldi zl,0x18 out UCSRB,zl ldi zh,high(25) ldi zl,low(25) out UBRR,zl rcall LcdIni ;****** USERS BASIC CODE ********************** ;-Line--0020----Enable Interrupts-- sei ;-Line--0021----Enable Urxc-- sbi UCSRB,7 ;-Line--0022----DefLcdChar 0, &h07, &h05, &h07, &h00, &h00, &h00, &h00, &h00-- ldi r24,0x40 rcall _LCtr LcdCh0: .db 0x07,0x05,0x07,0x00,0x00,0x00,0x00,0x00 ldi zl,low(LcdCh0*2) ldi zh,high(LcdCh0*2) rcall _Def ldi r24,1 rcall _LCtr ldi zl,2 rcall _Wms ;-Line--0023----DDRD=&HFF-- ldi zl,low(255) out ddrd,zl ;-Line--0024----PORTD.2=1-- sbi PORTD,2 ;-Line--0025----serset = 0-- ldi zl,low(0) sts serset,zl ;-Line--0027----main:-- main: ;-Line--0028----Do -- L0000: ;-Line--0031----If serset=1 Then-- lds r24,serset ldi zl,low(1) cp r24,zl breq PC+0x02 rjmp L0003 L0004: ;-Line--0032----PORTD.2=0-- cbi PORTD,2 ;-Line--0033----Start Adc-- ldi zl,0x85 out ADCSR,zl ;-Line--0034----Print Adc(0)-- ldi zl,low(0) out ADMUX,zl rcall _Adc rcall _W2Str rcall _PrBW rcall _PCL ;-Line--0035----Print Adc(1)-- ldi zl,low(1) out ADMUX,zl rcall _Adc rcall _W2Str rcall _PrBW rcall _PCL ;-Line--0036----Print Adc(2)-- ldi zl,low(2) out ADMUX,zl rcall _Adc rcall _W2Str rcall _PrBW rcall _PCL ;-Line--0037----Print Adc(3)-- ldi zl,low(3) out ADMUX,zl rcall _Adc rcall _W2Str rcall _PrBW rcall _PCL ;-Line--0038----Stop Adc-- cbi ADCSR,7 ;-Line--0039----serset = 0-- ldi zl,low(0) sts serset,zl ;-Line--0040----WaitMs 150-- ldi zl,low(150) rcall _wms ;-Line--0041----PORTD.2=1-- sbi PORTD,2 ;-Line--0042----Enable Urxc-- sbi UCSRB,7 ;-Line--0043----End If-- L0003: L0002: ;-Line--0045----Start Adc-- ldi zl,0x85 out ADCSR,zl ;-Line--0046----a = (Adc(0)/2)-276-- ldi zl,low(0) out ADMUX,zl rcall _Adc push zh push zl ldi zl,low(2) ldi zh,high(2) pop r24 pop r25 rcall Di16u push zh push zl ldi zl,low(276) ldi zh,high(276) pop r24 pop r25 sub r24,zl sbc r25,zh mov zl,r24 mov zh,r25 sts a,zl sts a+1,zh ;-Line--0047----b = (Adc(1)/2)-278-- ldi zl,low(1) out ADMUX,zl rcall _Adc push zh push zl ldi zl,low(2) ldi zh,high(2) pop r24 pop r25 rcall Di16u push zh push zl ldi zl,low(278) ldi zh,high(278) pop r24 pop r25 sub r24,zl sbc r25,zh mov zl,r24 mov zh,r25 sts b,zl sts b+1,zh ;-Line--0048----c = (Adc(2)/2)-278-- ldi zl,low(2) out ADMUX,zl rcall _Adc push zh push zl ldi zl,low(2) ldi zh,high(2) pop r24 pop r25 rcall Di16u push zh push zl ldi zl,low(278) ldi zh,high(278) pop r24 pop r25 sub r24,zl sbc r25,zh mov zl,r24 mov zh,r25 sts c,zl sts c+1,zh ;-Line--0049----d = (Adc(3)/2)-276-- ldi zl,low(3) out ADMUX,zl rcall _Adc push zh push zl ldi zl,low(2) ldi zh,high(2) pop r24 pop r25 rcall Di16u push zh push zl ldi zl,low(276) ldi zh,high(276) pop r24 pop r25 sub r24,zl sbc r25,zh mov zl,r24 mov zh,r25 sts d,zl sts d+1,zh ;-Line--0055----Stop Adc-- cbi ADCSR,7 ;-Line--0057----Cls-- ldi r24,1 rcall _LCtr ldi zl,0x02 rcall _Wms ;-Line--0058----Locate 1,1-- ldi r24,0x7F push r24 ldi zl,low(1) pop r24 add r24,zl rcall _LCtr ;-Line--0059----Lcd "T1:"-- ldi zl,low(S00*2) ldi zh,high(S00*2) rcall _LSc ;-Line--0060----Locate 1,4-- ldi r24,0x7F push r24 ldi zl,low(4) pop r24 add r24,zl rcall _LCtr ;-Line--0061----Lcd a-- lds zl,a lds zh,a+1 rcall _I2Str rcall _LBW ;-Line--0062----Locate 1,6-- ldi r24,0x7F push r24 ldi zl,low(6) pop r24 add r24,zl rcall _LCtr ;-Line--0063----Lcd Chr(0)-- ldi zl,low(0) mov r24,zl rcall _Lch ;-Line--0064----Lcd "C"-- ldi zl,low(S01*2) ldi zh,high(S01*2) rcall _LSc ;-Line--0065----Locate 1,9-- ldi r24,0x7F push r24 ldi zl,low(9) pop r24 add r24,zl rcall _LCtr ;-Line--0066----Lcd "T2:"-- ldi zl,low(S02*2) ldi zh,high(S02*2) rcall _LSc ;-Line--0067----Locate 1,12-- ldi r24,0x7F push r24 ldi zl,low(12) pop r24 add r24,zl rcall _LCtr ;-Line--0068----Lcd b-- lds zl,b lds zh,b+1 rcall _I2Str rcall _LBW ;-Line--0069----Locate 1,14-- ldi r24,0x7F push r24 ldi zl,low(14) pop r24 add r24,zl rcall _LCtr ;-Line--0070----Lcd Chr(0)-- ldi zl,low(0) mov r24,zl rcall _Lch ;-Line--0071----Lcd "C"-- ldi zl,low(S01*2) ldi zh,high(S01*2) rcall _LSc ;-Line--0073----Locate 2,1-- ldi r24,0xBF push r24 ldi zl,low(1) pop r24 add r24,zl rcall _LCtr ;-Line--0074----Lcd "T3:"-- ldi zl,low(S03*2) ldi zh,high(S03*2) rcall _LSc ;-Line--0075----Locate 2,4-- ldi r24,0xBF push r24 ldi zl,low(4) pop r24 add r24,zl rcall _LCtr ;-Line--0076----Lcd c-- lds zl,c lds zh,c+1 rcall _I2Str rcall _LBW ;-Line--0077----Locate 2,6-- ldi r24,0xBF push r24 ldi zl,low(6) pop r24 add r24,zl rcall _LCtr ;-Line--0078----Lcd Chr(0)-- ldi zl,low(0) mov r24,zl rcall _Lch ;-Line--0079----Lcd "C"-- ldi zl,low(S01*2) ldi zh,high(S01*2) rcall _LSc ;-Line--0080----Locate 2,9-- ldi r24,0xBF push r24 ldi zl,low(9) pop r24 add r24,zl rcall _LCtr ;-Line--0081----Lcd "T4:"-- ldi zl,low(S04*2) ldi zh,high(S04*2) rcall _LSc ;-Line--0082----Locate 2,12-- ldi r24,0xBF push r24 ldi zl,low(12) pop r24 add r24,zl rcall _LCtr ;-Line--0083----Lcd d-- lds zl,d lds zh,d+1 rcall _I2Str rcall _LBW ;-Line--0084----Locate 2,14-- ldi r24,0xBF push r24 ldi zl,low(14) pop r24 add r24,zl rcall _LCtr ;-Line--0085----Lcd Chr(0)-- ldi zl,low(0) mov r24,zl rcall _Lch ;-Line--0086----Lcd "C"-- ldi zl,low(S01*2) ldi zh,high(S01*2) rcall _LSc ;-Line--0087----WaitMs 150-- ldi zl,low(150) rcall _wms ;-Line--0088----Loop-- rjmp L0000 L0001: ;-Line--0091----Interrupt Urxc()-- ;-Line--0092----serset=1-- IntN8: in r2,SREG ldi zl,low(1) sts serset,zl ;-Line--0093----Disable Urxc-- cbi UCSRB,7 ;-Line--0094----End Interrupt-- out SREG,r2 reti ;-Line--0095----GoTo main-- rjmp main ;****** END OF USER BASIC CODE **************** ; String constants: S00: .db "T1:", 0 S01: .db "C", 0 S02: .db "T2:", 0 S03: .db "T3:", 0 S04: .db "T4:", 0 ;////// Print Byte & Word ///////////////// _PrBW: ld r24,Z+ tst r24 breq _PBW1 rcall _Pch rjmp _PrBW _PBW1: ret ;////// Print Cr, Lf & any char//////////// _PCL: ldi r24,13 rcall _Pch ldi r24,10 _Pch: sbis UCSRA,5 rjmp _Pch out UDR,r24 ret ;////// LcdInit /////////////////////////// LcdIni: in zl,DDRB ori zl,0x0f out DDRB,zl sbi DDRD,3 sbi DDRD,4 cbi PORTD,3 cbi PORTD,4 ldi zl,16 rcall _Wms ldi r24,0x03 rcall _LOut ldi zl,5 rcall _Wms rcall _LEN ldi zl,6 rcall _Wus rcall _LEN cbi PORTB,0 rcall _LEN ldi r24,0x28 rcall _LCtr ldi r24,0x06 rcall _LCtr ldi r24,0x0c rcall _LCtr ldi r24,0x01 rcall _LCtr ldi zl,0x03 rcall _Wms ret _Lch: sbi PORTD,3 rjmp _LNib _LCtr: cbi PORTD,3 _LNib: mov r21,r24 swap r24 rcall _LOut mov r24,r21 _LOut: in r23,PORTB andi r23,0xf0 andi r24,0x0f or r24,r23 out PORTB,r24 rcall _LEN ret ;////// LcdEN ///////////////////////////// _LEN: sbi PORTD,4 nop nop cbi PORTD,4 push zl ldi zl,0x04 rcall _Wus pop zl ret ;////// LCD Byte & Word /////////////////// _LBW: ld r24,Z+ tst r24 breq _LBW1 rcall _Lch rjmp _LBW _LBW1: ret ;////// LCD string constants ////////////// _LSc: lpm tst r0 breq _LSc1 mov r24,r0 rcall _Lch adiw zl,1 rjmp _LSc _Lsc1: ret ;////// ADC /////////////////////////////// _Adc: sbi ADCSR,6 _Adc1: sbic ADCSR,6 rjmp _Adc1 in zl,ADCL in zh,ADCH ret ;////// CopyLCDChars ////////////////////// _Def: ldi r25,0x08 _Def1: lpm adiw zl,0x01 mov r24,r0 rcall _Lch dec r25 brne _Def1 ret ;////// IntToStr ////////////////////////// _B2str: clr zh clt rjmp _W2st4 _W2str: clt rjmp _W2st4 _I2str: clt sbrs zh,0x07 rjmp _W2st4 com zl com zh subi zl,-0x01 sbci zh,-0x01 set _W2st4: push yl clr r6 st -Y,r6 _N2str: ldi xl,0x10 sub xh,xh _N2st1: lsr r6 rol zl rol zh rol xh rol r6 cpi xh,0x0a brcs _N2st2 sbci xh,0x0a inc zl _N2st2: dec xl brne _N2st1 subi xh,-0x30 st -Y,xh mov xh,zl or xh,zh brne _N2str _N2st5: brtc _N2st3 ldi zl,0x2d st -Y,zl _N2st3: mov zl,yl pop yl ret ;////// _Waitms /////////////////////////// _Wms: ldi r20,0x14 _Wms1: ldi r21,0x42 _Wms2: dec r21 brne _Wms2 dec r20 brne _Wms1 dec zl brne _Wms ret ;////// _waitus /////////////////////////// _wus: ldi r22,12 _wus1: dec r22 brne _wus1 dec zl brne _wus ret ;////// 16/16 unsigned division /////////// Di16u: mov r22,zl mov r23,zh mov zl,r24 mov zh,r25 clr r24 sub r25,r25 ldi r20,0x11 d16u1: rol zl rol zh dec r20 brne d16u2 ret d16u2: rol r24 rol r25 sub r24,r22 sbc r25,r23 brcc d16u3 add r24,r22 adc r25,r23 clc rjmp d16u1 d16u3: sec rjmp d16u1 ;System Global Variables: 0 bytes ;User Global Variables: 18 bytes
wenn die ständig ausgeführt wird, macht das Sinn - hatte ich schon geschrieben - um das RxC-zu löschen, muss man UDR lesen. Wenn Statusbits per Software gelöscht werden sollen, ist i.a. das Schreiben einer "1" nötig, beim RxC steht das allerdings nicht dabei... Also lies das UDR. Hat mal jemand probiert, ob sich das RxC-Bit durch Schreiben einer 1 löschen lässt?
So ich hab jetzt einfach mit der Holzhammer Methode ein bisschen ASM Code in den Basic Code gepackt und es geht :-) es lag tatsächlich am UDR
Ich hab es noch nicht ausprobiert. Im Normalfall verwendet man ja auch die Daten von der seriellen Schnittstelle für irgendwas und nicht nur zu Triggern eines ADC. Das einfachste ist UDR auszulesen.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.