Hallo,
Ich versuche derzeit den Pin OC1B in einer genau festgelegten Zeit zu
clearen (auf GND setzen).
Meine Idee war dazu den 16Bit Timer des Atmega8 zu benutzen:
- Pin OC1B (=PB2) in DDRB als Ausgang definieren.
- Timer konfigurieren für "Normal Mode": WGM13:10 = 0
- und dann den Compare Match an den Pin koppeln: COM1B1 = 1 (Clear bei
Compare Match)
- Nach einem Compare Match will ich den Timer anhalten und zurücksetzen
für das nächste Event
Starte ich nun den Timer, tritt der Compare Match ein (Geprüft über
Compare match Interrupt)
Mein Problem ist, dass ich es nicht schaffe, den Pin OC1B zu setzen
(also auf 5V zu legen). Dies macht dann auch irgendwie das Clearen
überflüssig :P
Ich habe bereits probiert:
Erster Versuch:
=> Hat keinerlei Auswirkung
Zweiter Versuch:
pseudocode:
1 | 1. COM1B1:0 = 0 also den timer von OC1B abkoppeln
|
2 | 2. PORTB = (1<<PB2)
|
3 | 3. COM1B1 = 1 also clear on compare match weder aktivieren
|
=> dies hat auch keinerlei Auswirkung... OC1B ist immer auf GND (eine
angeschlosssene LED leuchtet nicht)
Füge ich zwischen 2. und 3. ein kurzes delay ein, sehe ich die led kurz
aufblinken. Aber sobald 3. ausgeführt wird ist die led wieder auf GND
Hier der komplette code:
Erwartetes Verhalten:
Taster (an INT0) wird gedrückt
LED an OC1B sollte leuchten
ca. 2sec später:
LED an OC1B sollte erlöschen
LED an PD6 wird per software getoggled
Beobachtetes Verhalten:
Taster (an INT0) wird gedrückt
LED an OC1B geht für 50ms an, dannach wieder aus
nach 2 sekunden:
LED an PD6 wechselt status
LED an OC1B bleibt aus
1 | #include <avr/io.h>
|
2 | #include <stdint.h>
|
3 | #include <stdlib.h>
|
4 | #define F_CPU 8000000UL
|
5 | #include <util/delay.h>
|
6 | #include <inttypes.h>
|
7 | #include <avr/interrupt.h>
|
8 |
|
9 | #define led2_an PORTD|=(1<<PD6)
|
10 | #define led2_aus PORTD&=~(1<<PD6)
|
11 | #define led2_toggle PORTD=PORTD ^ (1<<PD6)
|
12 |
|
13 | #define starttimer TCCR1B = (1<<CS12) | (1<<CS10) // Timer/Counter 1 prescaler=1024 -> 0.12ms per timer update (8.38s until 16bit overflow)
|
14 | #define stoptimer TCCR1B =0 //stop timer
|
15 | void port_init(){
|
16 | DDRD = 0;
|
17 | DDRD = (1<<PD6); //signal led
|
18 | DDRB |= (1<<PB2); // timer controlled led
|
19 | }
|
20 |
|
21 | ISR(INT0_vect){
|
22 | TCCR1A &= ~( (1<<COM1B0) | (1<<COM1B1) ); //disconnect OCR1B (PB2) from timer
|
23 | _delay_ms(50);
|
24 | PORTB |= (1<<PB2); //enable PB2
|
25 | _delay_ms(50);
|
26 | TCCR1A |= (1<<COM1B1); //clear OCR1B on compare match //reconnect PB2 to timer
|
27 | starttimer;
|
28 | }
|
29 |
|
30 | ISR(TIMER1_COMPB_vect){
|
31 | stoptimer;
|
32 | TCNT1 = 0; //reset timer value to 0
|
33 | led2_toggle;
|
34 | }
|
35 |
|
36 | int main (void)
|
37 |
|
38 | {
|
39 | port_init();
|
40 |
|
41 |
|
42 | MCUCR |= (1<<ISC01); //falling edge of INT0 generates interrupt request
|
43 | GICR |= (1<<INT0); //enale external pin interrupt INT0
|
44 |
|
45 | OCR1B = 0x3FFF; //load OCR1B (ca. 2sec)
|
46 |
|
47 | TIMSK = (1<<OCIE1B); //compare match with OCR1B generates interrupt request
|
48 |
|
49 | sei(); //enable interrupts
|
50 |
|
51 | led_aus;
|
52 |
|
53 | while (1) {
|
54 | _delay_ms(10);
|
55 | }
|
56 | }
|
Über jede Hilfe bzw. Tipps würde ich mich sehr freuen.