Ich steh hier voll auf dem Schlauch. Im Simulator läuft das Programm, am Device scheint der ATTiny44 nur einmal den Wert korrekt zu messen. Ich möchte über einen Spannungsteiler die Spannung an einem Kondensator messen. Als Messeingang verwende ich dem PA1. PA3 Wechselt auf High wenn meine Schwellspannung erreicht wird. Das klappt aber nicht. Resete ich den ATTiny44 wenn die Schwellspannung höher ist, dann wird PA3 High. Resete ich den ATTiny44 wenn die Schwellspannung niedriger ist, dann ist der PA3 Low. Lade ich den Kondensator bleibt PA3 Low. Der AD-Interrupt scheint aber zu funktionieren, da nur dort der Watchdogtimerreset erfolgt und ein WD-Reset scheinbar nicht ausgelöst wird. Kennt jemand das Problem ? ;* Target : ATTiny44 ;**** includes **** ;Interner Takt 8MHz und Takteiler auf 8 somit effektiev 1MHz .DEF V_Cpower_akt =r2 ;Aktuelle Spannung am GoldCap in cV .DEF V_MicPower_akt =r3 ;Aktuelle Spannung am µ-Controller .DEF V_Cpower_alt =r4 ;Alte Spannung am GoldCap in cV .DEF V_MicPower_alt =r5 ;Alte Spannung am µ-Controller .DEF Flags =r23;Flags |C_V_Busy|Mic_V_Busy|0|0|0|0|0|0| .EQU C_V_Busy =7 .EQU Mic_V_Busy =6 .include "tn44def.inc" .ESEG .ORG 0x00 datx: .DB 1, 2, 3, 4, 5, 6, 7, 8, 9 .CSEG .ORG 0x00 rjmp RESET ; Reset Handle reti ; External Interrupt Request 0 reti ; Pin Change Interrupt Request 0 reti ; Pin Change Interrupt Request 1 reti ; Watchdog Timer Overflow reti ; Timer/Counter1 Capture Event reti ; Timer/Counter1 Compare Match A reti ; Timer/Counter1 Compare Match B reti ; Timer/Counter1 Overflow reti ; Timer/Counter0 Compare Match A reti ; Timer/Counter0 Compare Match B reti ; Timer/Counter0 Overflow reti ; Analog Comparator rjmp ADC_Ready ; ADC Conversion Complete reti ; EEPROM Ready reti ; USI Start Condition reti ; USI Overflow .ORG 0x11 RESET: ldi r16,high(RAMEND) out SPH,r16 ; Stack auf höchste RAM-Adresse ldi r16,low(RAMEND) out SPL,r16 ; Stack auf höchste RAM-Adresse ;Watchdog ldi r16,0b00001011 out WDTCSR,r16 ;Port ini ldi r16,0b00000000 out PORTA,r16 ldi r16,0b00111101 out DDRA,r16 ldi r16,0b00000000 out PORTB,r16 ldi r16,0b00000000 out DDRB,r16 ;AD-Wandler ini ;AD-Wandler ein, Inerrupt ein, Takt 125kHz ldi r16,1<<ADEN|0<<ADSC|0<<ADATE|0<<ADIF|1<<ADIE|3 out ADCSRA,r16 ldi r16,0<<BIN|0<<ACME|0<<ADLAR|0 out ADCSRB,r16 ;Nicht benötigte AD mit 1 ausschalten. ldi r16,0b11111101 out DIDR0,r16 ;Spannung am Kondensator messen Ref 1,1V 1 Digit =0,01 Volt ldi r16,1<<REFS1|1 out ADMUX,r16 sei sbi PORTA,PA2 sbi ADCSRA,ADSC Spannungen_C_messen: sbr Flags,1<<C_V_Busy L1_C_V_Busy: sbrc Flags,C_V_Busy rjmp L1_C_V_Busy sbi ADCSRA,ADSC mov r16,V_Cpower_akt cpi r16,60 brlo Spannungen_C_messen ;warten bis mind. 0,6V am C sbi PORTA,PA3 Spannungen_mC_messen: sbr Flags,1<<C_V_Busy|1<<Mic_V_Busy L1_Mic_V_Busy: sbrc Flags,Mic_V_Busy rjmp L1_Mic_V_Busy sbi ADCSRA,ADSC mov r16,V_MicPower_akt cpi r16,0b10011010 brlo Spannungen_mC_messen ;prüfen ob Mindestspannung am mC überschritten wurde sbi PORTA,PA4 mC_low_check: sbr Flags,1<<C_V_Busy|1<<Mic_V_Busy L2_Mic_V_Busy: sbrc Flags,Mic_V_Busy rjmp L2_Mic_V_Busy sbi ADCSRA,ADSC mov r16,V_MicPower_akt cpi r16,0b10011000 brsh mC_low_check ;prüfen ob Mindestspannung unterschritten wurde. sbi PORTA,PA5 mov r16,V_Cpower_akt cpi r16,60 brlo Spannungen_C_messen ;prüfen ob mind. 0,6V am C sbi PORTA,PA0 mov r17,V_Cpower_akt subi r17,30 I_C_Tr_Check: sbr Flags,1<<C_V_Busy L3_C_V_Busy: sbrc Flags,C_V_Busy rjmp L3_C_V_Busy sbi ADCSRA,ADSC cp V_Cpower_akt,r17 brsh I_C_Tr_Check ;warten bis am C, U um 0,3V gesunken. cbi PORTA,PA0 mC_fall_check: sbr Flags,1<<C_V_Busy|1<<Mic_V_Busy L3_Mic_V_Busy: sbrc Flags,Mic_V_Busy rjmp L3_Mic_V_Busy sbi ADCSRA,ADSC cp V_MicPower_akt,V_MicPower_alt brsh mC_fall_check ;warte bis am mC U fällt. rjmp mC_low_check ADC_Ready: wdr sbrs Flags,C_V_Busy ;wenn C_V_Busy gesetzt dann ist das Ergebnis die Spannung am C rjmp ADC_Ready_MicC cbr Flags,1<<C_V_Busy mov V_Cpower_alt,V_Cpower_akt in r15,ADCH in V_Cpower_akt,ADCL ldi r22,0<<REFS1|1 ;Vorbereitung zu Mic_V Messung out ADMUX,r22 sbrc Flags,Mic_V_Busy sbi ADCSRA,ADSC lsr r15 ror V_Cpower_akt lsr r15 ror V_Cpower_akt ldi r22,1<<REFS1|1 ;Vorbereitung zu Mic_V Messung rückgängig ? sbrs Flags,Mic_V_Busy out ADMUX,r22 reti ADC_Ready_MicC: sbrs Flags,Mic_V_Busy rjmp ADC_Ready_Exit sbi ADMUX,REFS1 mov V_MicPower_alt,V_MicPower_akt clr V_MicPower_akt in r22,ADCH cpi r22,0 brne ADC_Ready_Exit in r15,ADCL mov r22,V_Cpower_akt sub r22,r15 brlo ADC_Ready_Exit ;Spannung < 4,4 Volt inc V_MicPower_akt lsl r22 ;Rest r22 maximal 51 lsl r22 ldi r21,2 neg r15 DIVLOOP: add r22,r15 rol r21 sbrs r21,0 sub r22,r15 lsl r22 sbrs r21,7 rjmp DIVLOOP mov V_MicPower_akt,r21 ADC_Ready_Exit: cbr Flags,1<<C_V_Busy|1<<Mic_V_Busy reti
Beim Auslesen des ADC-Datenregisters muss unbedingt zuerst ADCL gelesen werden und dann ADCH! Der ADC kann nach einem Lesezugriff auf ADCL erst dann wieder einen neuen Wert in die beiden Register schreiben, wenn ADCH gelesen wurde. Wenn ADCL nach ADCH gelesen wird, dann werden die Register blockiert.
>>Wenn ADCL nach ADCH gelesen wird, dann werden >>die Register blockiert. Ganz genau richtig! Und das ist auch keine Schikane, sondern hat seinen guten Grund. Nur so ist sichergestellt, dass Du BEIDE Register ungestört auslesen kannst und nicht (z.b. bei free-running-mode) ein neuer Wert dazwischen funkt. Jochen Müller
Tausend Dank, klar lesen von 16 Bit-Werten beim AVR. Ich Trottel, voll in die Falle getabt. Ich Danke euch herzlich !!!!!!!!!!!!!!!!!!!!!!!!!!!
Ich werd verückt ! Eure Erklärung past genau auf das Fehler Bild, aber das Problem ist immer noch das Gleiche. Ich habe die Interruptroutine nun so geändert:
1 | ADC_Ready: |
2 | wdr |
3 | sbrs Flags,C_V_Busy ;wenn C_V_Busy gesetzt dann ist das Ergebnis die Spannung am C |
4 | rjmp ADC_Ready_MicC |
5 | cbr Flags,1<<C_V_Busy |
6 | mov V_Cpower_alt,V_Cpower_akt |
7 | in V_Cpower_akt,ADCL |
8 | in r15,ADCH |
9 | ldi r22,0<<REFS1|1 ;Vorbereitung zu Mic_V Messung |
10 | out ADMUX,r22 |
11 | sbrc Flags,Mic_V_Busy |
12 | sbi ADCSRA,ADSC |
13 | lsr r15 |
14 | ror V_Cpower_akt |
15 | lsr r15 |
16 | ror V_Cpower_akt |
17 | ldi r22,1<<REFS1|1 ;Vorbereitung zu Mic_V Messung rückgängig ? |
18 | sbrs Flags,Mic_V_Busy |
19 | out ADMUX,r22 |
20 | reti |
21 | |
22 | ADC_Ready_MicC: |
23 | sbrs Flags,Mic_V_Busy |
24 | rjmp ADC_Ready_Exit |
25 | sbi ADMUX,REFS1 |
26 | mov V_MicPower_alt,V_MicPower_akt |
27 | clr V_MicPower_akt |
28 | in r15,ADCL |
29 | in r22,ADCH |
30 | cpi r22,0 |
31 | brne ADC_Ready_Exit |
32 | mov r22,V_Cpower_akt |
33 | sub r22,r15 |
34 | brlo ADC_Ready_Exit ;Spannung < 4,4 Volt |
35 | inc V_MicPower_akt |
36 | lsl r22 ;Rest r22 maximal 51 |
37 | lsl r22 |
38 | |
39 | ldi r21,2 |
40 | neg r15 |
41 | DIVLOOP: |
42 | add r22,r15 |
43 | rol r21 |
44 | sbrs r21,0 |
45 | sub r22,r15 |
46 | lsl r22 |
47 | sbrs r21,7 |
48 | rjmp DIVLOOP |
49 | |
50 | mov V_MicPower_akt,r21 |
51 | |
52 | ADC_Ready_Exit: |
53 | cbr Flags,1<<C_V_Busy|1<<Mic_V_Busy |
54 | reti |
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.