Forum: Mikrocontroller und Digitale Elektronik Tiny24 Timer1 auslesen


von L. K. (ladde)


Lesenswert?

Hallo!
Ich möchte über die Entladezeit eines Kondensators desssen Kapazität 
bestimmen. Habe dazu den einen Pol an den Komparatoreingang AIN1 
(PortA.2) und über einen Widerstand mit einem Portpin (PortA.3) 
verbunden und den anderen Pol an Masse gelegt. Das Assemblerprogramm 
lädt den Kondensator zunächst 1s lang. Direkt vor dem Entladen wird 
Timer1 gestartet und soll im Komparator-Interrupt ausgelesen und im 
EEPROM gespeichert werden.
Es scheint alles korrekt zu funktionieren (im Komparator-Interrupt wird 
eine LED angeschaltet), jedoch finden sich nach Ablauf des Programms im 
EEPROM unsinnige (viel zu kleine) Werte; das HIGH-Byte ist immer 0x00 
und das LOW-Byte schwankt ungefähr zwischen 0x06 und 0xA4.
Bei der Simulation im AVR-Studio funktionierte alles wie gewünscht, ich 
weiß echt nicht, wo der Fehler liegen könnte.
Hier der aktuelle Quelltext:
1
.include "tn24def.inc"
2
3
.macro ROT_AN
4
  sbi PORTB,0
5
.endmacro
6
.macro ROT_AUS
7
  cbi PORTB,0
8
.endmacro
9
.macro GRUEN_AN
10
  sbi PORTB,1
11
.endmacro
12
.macro GRUEN_AUS
13
  cbi PORTB,1
14
.endmacro
15
.macro C_LADEN
16
  sbi PORTA,3
17
.endmacro
18
.macro C_ENTLADEN
19
  cbi PORTA,3
20
.endmacro
21
22
.cseg
23
.org 0x0000
24
  rjmp main
25
26
.org EXT_INT0addr  ; External Interrupt Request 0
27
  reti
28
.org PCI0addr    ; Pin Change Interrupt Request 0
29
  reti
30
.org PCI1addr    ; Pin Change Interrupt Request 1
31
  reti
32
.org WATCHDOGaddr  ; Watchdog Time-out
33
  reti
34
.org ICP1addr    ; Timer/Counter1 Capture Event
35
  reti
36
.org OC1Aaddr    ; Timer/Counter1 Compare Match A
37
  reti
38
.org OC1Baddr    ; Timer/Counter1 Compare Match B
39
  reti
40
.org OVF1addr    ; Timer/Counter1 Overflow
41
  reti
42
.org OC0Aaddr    ; Timer/Counter0 Compare Match A
43
  reti
44
.org OC0Baddr    ; Timer/Counter0 Compare Match B
45
  reti
46
.org OVF0addr    ; Timer/Counter0 Overflow
47
  reti
48
.org ACIaddr    ; Analog Comparator
49
  rjmp AC_Int
50
.org ADCCaddr    ; ADC Conversion Complete
51
  reti
52
.org ERDYaddr    ; EEPROM Ready
53
  reti
54
.org USI_STRaddr  ; USI START
55
  reti
56
.org USI_OVFaddr  ; USI Overflow
57
  reti
58
59
.org INT_VECTORS_SIZE
60
main:
61
  ldi r16, RAMEND  ;Stackpointer initialisieren
62
  out SPL, r16
63
  ldi r16, 0x03  ;Ausgänge aktivieren
64
  out DDRB, r16
65
  sbi DDRA, 3
66
  ldi ZL, LOW(EEPROM_Daten)
67
  ldi ZH, HIGH(EEPROM_Daten)
68
  ROT_AN
69
  GRUEN_AN
70
  rcall wait1s
71
  ROT_AUS
72
  GRUEN_AUS
73
  rcall wait1s
74
  ROT_AN
75
  GRUEN_AN
76
  C_LADEN
77
  rcall wait1s
78
  ROT_AUS
79
  GRUEN_AUS
80
  cbi ADCSRB, ACME  ;AIN0 und AIN1 als Eingänge verwenden (Mux aus)
81
  cbi ACSR, ACIS1
82
  cbi ACSR, ACIS0
83
  sbi ACSR, ACIE  ;Komparator aktivieren
84
  ldi r16, 0x00
