Forum: Mikrocontroller und Digitale Elektronik ADC in AVR ASM: Was läuft hier schief


von Andreas B. (bitverdreher)


Lesenswert?

Hallo,
anbei mal eine Code, der mittels eines Tasters mit einem ATTiny10 ein 
Gerät ein/ausschalten soll.
Das funktioniert auch soweit gut.
Nun soll auch die Betriebsspannung überprüft werden (läuft direkt an 
einer Liion Zelle) und bei ca. 3V das Gerät abgeschaltet werden.
Dazu ist Pin 3 (PB1) extern an 1.8V angeschlossen.
Das Problem ist nun, daß der ADC scheinbar nie angesprochen wird. Ich 
habe mal probeweise in die ISR des ADCs den Ausgang PB2 aktiviert. Diese 
ISR wird nie angesprungen.
Wo ist hier mein Denkfehler?

Hier der Code:
1
;-----------------------------------------------------------------------------
2
;* Switcher for ATtiny10 and Bluetooth loop    
3
;*
4
;* PB0 = Button
5
;* PB1 = ADC connected to 1.8V Pin12 XS3868 (reference for ADC is Vcc = Vbatt of LiIon)
6
;*       < 3,0V should be a ADC value > 154. Use 150 for security
7
;* PB2 = Gate mosfet, 0 = switch on the BT and amplifier!
8
;* PB3 = Status LED + Tx to bluetooth module
9
;*
10
;* off= 8uA, on 0.97mA 5V
11
;* off= 5uA, on 0.60mA 3V3
12
;-----------------------------------------------------------------------------
13
14
.include "tn10def.inc"
15
16
.org 0
17
rjmp RESET        ; Reset Handler
18
rjmp INT0         ; IRQ0 Handler
19
rjmp PCINT0       ; PCINT0 Handler
20
rjmp TIM0_CAPT    ; Timer0 Capture Handler
21
rjmp TIM0_OVF     ; Timer0 Overflow Handler
22
rjmp TIM0_COMPA   ; Timer0 Compare A Handler
23
rjmp TIM0_COMPB   ; Timer0 Compare B Handler
24
rjmp ANA_COMP     ; Analog Comparator Handler
25
rjmp WDT          ; Watchdog Interrupt Handler
26
rjmp VLM          ; Voltage Level Monitor Handler
27
rjmp ADCCH        ; ADC Conversion Handle
28
29
30
; defines + equ
31
;-----------------------------------------------------------------------------
32
.def  save_sreg         = r16
33
.def  iwr0              = r17
34
.def  iwr1              = r18
35
 
36
.def  key_old           = r19
37
.def  key_state         = r20
38
.def  key_press         = r21
39
 
40
.def  rTEMP             = r22
41
.def  adc_value         = r23
42
43
; IRQs
44
;-----------------------------------------------------------------------------
45
46
TIM0_COMPA:                   ; IRQ Timer0 compare match A
47
   in     save_sreg, SREG
48
49
; Timer-Verfahren (nach Peter Dannegger): http://www.mikrocontroller.net/articles/Entprellung
50
get8key:                         ;/old      state     iwr1      iwr0
51
   mov    iwr0, key_old       ;00110011  10101010            00110011
52
   in     key_old, PINB       ;11110000
53
   eor    iwr0, key_old       ;                              11000011
54
   com    key_old             ;00001111
55
   mov    iwr1, key_state     ;                    10101010
56
   or     key_state, iwr0     ;          11101011
57
   and    iwr0, key_old       ;                              00000011
58
   eor    key_state, iwr0     ;          11101000
59
   and    iwr1, iwr0          ;                    00000010
60
   or     key_press, iwr1     ;store key press detect
61
   out    SREG, save_sreg
62
   reti
63
64
ADCCH:
65
   in adc_value, ADCL
66
   reti
67
      
68
69
; not used IRQs      
70
TIM0_CAPT:      
71
TIM0_OVF:
72
TIM0_COMPB:
73
ANA_COMP:
74
      reti
75
      
76
;-----------------------------------------------------------------------------
77
78
; Start, Power On, Reset
79
RESET:
80
WDT:
81
VLM:
82
; initialize SP
83
   ldi rTEMP, HIGH(RAMEND)
84
   out SPH, rTEMP
85
   ldi rTEMP, LOW(RAMEND)     
86
   out SPL, rTEMP
87
88
   rcall SetLowClock
89
90
   sbi ACSR, ACD                 ; disable AC
91
92
; set ADC clock dividier to 8, irq on, auto trigger, free running in ADCSRB is default
93
   ldi rTemp, 1<<ADPS0 | 1<<ADPS1 | ADIE | ADATE
94
   out ADCSRA, rTemp
95
   sbi DIDR0, ADC1D              ; deactivate digital input PB1 (1V8)
96
   sbi ADMUX, MUX0               ; set AD mux to PB1  (1V8)
