Hallo Ich möchte jetzt das erste mal mit einer Interupt steuerung arbeiten. Ich habe mir im AVR GCC Tutorial die Interupt Steuerung mal durchgelesen, aber es sind noch ein Paar Fragen offen. 1. Ich möchte Temperatur sensoren über I2C auslesen um ein System abhängig von Min. u. Max. Werten entsprechend zu kühlen oder zu heizen. Also sprich ich Lege 2 werte fest TempMin, TempMax, wenn TempMin erreicht ist wird geheizt u. wenn TempMax erreicht ist wird über Lüfter gekühlt. Wie ist das jetzt zu bewerkstelligen ? Der Temperatursensor muss ja dauernd abgefragt werden, um konstant werte zu liefern, die dann mit den TempMin und TempMax Variablen verglichen werden. Wie löse ich nun einen Interupt aus, um aus dieser abfrage und vergleichs routine in die Routine reinspringe in der die Lüfter u. Heizungen angesteuert werden. ? wäre nett wenn Ihr mir helfen könntet ? Gruß Gizmo
Gizmo wrote: > 1. Ich möchte Temperatur sensoren über I2C auslesen um ein System > abhängig von Min. u. Max. Werten entsprechend zu kühlen oder zu heizen. > Also sprich ich Lege 2 werte fest TempMin, TempMax, wenn TempMin > erreicht ist wird geheizt u. wenn TempMax erreicht ist wird über Lüfter > gekühlt. Soweit klar. > > Wie ist das jetzt zu bewerkstelligen ? In einer Schleife ständig die folgenden Aktionen wiederholen Sensor über I2C auslesen Mit Min vergleichen Wenn kleiner -> Heizung ein ansonsten -> Heizung aus Mit Max vergleichen Wenn größer -> Kühlung an ansonsten -> Kühlung aus > > Der Temperatursensor muss ja dauernd abgefragt werden, um konstant werte > zu liefern, die dann mit den TempMin und TempMax Variablen verglichen > werden. Dazu packst du das ganze in eine Schleife und gut ists. > Wie löse ich nun einen Interupt aus, um aus dieser abfrage und > vergleichs routine in die Routine reinspringe in der die Lüfter u. > Heizungen angesteuert werden. ? Kein Mensch braucht dazu einen Interrupt. Aber wenns denn unbedingt sein muss: Du programmierst einen Timer, so dass alle paar Zig-Millisekunden ein Interrupt ausgelöst wird. In der Interrupt Routine finden dann die Abfrage und Auswerte Aktivitäten statt. OK. Einen Vorteil hat diese Variante. Der Prozessor kann sich in der Zwischenzeit schlafen legen und Strom sparen.
erst einmal Danke für Deine Hilfe. könntest Du mir das mit dem Timer genauer erläutern ?
Gizmo wrote: > erst einmal Danke für Deine Hilfe. > > könntest Du mir das mit dem Timer genauer erläutern ? Ein Timer ist erst mal einfach nur eine im µC eingebaute 'Variable'. Diese Variable wird ständig erhöht. Wie schnell sie erhöht wird, wird mit dem Vorteiler des Timers eingestellt. Ein Zähler ist entstanden, der ständig vor sich hinzählt. Soweit so gut und nicht besonders aufregend. Aber: Dieser Zähler hat wie jede andere 'Variable' einen Datentyp. Es gibt 8-Bit Zähler und 16-Bit Zähler. Daraus resultiert, dass es eine Obergrenze gibt, bis zu der dieser Zähler zählen kann. Ist die Obergrenze erreicht, dann passiert ein Overflow und der Zähler beginnt wieder bei 0. Und genau da beginnt die Sache interesant zu werden. Denn dieser Overflow kann einen Interrupt auslösen. Als Folge dieses Interrupts wird ein Interrupt Handler angesprungen, der dann irgendetwas machen kann (während der Zähler immer noch nach wie vor still und heimlich vor sich hinzählt). Alles was man dazu tun muss, ist: * Dem Timer einen Vorteiler einstellen. Dadurch, dass ein Vorteiler aktiviert wird, beginnt der Timer bereits mit seiner Zählerei. Der Vorteiler wird eingestellt, indem man in bestimmten, dem Timer zugeordneten, Steuerregistern bestimmte Bits setzt. Welche das sind -> Datenblatt des Prozessors * In weiteren Steuerregistern des Timers, gibt es Bits für verschiedene Eregnisse, die dem Timer zustossen können, wie zb. das ein Overflow passiert. Wenn man dort das richtige Bit setzt, dann löst der Timer einen Interrupt aus Welche das sind -> Datenblatt des Prozessors * Interrupts muessen generell freiggeben sein. -> sei() aufrufen * Dann muss man noch einen Interrupt Handler schreiben, damit es auch eine Aktion gibt, die bei Auftreten dieses speziellen Interrupts ausgeführt werden soll Und das wars dann auch schon. http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Die_Timer.2FCounter_des_AVR Am Beispiel eines Mega8:
1 | #include <avr/io.h> |
2 | #include <avr/interrupt.h> |
3 | |
4 | volatile uint8_t Cnt; |
5 | |
6 | ISR( TIMER0_OVF_vect ) // wird aufgerufen wenn der Timer 0 |
7 | { // einen Overflow Interrupt auslöst |
8 | Cnt = Cnt + 1; |
9 | |
10 | if( Cnt == 5 ) { // nach dem 5-ten Interrupt |
11 | PORTB = PORTB ^ 0xFF; // alle Pins am Port B umdrehen |
12 | Cnt = 0; |
13 | }
|
14 | }
|
15 | |
16 | int main() |
17 | {
|
18 | DDRB = 0xFF; |
19 | PORTB = 0xAA; |
20 | |
21 | TCCR0 = ( 1 << CS02 ) | ( 1 << CS01 ); // Vorteiler auf 1024 |
22 | TIMSK = ( 1 << TOIE0 ); // Interrupt bei Overflow vom Timer 0 |
23 | |
24 | sei(); |
25 | |
26 | while( 1 ) |
27 | ;
|
28 | }
|
Das lässt ein paar Leds am Port B blinken. Wie schnell sie blinken hängt von der Taktfrequenz des µC ab. Angenommen dein µC läuft mit 1Mhz. Dann gehen diese 1Mhz auch an den Vorteiler. Der teilt durch 1024 1000000 / 1024 = 976 d.h. der Timer wird 976 mal in der Sekunde um 1 erhöht. Da er, als 8 Bit Timer, bis 255 zählen muss ehe dann ein Overflow passiert, bedeutet das, dass 976 / 256 = 3.8 Overflow in einer Sekunde vorkommen. Dementsprechend wird auch die ISR 3.8 mal in der Sekunde aufgerufen. Da aber in der ISR bis 5 gezählt wird, ehe der Port umgeschaltet wird, bedeutet das, dass 3.8 / 5 = 0.76 die angenommenen Led am Port B mit einer Freuqenz von 0.76 Hz umgeschaltet werden. Sie blinken also mit einer Frequenz von 0.38Hz oder ( 1 / 0.38 = 2.6 ) alle 2.6 Sekunden.
Vertippt. Ich hab die falschen Vorteiler Bits genommen. Hier dir korrekten für Mega8 - Timer0 - 1024
1 | #include <avr/io.h> |
2 | #include <avr/interrupt.h> |
3 | |
4 | volatile uint8_t Cnt; |
5 | |
6 | ISR( TIMER0_OVF_vect ) // wird aufgerufen wenn der Timer 0 |
7 | { // einen Overflow Interrupt auslöst |
8 | Cnt = Cnt + 1; |
9 | |
10 | if( Cnt == 5 ) { // nach dem 5-ten Interrupt |
11 | PORTB = PORTB ^ 0xFF; // alle Pins am Port B umdrehen |
12 | Cnt = 0; |
13 | }
|
14 | }
|
15 | |
16 | int main() |
17 | {
|
18 | DDRB = 0xFF; |
19 | PORTB = 0xAA; |
20 | |
21 | TCCR0 = ( 1 << CS02 ) | ( 1 << CS00 ); // Vorteiler auf 1024 |
22 | TIMSK = ( 1 << TOIE0 ); // Interrupt bei Overflow vom Timer 0 |
23 | |
24 | sei(); |
25 | |
26 | while( 1 ) |
27 | ;
|
28 | }
|
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.