Hallo,
ich bin gerade dabei mit dem Analog Comparator des Atmega8 einen Sinus
am Eingang in ein Rechtecksignal am Ausgangsport umzuwandeln.
Eigentlich trivial, aber... :-)
Das einfache Programm toggelt einfach bei jedem Interrupt den Port-Pin
und sollte eigentlich nur bei einer steigenden Flanke ausgeführt werden.
Leider wird das Eingangsignal beim Ausführen des ISR gestört und führt
zu weiteren Interrupts bis der Sinus wieder steigt. So sieht es
zumindest auf dem Oszi aus.
Warum? KEINE AHNUNG.
Auf jeden Fall soll der ISR nur einmal bei der Steigenden Flanke
ausgeführt werden. Wie kann ich überhaupt verhindern, dass der ISR bei
einem Sinus x-Mal läuft?
Was sagt ihr?
Im Anhang:
- Die Eingangsbeschaltung des Comparators (erstellt mit Freeware
Schematic Tool "Post-it".)
- Oszi Screen-shot zeigt das Eingangsignal(A) mit ausgeschaltetem AVR
- Oszi Screen-shot zeigt das Eingangsignal und Ausgangssingnal(B) mit
laufenden AVR
Bin schon gespannt..
Lg,
Wauschi
1 | #ifndef F_CPU
|
2 | #define F_CPU 8000000UL
|
3 | #endif /**< clock frequency in Hz, used to calculate delay timer */
|
4 |
|
5 | #include <avr/delay.h>
|
6 | #include <avr/sfr_defs.h>
|
7 | #include <avr/interrupt.h>
|
8 | #include <avr/iom8.h>
|
9 | #include <avr/io.h>
|
10 | #include "lcd.h"
|
11 |
|
12 | ISR(ANA_COMP_vect){
|
13 | // toggle led to visualize isr is executed
|
14 | PORTC ^= _BV(0);
|
15 | }
|
16 |
|
17 | void comparator_init()
|
18 | {
|
19 | // Enable Analog Comparator
|
20 | ACSR &= ~_BV(ACD);
|
21 | // Enable comp interrupt
|
22 | ACSR |= _BV(ACIE);
|
23 | // Enable Comparator Input Capture
|
24 | ACSR |= _BV(ACIC);
|
25 | // Interrupt on rising edge
|
26 | ACSR |= _BV(ACIS0)|_BV(ACIS1);
|
27 | }
|
28 |
|
29 | int main(void)
|
30 | {
|
31 | DDRC = 0x01;
|
32 | PORTC = 0x01;
|
33 | comparator_init();
|
34 |
|
35 | // Gobally enable interrupts
|
36 | sei();
|
37 | while(1)
|
38 | {
|
39 | _delay_ms(200);
|
40 | }
|
41 |
|
42 | }
|