97
   cbi ADCSRA, ADEN              ; disable ACD
98
   ldi rTEMP, 1<<PRADC 
99
   out PRR, rTEMP                ; shut down ACD
100
101
   ldi rTEMP, 1<<PB2
102
   out DDRB, rTEMP               ; Out -> Mosfet (-> BT)
103
104
   sbi PUEB, PUEB0               ; Pullup an PB0 (Button)
105
   
106
   ldi rTEMP, 1<<OCIE0A          ; enable timer compare A interrupt 
107
   out TIMSK0, rTEMP
108
109
   clr key_old
110
   clr key_state
111
   clr key_press
112
   
113
   sbi PORTB, PB2                ; switch BT off
114
115
   
116
mainloop: 
117
   cli
118
   sbis PORTB, PB2
119
   rjmp status_on
120
121
status_off:
122
   rjmp check_key
123
124
status_on:
125
   mov rTEMP, adc_value          ; check battery
126
   sbci rTEMP, 150
127
   brcc switch_to_off            ; low battery
128
129
check_key:
130
   sbrs key_press, PB0           ; skip the next if key 0 is pressed
131
   rjmp endloop
132
   
133
   clr key_press                 ; clear, if key press action done
134
   sei
135
   sbis PORTB, PB2
136
   rjmp switch_to_off
137
     
138
switch_to_on:                    ; actual status is off
139
   cbi PORTB, PB2                ; switch BT on (out is GND)
140
   rcall SetHighClock
141
142
   ldi rTemp, 0
143
   out PRR, rTemp                ; power on ACD (+ Timer/Counter)
144
   sbi ADCSRA, ADEN              ; enable ACD
145
   sbi ADCSRA, ADSC              ; start first ADC conversion
146
147
   rjmp endloop
148
   
149
switch_to_off:                   ; actual status is on 
150
   sbi PORTB, PB2                ; switch BT off (out is Vcc)
151
   rcall SetLowClock
152
153
   cbi ADCSRA, ADEN              ; disable ACD
154
   ldi rTemp, 1<<PRADC
155
   out PRR, rTemp                ; shut down ACD
156
157
endloop:   
158
   clr key_press                 ; clear, if key press action done
159
   sei
160
   sleep
161
   rjmp mainloop
162
163
; set clock to 500Hz
164
SetLowClock:
165
   ldi rTEMP, 0xD8
166
   out CCP, rTEMP                ; Configuration Change Protection Register
167
   ldi rTEMP, 0x01               ; Clock source 128kHz
168
   out CLKMSR, rTEMP         
169
170
; Clock dividier 256
171
   ldi rTEMP, 0xD8
172
   out CCP, rTEMP                ; Configuration Change Protection Register
173
   ldi rTEMP, 1<<CLKPS3          ; Clk / 256 -> Clock 500Hz
174
   out CLKPSR, rTEMP
175
176
   ldi rTEMP, 1<<CS00 | 1<<WGM02 ; clock divide by 1 + CTC mode A
177
   out TCCR0B, rTEMP 
178
179
   ldi rTEMP, 0x00
180
   out OCR0AH, rTEMP 
181
   ldi rTEMP, 0x80 
182
   out OCR0AL, rTEMP             ; load timer with 0x80FF
183
   ret
184
185
;Set clock to 1MHz
186
SetHighClock:
187
   ldi rTEMP, 0xD8
188
   out CCP, rTEMP                ; Configuration Change Protection Register
189
   ldi rTEMP, 0x00               ; Clock source 8MHz
190
   out CLKMSR, rTEMP         
191
192
; Clock dividier 8
193
   ldi rTEMP, 0xD8
194
   out CCP, rTEMP                ; Configuration Change Protection Register
195
   ldi rTEMP, 1<<CLKPS0 | 1<<CLKPS1 ; Clk / 8 -> Clock 1 MHz
196
   out CLKPSR, rTEMP
197
198
   ldi rTEMP, 1<<CS00 | 1<<CS02 | 1<<WGM02 ; clock divide by 1024 + CTC mode A
199
   out TCCR0B, rTEMP 
200
201
   ldi rTEMP, 0x01
202
   out OCR0AH, rTEMP 
203
   ldi rTEMP, 0x00 
204
   out OCR0AL, rTEMP             ; load timer with 0x100FF (for 1MHz / 1024)
205
   ret

Gruß
Andreas

von spess53 (Gast)


Lesenswert?

Hi

>Wo ist hier mein Denkfehler?

hier:

 ldi rTemp, 1<<ADPS0 | 1<<ADPS1 | ADIE | ADATE
                                 ^^^^^^ ^^^^^^

MfG Spess

von Andreas B. (bitverdreher)


Lesenswert?

Aua, Tomaten auf den Augen. Und ich such mir hier einen Wolf.

Danke Dir!
Andreas

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
Noch kein Account? Hier anmelden.