Hallo, Ich möchte mittels externen Interrupt Impulse zählen. Bei steigender Flanke soll ein Interrupt ausgelöst werden. Wenn die Impulse eine kurze Dauer haben funktioniert das auch wunderbar. Bei längeren Impulsen wird leider bei steigender und bei fallender Flanke ein Interrupt ausgelöst. Interruptkonfiguration: GICR |= (1<<INT0); GICR &= ~((1<<IVSEL)|(1<<IVCE)); MCUCR |= ((1<<ISC01)|(1<<ISC00)); Kann mir bitte jemand sagen wieso bei längeren Impulsen der Interrupt bei fallender Flanke auch ausgelöst wird? Mfg. Carl
>wie kann ich die fallende Flanke entprellen?
Kommt drauf an was du am Interrupt Pin angeschlossen hast.
Bei mechanischen Kontakten hilft nur eine längere Zeit warten.
am interrupt pin ist der ausgang eines komperators angeschlossen
Was für einen Komparator? Und was vergleicht der? Gib doch mal die Schaltung preis..
Den Komparator zum Schmitt-Trigger umbauen, d.h. eine Hysterese einbauen, damit Rauschen an der Schaltgrenze kein Bündel von Flankenwechseln auslöst.
ich verwende den internen komperator dey µC.
1 | #include <avr/io.h> // Deklarationen |
2 | #include <stdio.h> |
3 | |
4 | #define BAUD 9600 // Symbol fuer Baudrate
|
5 | #define TAKT 3686400 // Symbol fuer Controllertakt
|
6 | #define TEILER (long)TAKT/(16*(long)BAUD) - 1 // Symbol fuer Teiler
|
7 | |
8 | #include <avr/interrupt.h> |
9 | //#include <avr/signal.h>
|
10 | |
11 | |
12 | |
13 | void UART_Init(void) // UART initialisieren |
14 | {
|
15 | UBRRL = TEILER; // Baudrate einstellen |
16 | UCSRB |= (1<<RXEN); // Empfaenger ein |
17 | UCSRB |= (1<<TXEN); // Sender ein |
18 | UCSRB |= (1<<RXCIE); // Empfaengerinterrupt frei |
19 | }
|
20 | |
21 | |
22 | void UART_putch(unsigned char data) // warten und Zeichen nach Sender |
23 | {
|
24 | //warte bis UDR leer ist UCSRA / USR bei z.B.: 2313
|
25 | while (!(UCSRA&0x20)); |
26 | //sende
|
27 | UDR = data; |
28 | }
|
29 | |
30 | |
31 | void UART_putstr(unsigned char *zeiger) // String bis Endemarke ausgeben |
32 | {
|
33 | while (*zeiger != 0) |
34 | {
|
35 | while (!(UCSRA&0x20)); // warte bis Datenregister frei |
36 | UDR = *zeiger; // Zeichen nach Sendedatenregister |
37 | zeiger++; |
38 | }
|
39 | }
|
40 | |
41 | |
42 | |
43 | |
44 | SIGNAL(SIG_INTERRUPT0) |
45 | {
|
46 | |
47 | UART_putstr("steigende Flanke \r\n"); |
48 | |
49 | }
|
50 | |
51 | int main(void) // Hauptfunktion |
52 | {
|
53 | |
54 | |
55 | UART_Init(); // UART initialisieren |
56 | |
57 | /*
|
58 | PD2 mit PC0 verbinden
|
59 | PD6 mit POTI
|
60 | PD7 mit Sensor braun
|
61 | PC0 mit PD2 verbinden
|
62 | PC1 mit LED auf AVR Platine verbindne
|
63 | PC2 mit LED auf Sensor schwarz
|
64 | |
65 | grau, weiß auf +5V
|
66 | violett GND
|
67 | */
|
68 | |
69 | |
70 | DDRD &= ~((1<<PB2)|(1<<PB6)|(1<<PB7)); |
71 | PORTD&= ~((1<<PB2)|(1<<PB6)|(1<<PB7)); |
72 | |
73 | |
74 | DDRC |= ((1<<PC0)|(1<<PC1)|(1<<PC2)); |
75 | PORTC |= ((1<<PC0)|(1<<PC1)); |
76 | PORTC &= ~(1<<PC2); |
77 | |
78 | GICR |= (1<<INT0); |
79 | GICR &= ~((1<<IVSEL)|(1<<IVCE)); |
80 | |
81 | MCUCR |= ((1<<ISC01)|(1<<ISC00)); |
82 | |
83 | |
84 | sei(); |
85 | |
86 | |
87 | ACSR &= ~((1 << ACD)|(1 << ACBG)); |
88 | |
89 | |
90 | |
91 | while(1) // Arbeitsschleife ist leer |
92 | {
|
93 | |
94 | if(bit_is_set(ACSR,5)==0) |
95 | {
|
96 | PORTC |= ((1<<PC0)|(1<<PC1)); |
97 | PORTC &= ~(1<<PC2); |
98 | }
|
99 | |
100 | else
|
101 | {
|
102 | PORTC &= ~((1<<PC0)|(1<<PC1)); |
103 | PORTC |= (1<<PC2); |
104 | }
|
105 | |
106 | |
107 | } //end while(1) |
108 | |
109 | } // Ende main |
Was nu ? INT0 oder Komparator. Im Programm hast Du die ISR auf INT0 liegen, machst aber auch Einstellungen für den Komparator.
Der interne Komparator hat einen eigenen Interrupt, der ebenfalls auf fallende oder steigende Flanke konfigurierbar ist. Das was Du da machst, macht so keinen Sinn. BTW: SIGNAL ist veraltet. Nimm ISR und die dazu passenden Vektornamen. Schau Dir mal Kapitel 19 im AVR-GCC-Tutorial und die libc-Dokumentation an.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.