Hallo, ich habe jetzt einige Zeit im Netz gesucht aber keine Lösung gefunden - vielleicht stehe ich auch einfach auf dem Schlauch... Ich habe einen Atmega328p und möchte über den Analog Comparator den Ladezustand eines Kondensators messen um damit die Kapazität bestimmen zu können. Es sollen ca. 1pF-500pF gemessen werden. Nun habe ich von dem ACSR Register und dem ACI Bit gelesen. Mir fehlt aber eine Vorlage um das auf Papier bringen zu können. Ich möchte die interne ACBG Referenz verwenden und damit dann die Zeit messen bis der Kondensator (bis ACBG) aufgeladen ist. Gibt es da ein Beispiel in C?
Hugo P. schrieb: > Gibt es da ein Beispiel in C? Ein Beispiel für Zeitmessungen in C? Nicht eins, sondern ganz sicher tausende und mehr! Such dir eins aus.
Gast
#5376881
Hugo P. schrieb: > Ich habe einen Atmega328p und möchte über den Analog Comparator den > Ladezustand eines Kondensators messen um damit die Kapazität bestimmen > zu können. Es sollen ca. 1pF-500pF gemessen werden. Ab gewisser Genauigkeitsanforderungen würde ich 1pF als "sportlich" bezeichnen.
Habe jetzt das probiert - jedoch macht der Atmega328 immer einen Reset!?
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | |
82 | |
83 | |
84 | |
85 | |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
Ich komme bis zu dem while(!util_IsBitSet(ACSR, ACI)) - dann gibt es einen Reset. Im Debugger sehe ich, dass das ACI Flag gesetzt ist.
Das Bit soll ja gesetzt sein, wenn der Komparator den gewünschten Zustand erkannt hat...was er vielleicht hat? Ich finde es auch ein wenig krude, die Ein- und Ausgabe-Steuerung auf die Makros zu verteilen und dahinter PC1 und PC0 zu legen. Ich hätte eher mit etwas in der Form DDRC = (1 << PC0) | (1 << PC1) gerechnet, irgendwie in Funktionen gekapselt. (Der Compiler macht daraus bei Bedarf ohnehin Inline-Konstrukte.)
Gast
#5377225
ist der gezeigte Code wirklich von dir?
Das ganze ist ja noch im Aufbau und nur für Tests gedacht. Jedoch komme ich nicht darauf warum der AVR einen Reset macht!? In die ISR Routine kommt er gar nicht mehr.
Gast
#5377236
Hugo P. schrieb: > ISR(ANA_COMP_vect) > { > // clear interrupt > sbi(ACSR, ACI); > } > Ich komme bis zu dem while(!util_IsBitSet(ACSR, ACI)) - dann gibt es > einen Reset. Im Debugger sehe ich, dass das ACI Flag gesetzt ist. Die While Schleife dürfte nie verlassen werden, weil laut Datenblatt das Bit bei Ausführung der ISR gelöscht wird: "Bit 4 – ACI: Analog Comparator Interrupt Flag This bit is set by hardware when a comparator output event triggers the interrupt mode defined by ACIS1 and ACIS0. The Analog Comparator interrupt routine is executed if the ACIE bit is set and the I-bit in SREG is set. ACI is cleared by hardware when executing the corresponding interrupt handling vector. Alternatively, ACI is cleared by writing a logic one to the flag." Hast du auch einen Schaltplan zu deinem Projekt?
Der Fehler:
1 | |
Es gehört:
1 | |
Nun gibt es keinen Reset mehr! Der Compiler hat aber nicht gemeckert...
Jetzt habe ich noch eine Frage. Ich habe nun den Source so umgebaut:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | |
82 | |
83 | |
84 | |
85 | |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | |
98 | |
99 | |
100 | |
101 | |
102 | |
103 | |
104 | |
105 | |
106 | |
107 | |
108 | |
109 | |
110 | |
111 | |
112 | |
113 | |
114 | |
115 | |
116 | |
117 | |
118 | |
119 | |
120 | |
121 | |
122 | |
123 | |
124 | |
125 | |
126 | |
127 | |
128 | |
129 | |
130 | |
131 | |
132 | |
133 | |
134 | |
135 | |
136 | |
137 | |
138 | |
139 | |
140 | |
141 | |
142 | |
143 | |
144 | |
145 | |
146 | |
147 | |
148 | |
149 | |
150 | |
151 | |
Mit dem Oszi messe ich eine Zeit von ~205µs. Ich habe einen 12MHz Quarz und einen Prescaler von 1. Somit sollte in ICR1 ein Wert von ~2500 rauskommen. Ich bekomme aber bei 100 Werten im Mittel zwischen 120-140 Counts. Das sind dann 1/12000000 * 130 == ~11µs ?? Der PD5 wird nur als Trigger für das Oszi hergenommen (Channel 3, blau). Channel 1, gelb, ist die Spannung am Kondensator.
EDIT: uint8_t average[100] = {0};
Kann nicht gehen in einem uint8_t array uint16_t Werte abzulegen.
Jetzt bekomme ich einen Wert von ~2475:
Das sind dann ca. 0,00020625 Sekunden. Passt also!
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.
