Hallo!
Ich habe ein Codeschloss für meine Eingangstür mit dem ATMEGA8
realisiert. Es muss ein 6-stelliger Code eingegben werden, damit der
Türöffner betätigt wird.
Ich suche nun nach einer Möglichkeit bei längerer Unterbrechung der
Tastendrücke den Array-Counter zurückzusetzen und somit den Code als
ungültig zu deklarieren.
Dazu habe ich mir mal den 16bit-Counter des Atmega8 angesehen - leider
komme ich nicht weiter... irgendwie läuft er nicht...
1
ISR(TIMER1_CAPT_vect)
2
{
3
GICR|=(1<<INT0);//Timer Interrupts einschalten
4
TIMSK|=(1<<TOIE1);//Timer1 Interrupt enabled
5
j=0;//Arrayzähler zurücksetzen
6
PORTD|=(1<<PD3);//Akustikes Warnsignal für ungültige Eingabe ausgeben (Summer)
7
_delay_ms(500);
8
PORTD&=~(1<<PD3);
9
}
10
11
12
intmain(){
13
14
TIMSK|=(1<<TICIE1);
15
TCCR1B|=(1<<CS10)|(1<<CS11);//Vorzähler auf 64 = alle 4,19 Sekunden ohne Tastendruck zurücksetzen (nur Testweise - später längere Zeit (10 sek.)
16
...
17
}
Leider reagiert der Timer1 überhaupt nicht. Was habe ich falsch gemacht?
Das Relais für den Türöffner zieht bei richtiger Kombination an.
Erklär doch mal etwas genauer, wie du dir die Funktionsweise gedacht
hattest. Ich sehe nämlich nicht, wie du über einen
Input-Capture-Interrupt den Timeout realisieren willst.
Der Timerzähler wird bei jedem Tastendruck auf 0 gesetzt um ihn vor dem
Überlauf zu schützen. Wenn dieser Tastendruck eine Zeit lang ausbleibt
gibt es einen Overflow und die array-Zähl-Variable j wird auf 0
zurückgesetzt (=erste Zahl).
Ich vermute, dass ich die Interrupts falsch freigeschaltet habe - weiß
aber nicht wo.
> Wenn dieser Tastendruck eine Zeit lang ausbleibt> gibt es einen Overflow ...
Du hast in deinem Code aber einen Input-Capture-Interrupt, keinen
Overflow-Interrupt.
TIMSK |= (1<<TICIE1); -> TIMSK |= (1<<TOIE1);
ISR(TIMER1_CAPT_vect) -> ISR(TIMER1_OVF_vect)
Hallo nochmal!
Sorry für den Doppelpost. Habe mich mal im Internet bzw. hier im
Tutorial schlau gemacht was sei(); ist. Hier mein aktueller Code,
welcher leider immer noch nicht funktioniert... habe ein paar Kommentare
zum besseren Verständnis in den Code gebaut.
Wie kann ich den Interrupt-Timer auf 0 zurücksetzen?
So wie es zur Zeit programmiert ist müsste der Summer alle 4,1 Sek.
einen Pieps von sich geben, was er aber nicht macht. Scheinbar wird die
INT-Routine nicht aufgerufen.
1
#include<avr/io.h>
2
#include<stdint.h>
3
#include<stdio.h>
4
#include<stdlib.h>
5
#define F_CPU 1000000UL
6
#ifndef F_CPU
7
#warning "F_CPU war noch nicht definiert, wird nun mit 1MHz definiert"
8
#define F_CPU 1000000UL /* Quarz mit 1 Mhz */
9
#endif
10
#include<util/delay.h>
11
#include<avr/interrupt.h>
12
13
14
15
volatileintj;
16
17
18
19
ISR(TIMER1_OVF_vect){
20
21
j=0;
22
PORTC|=(1<<PC5);//Summer aktivieren
23
_delay_ms(500);
24
PORTC&=~(1<<PC5);//Summer deaktivieren
25
26
}
27
28
29
30
intmain(){
31
TCCR1B|=(1<<CS10)|(1<<CS11);//Vorteiler Interrupt auf 64 (=alle 4,1 Sek)
> Wie kann ich den Interrupt-Timer auf 0 zurücksetzen?
TCNT1 = 0;
> So wie es zur Zeit programmiert ist müsste der Summer alle 4,1 Sek.> einen Pieps von sich geben, was er aber nicht macht. Scheinbar wird die> INT-Routine nicht aufgerufen.
Ich kann keinen Fehler sehen, und in der Simulation wird der Interrupt
brav alle 4,19 Sek ausgeführt.
AlexL wrote:
> sehr seltsam.... muß man evtl. wenn man ein einer ISR auf einen Port> zugreift irgend etwas beachten?
Nein.
Gibt der Compiler irgendwelche Meldungen/Warnungen aus?
Funktioniert das Flashen einwandfrei?
Flasht du vielleicht ein altes HEX-File?
Geht der Summer überhaupt?
Build succeeded with 0 Warnings...
Summer geht. Habe eben testweise statt dem Summer das Relais ansprechen
lassen - funktioniert auch nicht. Das Hex-File das ich geladen habe
ändert sich mit jedem Build - ist also das richtige. Hab Verify
angestellt. Verify successful.
#define F_CPU 1000000UL /* Quarz mit 1 Mhz */
//Vorteiler Interrupt auf 64 (=alle 4,1 Sek)
---
Wie kommt man auf 4,1 Sek?
1000000/64=15625
1/15625= 64us
X. H. wrote:
> #define F_CPU 1000000UL /* Quarz mit 1 Mhz */> //Vorteiler Interrupt auf 64 (=alle 4,1 Sek)> ---> Wie kommt man auf 4,1 Sek?>>> 1000000/64=15625>> 1/15625= 64us
64µs * 65536 = 4,194304s
Der Interrupt kommt immer, wenn der Timer (16-Bit) überläuft.
Habe eine komische Beobachtung durch Zufall gemacht. Die Funktion main
sollte ja erst ab while(1) {] ständig wiederholt werden. Jedoch zieht
das Relais alle 4,1 Sekunden an, obwohl das nur am Anfang passieren
sollte. Scheinbar macht der AVR bei jedem Timerüberlauf einen Reset -
Durch was könnte das ausgelöst werden? Watchdog? Ist eigentlich nicht
aktiviert...
1
#include<avr/interrupt.h>
2
#include<avr/io.h>
3
#include<stdint.h>
4
#include<stdio.h>
5
#include<stdlib.h>
6
#define F_CPU 1000000UL
7
#ifndef F_CPU
8
#warning "F_CPU war noch nicht definiert, wird nun mit 1MHz definiert"
9
#define F_CPU 1000000UL /* Quarz mit 1 Mhz */
10
#endif
11
#include<util/delay.h>
12
13
14
15
16
volatileintj;
17
18
19
20
ISR(TIMER1_OVF_vect){
21
//j=0;
22
//PORTD |= (1<<PD3);
23
//_delay_ms(200);
24
//PORTD &= ~(1<<PD3);
25
26
}
27
28
29
30
intmain(){
31
sei();
32
TCCR1B|=(1<<CS10)|(1<<CS11);//Vorteiler Interrupt auf 64 (=alle 4,1 Sek)
33
TIMSK|=(1<<TOIE1);//Timer1 Interrupt aktivieren
34
//RELAIS ANZIEHEN - DAS HIER WIRD KOMISCHERWEISE ALLE 4,1 SEK ohne Tastendruck wiederholt.
Was ein Sonntag... ;)
Ich habe noch ein paar Dinge ausprobiert...
1. Ich habe mein stab. Labornetzteil hinter den Festspannungsregler
gelegt (dachte vielleicht reicht der Strom nicht aus)
2. Habe mit dem Oszi am Resetpin gemessen - kein GND-Impuls - also
eigentlich auch kein ungewollter Reset.
3. Fuses habe ich kontrolliert, dass kein Watchdog oder Brown-Out
aktiviert ist. 1MHz interner Takt ist aktiv.
Irgendwie fängt der µC nach Ablauf des Timer1 das Programm von vorne an
zu durchlaufen. Habe testweise mal den Timer0 genommen - genau das
gleiche. Das der Ablauf des Timers dafür verantwortlich ist ist ziemlich
sicher... wenn ich nämlich Tasten drücke während er läuft verzögert sich
der Reset um weitere 4,1 Sek.
Mir scheint es fast so als kenne er die Einsprungadresse für den
Timer1Overflow INTR nicht und nimmt dann anstelle dieser Adresse die
Adresse 0000.
Hätte ich den µC nicht fest in die Schaltung eingelötet würde ich mal
den Baustein wechseln - aber es gehen ja alle anderen Funktionen...
Hat noch jemand eine Idee? Dankeschön!