Forum: Mikrocontroller und Digitale Elektronik Analog Comparator Tiny13


von Mr. X (Gast)


Lesenswert?

Hallo,

ich möchte, dass mein Tiny13 bei jeder Flanke an ADC1 (verglichen mit 
der internen Referenzspannung) einen Interrupt auslöst und einen anderen 
Pin togglet.

Hier ist mein Code:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
char on = 0;
5
void toggleLED()
6
{
7
  if (on == 0)
8
  {
9
    PORTB |=  (1<<PB4);
10
    on = 1;
11
  }
12
  else
13
  {
14
    PORTB &= ~(1<<PB4);
15
    on = 0;
16
  }
17
}
18
19
ISR (ANA_COMP_vect)
20
{
21
  toggleLED();
22
}
23
24
int main()
25
{
26
  ADCSRA &=~(1 << ADEN);
27
  ADCSRB |= (1 << ACME);
28
29
  ADMUX = (1 << MUX0);
30
31
  ACSR = (0 << ACD) | (1 << ACBG) | (1 << ACIE) | (1 << ACIS1) | (1 << ACIS0);
32
33
  sei();
34
35
  while (1) { }
36
}
37
38
Leider togglet der Pin PB4 nicht. Was mache ich falsch?

von spess53 (Gast)


Lesenswert?

Hi

>ich möchte, dass mein Tiny13 bei jeder Flanke an ADC1 (verglichen mit...

Datenblatt:

ACIS1  ACIS0     Interrupt Mode
  1      1       Comparator Interrupt on Rising Output Edge.

MfG Spess

von Mr. X (Gast)


Lesenswert?

Ok,

aber dann müsste er trotzdem mit halber Frequenz blinken. Der Interrupt 
wird aber garnicht ausgelöst!

von Johannes M. (johnny-m)


Lesenswert?

Toggeln macht man mit einem EXOR, da braucht man auch keine zusätzliche 
Variable.
1
PORTB ^= 1 << PB4;
macht das, wofür Du oben ne ganze Funktion geschrieben hast...

Wenn da allerdings an dem Pin tasächlich etwas nach außen sichtbares 
passieren soll, wäre es vielleicht sinnvoll, den Port auch als Ausgang 
zu konfigurieren...

von Mr. X (Gast)


Lesenswert?

Danke für den Hinweis! :-)

Aber mein eigentliches Problem löst das nicht... :-(

von STK500-Besitzer (Gast)


Lesenswert?

Du solltest noch den Portpin als Ausgang programmieren (das war das, was 
Johnny meinte)

von Mr. X (Gast)


Lesenswert?

Ok,

ich habe als erste Zeile in
1
main()
 folgendes eingefügt:
1
    DDRB |= (1 << PB4);

Damit ist PB4 als Ausgang definiert. Ich kann den Pin auch normal 
togglen (in der while-Schleife, mit Delays dazwischen). Das Problem 
liegt wirklich darin, dass der Interrupt nicht ausgelöst wird. Ich habe 
eine Dreieckspannung mit 0,5Hz von 0V bis 3V an ADC1 gelegt. Die ISR 
müsste also wirklich aufgerufen werden. Tut sie aber nicht.

von Diensthabender Troll (Gast)


Lesenswert?

Mister Icks, meinst Du, dass Du mit Versuch und Irrtum bei penetranter 
Vermeidung eigenen analytischen Denkens jemals zum Erfolg kommen wirst? 
Solange Du nicht verstehst, was Du da tust, wird das sowiso nichts. Wenn 
es (noch) zu hoch für Dich ist, dann beginne mit kleineren Dingen.

TvD

von Mr. X (Gast)


Lesenswert?

Ok, es funktioniert. War ein Hardware-Problem in der Schaltung.

Jetzt wird die ISR aufgerufen, jedoch immer zweimal. Das merke ich 
daran, dass die LED nicht (bei 0,5Hz Dreieckspannung) an und ausgeht 
sondern mit 1Hz blitzt. Ich denke, dass hier eine kleine Hysterese nicht 
schlecht wäre. Oder mache ich etwas anderes falsch, dass die ISR immer 
zweimal aufgerufen wird?

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.