85
  out TCCR1B, r16
86
  out TCNT1H, r16
87
  out TCNT1L, r16
88
  ldi r16, (0<<CS12)|(0<<CS11)|(1<<CS10)
89
  out TCCR1B, r16  ;Timer starten
90
  sbi ACSR, ACI  ;AC-Interrupt zurücksetzen
91
  sei        ;Interrupts global aktivieren
92
  C_ENTLADEN
93
loop:
94
  rjmp loop
95
96
AC_Int:
97
  GRUEN_AN
98
;  ldi r18, 0x00
99
;  out TCCR1B, r18
100
  in r18, TCNT1H
101
  rcall EEPROM_Write
102
  adiw ZL, 1
103
  in r18, TCNT1L
104
  rcall EEPROM_Write
105
  cbi ACSR, ACIE
106
  reti
107
108
EEPROM_Write:
109
  sbic EECR, EEPE
110
  rjmp EEPROM_Write
111
  out EEARH, ZH
112
  out EEARL, ZL
113
  out EEDR, r18
114
  in r18, sreg
115
  cli
116
  sbi EECR, EEMPE
117
  sbi EECR, EEPE
118
  out sreg, r18
119
  ret
120
121
wait1s:
122
  push r16
123
  ldi r16, 0xFA
124
wait1s_inner:
125
  rcall wait1ms
126
  rcall wait1ms
127
  rcall wait1ms
128
  rcall wait1ms
129
  dec r16
130
  brne wait1s_inner
131
  pop r16
132
  ret
133
134
wait1ms:
135
  push r16
136
  push r17
137
  ldi r16, 0x10
138
wait1ms_r16:
139
  ldi r17, 0xA5
140
wait1ms_r17:
141
  dec r17
142
  brne wait1ms_r17
143
  dec r16
144
  brne wait1ms_r16
145
  pop r17
146
  pop r16
147
  ret
148
149
.eseg
150
EEPROM_Daten:

Ich hoffe ihr könnt mir helfen.
Danke und Gruß
Ladde

von Gast (Gast)


Lesenswert?

>jedoch finden sich nach Ablauf des Programms im
>EEPROM unsinnige (viel zu kleine) Werte;

Wie groß sollte der im EEPROM abgespeicherte Wert denn sein?

von L. K. (ladde)


Lesenswert?

Da mit bloßem Auge zu erkennen ist, dass die LED erst aus und nach 
kurzer Zeit wieder an geht (~0,1s) sollte der Timer1 schon mehrfach 
überlaufen bis er ausgelesen wird. Ich erwarte stark schwankende Werte 
(auch im HIGH-Byte), bekomme jedoch auch bei Variation des 
angeschlossenen Kondensators immer unwahrscheinlich kleine Werte 
(HIGH-Byte 0x00, LOW-Byte =< 0xB0).

von spess53 (Gast)


Lesenswert?

Hi

>  in r18, TCNT1H
>  rcall EEPROM_Write
>  adiw ZL, 1
>  in r18, TCNT1L

Falsche Reihenfolge. Erst TCNT1L, dann TCNT1H auslesen.

MfG Spess

von Reinhard R. (reirawb)


Lesenswert?

>  in r18, TCNT1H
>  rcall EEPROM_Write
>  adiw ZL, 1
>  in r18, TCNT1L
>  rcall EEPROM_Write

Also, schau mal auf das Datenblatt, Seite 88, da steht etwas über die 
16-Bit-Zugriffe. Quintessenz des Textes:

16 Bit Schreiben: erst High-Byte, dann Low-Byte
16 Bit Lesen: erst Low-Byte, dann High-Byte

Wenn Du Dir das Blockdiagramm und die Beschreibung auf Seite 92 
durchliest, wird auch klar, warum. Beim Lesen des Low-Bytes wird das 
High-Byte in das Zwischenregister kopiert. Das High-Byte wird danach aus 
dem Zwischenregister gelesen. Liest Du zuerst das High-Byte, ist ja im 
Zwischenregister noch nichts.
Versuch es mal anders herum.

Viel Erfolg.

Reinhard

von L. K. (ladde)


Lesenswert?

Jaaa! Das war's! Spess und Reinhard ihr seid meine Helden ;)
Hätte wohl mal das Datenblatt genauer lesen sollen...
Vielen Dank!

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.