MoinMoin
ich hab mal wieder ein kleines Problem, ich möchte mit dem
Analogkomparator eine Spannung messen.
Meine Spannung gebe ich auf PinA0, den Komp habe ich auf interne
Bandgabreferenz gestellt, und den Multiplexer eingeschaltet. Per polling
hat das auch alles wunderbar geklappt, Spannung größer Bandgap --> LED
an und andersrum. Dann hab ich versucht, das ganze per Interrupt zu
lösen, jeddoch wird mein Interrupt nicht ausgelöst. ACO wechselt aber je
nachdem, ob ich positivere oder negativere Spannung an PinA0 geb, das
sehe ich per OCD. Globale Interrupts sind auch aktiviert, in einem alten
Beitrag hab ich gelesen, das es auf die Reihenfolge ankommt, in der man
den AC initialisiert. Also hab ichs wie dort gemacht, ACD ein,
Einstellungen machen, ACO wieder aus, und dann ACIE (die
Komparatorinterrupts) an. Auch erfolglos....
Das ganze läuft auf nem Mega32, wie oben schon erwähnt.
Für weiterführende Hinweise wäre ich sehr dankbar,
MfG Chaos =)
Hier noch der Quelltext
1
/*
2
* Lueftercontroller.c
3
*
4
* Created: 09/07/2014 21:35:30
5
* Author: Ich
6
*/
7
8
9
#include<avr/io.h>
10
#include<avr/interrupt.h>
11
#include<inttypes.h>
12
13
ISR(ANA_COMP_vect)
14
{
15
uint8_tArbeitsreg=0;
16
17
Arbeitsreg=ACSR&(1<<ACO);
18
19
if(Arbeitsreg==0)
20
{
21
PORTB&=~(1<<PB0);
22
}
23
24
if(Arbeitsreg==ACO)
25
{
26
PORTB|=(1<<PB0);
27
}
28
}
29
30
31
voidinit(void);
32
33
34
35
intmain(void)
36
{
37
init();
38
39
while(1)
40
{
41
uint8_ti=0;//um zu sehen, ob etwas passiert
42
i=PORTC;
43
i++;
44
PORTC=i;
45
}
46
}
47
48
49
50
51
52
voidinit(void)
53
{
54
TCCR0=(1<<WGM00)|(1<<WGM01)|(1<<COM00)|(1<<COM01)|(1<<CS01);//Timer0 init auf FastPWM Inverting Mode, Prescaler 1
55
DDRB=(1<<PB3)|(1<<PB0);//auf Ausgang setzen, um den Ausgangstreiber vom OC-Pin zu aktivieren
56
DDRC=255;
57
ACSR|=(1<<ACD);
58
ACSR|=(1<<ACBG);//AnalogComparator auf interne Referenz am +Eingang
199
2503Q–AVR–02/11
ATmega32(L)
Analog Comparator
Control and Status
Register – ACSR
• Bit 7 – ACD: Analog Comparator Disable
When this bit is written logic one, the power to the Analog Comparator
is switched off.
edit sagt: weiter unten schaltest du es ja wieder aus.
>> if (Arbeitsreg == ACO)
tut nicht, was du erwartest.
ja ich schalte das ACD bit ein, damit der der AC ausgeschaltet ist,
stelle ihn dann ein, und dann schalte ich ihn wieder ein, indem ich das
ACD-bit lösche. So stand es in dem Thread.
Aber auch ohne das Aus- und wieder Einschalten geht es nicht.....
und nochmal, der AC an sich geht ja, ich sehe ja, wie sich das ACO-Bit
ändert, wenn ich die Spannung höher oder tiefer setze als die
Bandgapspannung. Nur der Interrupt wird halt nicht ausgelöst
Noch etwas, ich habe mir nun mal klugerweise einen Breakpoint in den
Interrupt gesetzt, und siehe da, er springt ihn doch an. Seltsamerweise
funktionieren zb der Timer und UART-IRQ auch im SingleStepModus, weiß
zufällig wer, warum das beim AC_IRQ nicht so ist?
Nun verstehe ich aber auch den Hinweis
>> >> if (Arbeitsreg == ACO)>> tut nicht, was du erwartest.
Egal wie ACO gerade steht, es wird immer if(Arbeitsreg == 0) ausgeführt,
wenn ich aber if(Arbeitsreg = 0) schreibe, dann führt er immer den
Else-Zweig aus.
Das funktioniert wie erwartet. Vermutlich ist das ACO also nicht 32
sondern 5. Naja selber denken führt auch zum Ziel.
Dank an Crazyhorse für den Gedankenanstoss =)
MfG Chaos
@ ich
heißt das, wenn ich if(Arbeitsreg = x) wird das Arbeitsreg auf x
gesetzt?
Und was ist dann die Bedingung, dafür das die Schleife ausgeführt wird?
Ob das Arbeitsregister überhaupt da, also 1 ist? oder wird der If-Zweig
ausgeführt, solange x != 0?
Der IF-Zweig wird ausgeführt wenn die bedingung Wahr ist. Hier das
Register GLEICH 0 (Nicht NULL ich unterscheide beides da es für mich zum
lesen leichter ist, einmal wert und einmal ein Pointer mit Null).
Das Arbeitsregister wird tatsächlich auf x gesetzt.
Eine schleife kann ich (außer der üblichen while(1) Schleife) nicht
sehen.
Diese wird ausgeführt solange der Ausdruck wahr ist (in C also !=0).
MfG
ich
Da haste Recht, das würde reichen, das war nur im Testwahn so entstanden
*gg
Auhja, das sieht komfortabel aus! Was is denn dieses CodeVision? auch
eine IDE?
ich schrieb:> Der IF-Zweig wird ausgeführt wenn die bedingung Wahr ist. Hier das> Register GLEICH 0 (Nicht NULL ich unterscheide beides da es für mich zum> lesen leichter ist, einmal wert und einmal ein Pointer mit Null).> Das Arbeitsregister wird tatsächlich auf x gesetzt.> Eine schleife kann ich (außer der üblichen while(1) Schleife) nicht> sehen.> Diese wird ausgeführt solange der Ausdruck wahr ist (in C also !=0).> MfG> ich
Ja schleife war der falsche Begriff, der kam mir nur in den Kopf, weil
ich genau an diese ominöse while(1)-Geschichte denken musste.
Danke euch beiden nochmal, wieder ein kleines Stückchen mehr C
verstanden =)