Hallo,
ich bin noch ziemlicher anfänger in der c- und mikrocontroller
-programmierung und versuche zur Zeit, eine Servosteuerung mittels
pwm-signal zu realisieren. Dabei soll Timer2 die pwm-signale erzeugen,
was auch gut funktioniert. Allerdings möchte ich dem Servo mittels
timer1 (16-bit-timer) ein gewisses "zeitgefühl" geben, also die
verschiedenen Servopositionen sollen verschieden lange (zw. 3 und 8
sek.) angesteuert werden.
Hier Ausschnitte vom Code:
1 | #include <avr/io.h>
|
2 | #include <stdint.h> //was ist das??
|
3 | #include <avr/interrupt.h>
|
4 |
|
5 | struct {
|
6 | unsigned Interrupt_BIT_1:1;
|
7 | } volatile x;
|
8 |
|
9 | // Initialisierung für Timer1
|
10 | void timer_warte_initial (void) {
|
11 |
|
12 | TCNT1 = 0x0000; //Startwert 0 setzen
|
13 | TIMSK = (1<<OCIE1A); //Output Compare Interrupt enable
|
14 | sei(); //Enable Global Interrupt
|
15 | TCCR1A = 0x00;
|
16 | TCCR1B = ((1<<WGM12) | (1<<CS12)); //CTC-Mode, Prescaler 256
|
17 | }
|
18 |
|
19 | //Interrupt-service- Routine
|
20 | ISR(TIMER1_COMPA_vect) { //Compare Match A - Vector
|
21 | x.Interrupt_BIT_1 = 1;
|
22 | reti(); // beendet die ISR
|
23 | }
|
24 |
|
25 | int main(void) {
|
26 | sei();
|
27 |
|
28 | timer2_initial();
|
29 | OCR2 = 0x3A;
|
30 |
|
31 | while(1) {
|
32 |
|
33 | if (ADWert > 624) {
|
34 | OCR2 = 0x99;
|
35 | OCR1A = 0x5b8d; // 23437,5 (3 Sek.) Output-compare-register, soll Interrupt auslösen
|
36 | timer_warte_initial(); // startet timer1
|
37 | }
|
38 |
|
39 | if (x.Interrupt_BIT_1 ==1) {
|
40 | OCR2 = 0x19;
|
41 | }
|
42 | }
|
43 | }
|
Dazu muss ich noch erwähnen, dass an den AD_wandler ein Abstandssensor
angeschlossen ist, welcher Werte in ADWert schreibt. Der AD-wandler und
die gelieferten Werte stimmen aber alle.
also was das Programm manchen soll, ist Folgendes: Wenn der AD-Wandler
einen Wert >624 liefert, soll die Servoposition 0x99 angefahren werden,
Timer1 soll gestartet werden, welcher nach 3 Sekunden (OCR1A = 0x5b8d,
CTC-Mode, Prescaler 256, CPU-Takt 2 MHz) einen Interrupt auslöst.
In der Interrupt-Routine wird die Variable x.Interrupt_BIT_1 auf 1
gesetzt und die Routine wird verlassen. Im Hauptprogramm wird der Wert
dieser Varablen abgefragt und wenn der Wert = 1 ist, soll die
Servoposition
OCR2 = 0x19 angefahren werden.
Das funktioniert aber nicht, irgendwie wird scheinbar die Variable
x.Interrupt_BIT_1 nie auf 1 gesetzt, denn die position OCR2 = 0x19 wird
nie angefahren, sondern immer nur die position OCR2 = 0x3A, das
allerdings nach den gewünschten 3 sek.(s.3.Zeile der main-funktion, wenn
ich diese Zeile weg lasse, bleibt der Servo allerdings immer in der
Position OCR2 = 0x99).
Jetzt ist meine Frage warum das nicht funktioniert.
ich hoffe mein Problem ist deutlich geworden und bin für alle Hinweise
dankbar,
Grüße,
Storm