Mikrocontroller und Digitale Elektronik
›
Thread
ATMEGA 168: Register-Einstellungen nacheinander in Ausgänge laden
JW
Julia W
Gast
24.10.2015 08:39
#4321842
Hallo Forum,
ich möchte über den ATMEGA 168 zwei DC-Motoren im PWM-Modus steuern.
Leider funktioniert es momentan nur so, dass nur ein Motor läuft.
hier mal der bisherige c-Code:
#include<avr/io.h>
//#define F_CPU 20000000UL //Taktfrequenz 20MHz
#include<util/delay.h> // Verzögerung
int main(void)
{
DDRB |= (1<<PB2); //initialisieren Output 16 [Motor rechtslauf]
DDRB |= (1<<PB1); //initialisieren Output 15 [Motor linkslauf]
DDRB |= (1<<PB0); //initialisieren Output 14 [Motor rechtslauf]
DDRB |= (1<<PB3); //initialisieren Output 17 [Motor linkslauf]
DDRD |= (1<<PD5); //initialisieren Output 11 [LED]
PORTD |= (1<<PD5); //LED einschalten
unsigned char duty_cyc_a,duty_cyc_b;
duty_cyc_a=0; // Initial Duty Cycle for Channel A
duty_cyc_b=0; // Initial Duty Cycle for Channel B
// erster Motor start: (PB2 im PORTB setzten [1A])
PORTB &= ~(1<< PB1); //PB1 im PORTB löschen [2A]
TCCR2B = (1<<CS21) | (1<<CS20); //Clock select
TCCR2A = (1<<COM2A1) | (1<<WGM21) | (1<<WGM20); //Waveform generation
mode
OCR2A = 0;
OCR2B = 0;
while(duty_cyc_a < 255)
{
OCR2A=duty_cyc_a++;
OCR2B=duty_cyc_b--;
_delay_ms(100);
}
while(duty_cyc_b < 255)
{
OCR2A=duty_cyc_a--;
OCR2B=duty_cyc_b++;
_delay_ms(200);
}
// erster Motor stop
PORTB &= ~(1<< PB2); // PB2 im PORTB löschen [1A]
//zweiter Motor start (PB4 im PORTB setzten [4A])
PORTB &= ~(1<< PB3); // PB3 im PORTB löschen [3A]
TCCR2B = (1<<CS21) | (1<<CS20); //Clock select
TCCR2A = (1<<COM2A1) | (1<<WGM21) | (1<<WGM20); //Waveform generation
mode
OCR2A = 0;
OCR2B = 0;
while(duty_cyc_a < 255)
{
OCR2A=duty_cyc_a++;
OCR2B=duty_cyc_b--;
_delay_ms(100);
}
while(duty_cyc_b < 255)
{
OCR2A=duty_cyc_a--;
OCR2B=duty_cyc_b++;
_delay_ms(200);
}
// zweiter Motor stop
PORTB &= ~(1<< PB4); // PB4 im PORTB löschen [4A]
return 0;
}
___________________________________
ich kann mir schon denken, dass die Register-Einstellung nur einmalig
nach der Input/Output Deklaration gesetzt werden müssen, jedoch schlug
dieser Versuch bei mir ebenfalls fehl.
Könnte mir bitte einer helfen?
M
mecker
Gast
24.10.2015 09:07
#4321849
Julia W schrieb:
> Leider funktioniert es momentan nur so, dass nur ein Motor läuft.
Und wir dürfen raten welcher.
> hier mal der bisherige c-Code:
Ohne Kommentare und Erläuterung (Funktionsbeschreibung) welcher Gedanke
dahinter steckt.
Im allgemeinen wird ein Timer in einem PWM Modus intitialisiert und
seine OCA-Pins bzw OCB-Pins mit dem COM Bits durchgeschaltet. Über die
OCR Register wird der Duty Cycle eingestellt - fertig. Die OC Pins kann
man auf die EN Pins des L293 schalten.
JW
Julia W
Gast
24.10.2015 15:30
#4322147
mecker schrieb:
>> Leider funktioniert es momentan nur so, dass nur ein Motor läuft.
>
> Und wir dürfen raten welcher.
es wird nur PB2 [A1] angesprochen.
wäre es ein Lösungsweg, wenn ich nach dem "erster Motor stop" alle Timer
deaktiviere/ resete und die Ports bis auf den anzusprechenden lösche?
#include<avr/io.h>
//#define F_CPU 20000000UL //Taktfrequenz 20MHz
#include<util/delay.h> // Verzögerung
int main(void)
{
DDRB |= (1<<PB2); //initialisieren Output 16 [Motor rechtslauf]
DDRB |= (1<<PB1); //initialisieren Output 15 [Motor linkslauf]
DDRB |= (1<<PB0); //initialisieren Output 14 [Motor rechtslauf]
DDRB |= (1<<PB3); //initialisieren Output 17 [Motor linkslauf]
DDRD |= (1<<PD5); //initialisieren Output 11 [LED]
PORTD |= (1<<PD5); //LED einschalten
PORTB &= ~(1<< PB1); //PB1 im PORTB löschen [2A], um Invertierung am
[1A] zu vermeiden
PORTB &= ~(1<< PB3); //PB3 im PORTB löschen [3A], um Invertierung am
[4A] zu vermeiden
unsigned char duty_cyc_a,duty_cyc_b;
duty_cyc_a=0; // Initial Duty Cycle for Channel A
duty_cyc_b=0; // Initial Duty Cycle for Channel B
// erster Motor start: (PB2 im PORTB setzten [1A])
PORTB &= (1<< PB2); // PB2 im PORTB setzen [1A]
TCCR2B = (1<<CS21) | (1<<CS20); //Clock select
TCCR2A = (1<<COM2A1) | (1<<WGM21) | (1<<WGM20); //Waveform generation
mode
OCR2A = 0;
OCR2B = 0;
while(duty_cyc_a < 255) //hochfahren
{
OCR2A=duty_cyc_a++;
OCR2B=duty_cyc_b--;
_delay_ms(100);
}
while(duty_cyc_b < 255) //runterfahren
{
OCR2A=duty_cyc_a--;
OCR2B=duty_cyc_b++;
_delay_ms(200);
}
// erster Motor stop, Register reseten
PORTB &= ~(1<< PB2); // PB2 im PORTB löschen [1A]
TCCR2A = 0; // Timer auf 0 reseten
TCCR1A = 0; // Timer auf 0 reseten
TCNT2 = 0; // clear
TIFR2 = 0xFF; // clear interrupt-flags
//zweiter Motor start (PB4 im PORTB setzten [4A])
PORTB &= (1<< PB0); // PB0 im PORTB setzen [4A]
TCCR2B = (1<<CS21) | (1<<CS20); //Clock select
TCCR2A = (1<<COM2A1) | (1<<WGM21) | (1<<WGM20); //Waveform generation
mode
OCR2A = 0;
OCR2B = 0;
while(duty_cyc_a < 255)
{
OCR2A=duty_cyc_a++;
OCR2B=duty_cyc_b--;
_delay_ms(100);
}
while(duty_cyc_b < 255)
{
OCR2A=duty_cyc_a--;
OCR2B=duty_cyc_b++;
_delay_ms(200);
}
// zweiter Motor stop
PORTB &= ~(1<< PB0); // PB0 im PORTB löschen [4A]
return 0;
}
DF
Dieter F.
Gast
24.10.2015 15:51
#4322174
Schaust Du auch mal in Datenblätter?
Julia W schrieb:
> es wird nur PB2 [A1] angesprochen
PB2 mit Sicherheit nicht - PB3 ja, da hängt OC2A dran.
mecker schrieb:
> Die OC Pins kann
> man auf die EN Pins des L293 schalten.
mecker hat insofern Recht, als Du nur 2 OC..-Pins mit Deiner PWM
beeinflusst. Die wirken sich auf PB3 (OC2A) und PD3 (OC2B) aus.
Ob es reicht, diese beiden PWM-Pins auf die enable-Leitungen des L293D
zu geben weiß ich nicht, vermute es aber. Damit gibst Du dann die
"Drehzahl" / Geschwindigkeit vor.
Ferner musst Du dann zusätzlich noch die jeweilige Richtung über
insgesamt 4 Ausgänge (high / low) steuern.
Alternativ kannst Du natürlich 4 (von den vorhanden 6) PWM-Ausgängen für
die Richtungssteuerung incl."Drehzahl" nutzen. Das musst Du entscheiden
- musst aber in jedem Fall mal die Datenblätter studieren :-).
Deine Schaltung scheint mir aber auch noch nicht (wenn ich das
Datenblatt des L293D richtig lese) optimal zu sein. Fehlen da noch ein
paar Dioden?
Gruß
Dieter
Julia W schrieb:
> es wird nur PB2 [A1] angesprochen
JW
Julia W
Gast
24.10.2015 16:02
#4322188
#include<avr/io.h>
//#define F_CPU 20000000UL //Taktfrequenz 20MHz
#include<util/delay.h> // Verzögerung
int main(void)
{
DDRB |= (1<<PB2); //initialisieren Output 16 [Motor rechtslauf]
DDRB |= (1<<PB1); //initialisieren Output 15 [Motor linkslauf]
DDRB |= (1<<PB0); //initialisieren Output 14 [Motor rechtslauf]
DDRB |= (1<<PB3); //initialisieren Output 17 [Motor linkslauf]
DDRD |= (1<<PD5); //initialisieren Output 11 [LED]
PORTD |= (1<<PD5); //LED einschalten
PORTB &= ~(1<< PB2); //PB2 im PORTB löschen [1A], um Invertierung am
[2A] zu vermeiden
PORTB &= ~(1<< PB3); //PB3 im PORTB löschen [3A], um Invertierung am
[4A] zu vermeiden
unsigned char duty_cyc_a,duty_cyc_b;
duty_cyc_a=0; // Initial Duty Cycle for Channel A
duty_cyc_b=0; // Initial Duty Cycle for Channel B
// erster Motor start: (PB1 im PORTB setzten [2A])
TCCR2B = (1<<CS21) | (1<<CS20); //Clock select
TCCR2A = (1<<COM2A1) | (1<<WGM21) | (1<<WGM20); //Waveform generation
mode
OCR2A = 0;
OCR2B = 0;
while(duty_cyc_a < 255) //hochfahren
{
OCR2A=duty_cyc_a++;
OCR2B=duty_cyc_b--;
_delay_ms(100);
}
while(duty_cyc_b < 255) //runterfahren
{
OCR2A=duty_cyc_a--;
OCR2B=duty_cyc_b++;
_delay_ms(200);
}
// erster Motor stop, Register reseten
PORTB &= ~(1<< PB1); // PB1 im PORTB löschen [2A]
TCCR2A = 0; // Timer auf 0 reseten
TCCR1A = 0; // Timer auf 0 reseten
TCNT2 = 0; // clear
TIFR2 = 0xFF; // clear interrupt-flags
//zweiter Motor start (PB4 im PORTB setzten [4A])
TCCR2B = (1<<CS21) | (1<<CS20); //Clock select
TCCR2A = (1<<COM2A1) | (1<<WGM21) | (1<<WGM20); //Waveform generation
mode
OCR4A = 0;
OCR4B = 0;
while(duty_cyc_a < 255)
{
OCR2A=duty_cyc_a++;
OCR2B=duty_cyc_b--;
_delay_ms(100);
}
while(duty_cyc_b < 255)
{
OCR2A=duty_cyc_a--;
OCR2B=duty_cyc_b++;
_delay_ms(200);
}
// zweiter Motor stop
PORTB &= ~(1<< PB0); // PB0 im PORTB löschen [4A]
return 0;
}
JW
Julia W
Gast
24.10.2015 16:06
#4322190
danke Euch.
Ich denke, ich habe es nun mit den OCR2 bzw OCR4 verstanden. 1 #include <avr/io.h>
2 //#define F_CPU 20000000UL //Taktfrequenz 20MHz
3 #include <util/delay.h> // Verzögerung
4
5 int main ( void )
6 {
7 DDRB |= ( 1 << PB2 ); //initialisieren Output 16 [Motor rechtslauf]
8 DDRB |= ( 1 << PB1 ); //initialisieren Output 15 [Motor linkslauf]
9 DDRB |= ( 1 << PB0 ); //initialisieren Output 14 [Motor rechtslauf]
10 DDRB |= ( 1 << PB3 ); //initialisieren Output 17 [Motor linkslauf]
11 DDRD |= ( 1 << PD5 ); //initialisieren Output 11 [LED]
12
13 PORTD |= ( 1 << PD5 ); //LED einschalten
14 PORTB &= ~ ( 1 << PB2 ); //PB2 im PORTB löschen [1A], um Invertierung am
15 [ 2 A ] zu vermeiden
16 PORTB &= ~ ( 1 << PB3 ); //PB3 im PORTB löschen [3A], um Invertierung am
17 [ 4 A ] zu vermeiden
18 unsigned char duty_cyc_a , duty_cyc_b ;
19 duty_cyc_a = 0 ; // Initial Duty Cycle for Channel A
20 duty_cyc_b = 0 ; // Initial Duty Cycle for Channel B
21
22
23 // erster Motor start: (PB1 im PORTB setzten [2A])
24
25 TCCR2B = ( 1 << CS21 ) | ( 1 << CS20 ); //Clock select
26 TCCR2A = ( 1 << COM2A1 ) | ( 1 << WGM21 ) | ( 1 << WGM20 ); //Waveform generation
27 mode
28 OCR2A = 0 ;
29 OCR2B = 0 ;
30 while ( duty_cyc_a < 255 ) //hochfahren
31 {
32 OCR2A = duty_cyc_a ++ ;
33 OCR2B = duty_cyc_b -- ;
34 _delay_ms ( 100 );
35 }
36
37 while ( duty_cyc_b < 255 ) //runterfahren
38 {
39 OCR2A = duty_cyc_a -- ;
40 OCR2B = duty_cyc_b ++ ;
41 _delay_ms ( 200 );
42 }
43 // erster Motor stop, Register reseten
44 PORTB &= ~ ( 1 << PB1 ); // PB1 im PORTB löschen [2A]
45 TCCR2A = 0 ; // Timer auf 0 reseten
46 TCCR1A = 0 ; // Timer auf 0 reseten
47 TCNT2 = 0 ; // clear
48 TIFR2 = 0xFF ; // clear interrupt-flags
49 //zweiter Motor start (PB4 im PORTB setzten [4A])
50
51 TCCR2B = ( 1 << CS21 ) | ( 1 << CS20 ); //Clock select
52 TCCR2A = ( 1 << COM2A1 ) | ( 1 << WGM21 ) | ( 1 << WGM20 ); //Waveform generation
53 mode
54 OCR4A = 0 ;
55 OCR4B = 0 ;
56 while ( duty_cyc_a < 255 )
57 {
58 OCR2A = duty_cyc_a ++ ;
59 OCR2B = duty_cyc_b -- ;
60 _delay_ms ( 100 );
61 }
62
63 while ( duty_cyc_b < 255 )
64 {
65 OCR4A = duty_cyc_a -- ;
66 OCR4B = duty_cyc_b ++ ;
67 _delay_ms ( 200 );
68 }
69 // zweiter Motor stop
70 PORTB &= ~ ( 1 << PB0 ); // PB0 im PORTB löschen [4A]
71
72 return 0 ;
73 }
Julia W schrieb:
> Ich denke, ich habe es nun mit den OCR2 bzw OCR4 verstanden.
Du hast überhaupt nichts verstanden. Ein Atmega168 hat keinen Timer4 und
somit auch keine OCR4-Register. Wenn du deinen Motor an OC1A und OC1B
angeschlossen hast, dann nimm auch Timer1.
Deine ganze Initialisierung ist wirres Zeug.
mfg.
DF
Dieter F.
Gast
24.10.2015 16:34
#4322213
Du kannst diese (Bild) Pins mit PWM beeinflussen - keine anderen. Die
Zahl steht jeweils für den beeinflussenden Timer ...
Sch..ade, jetzt ist es ein GIF geworden ...
Und ... ja, es führt kein Weg an den Datenblättern vorbei - weiß ich aus
eigener Erfahrung. Und dann lieber x-mal Lesen, da man beim ersten,
zweiten, ...ten Mal immer noch etwas überliest.
Ich habe die Hinweise auch nicht gerade als lustig empfunden, es hilft
aber ungemein. Googlen ist die 2. Wahl, da auch nicht immer korrekte
Aussagen getroffen werden :-(
JW
Julia W
Gast
24.10.2015 17:29
#4322281
Abend,
@ Dieter: Also ich kann PB1, PB2, PB3 für PWM benutzen, richtig? PB0
aber nicht, weil hierfür kein Timer zu Verfügung steht.
Was ich noch immer nicht verstehe, warum kann ich nicht mit Timer2 die
Ausgänge PB1, PB2, PB3 steuern?
Anbei der fehlerfrei compilierte c-Code
1 #include <avr/io.h>
2 //#define F_CPU 20000000UL //Taktfrequenz 20MHz
3 #include <util/delay.h> // Verzögerung
4
5 int main ( void )
6 {
7 DDRB |= ( 1 << PB2 ); //initialisieren Output 16 [Motor rechtslauf]
8 DDRB |= ( 1 << PB1 ); //initialisieren Output 15 [Motor linkslauf]
9 DDRB |= ( 1 << PB0 ); //initialisieren Output 14 [Motor rechtslauf]
10 DDRB |= ( 1 << PB3 ); //initialisieren Output 17 [Motor linkslauf]
11 DDRD |= ( 1 << PD5 ); //initialisieren Output 11 [LED]
12
13 PORTD |= ( 1 << PD5 ); //LED einschalten
14 PORTB &= ~ ( 1 << PB2 ); //PB2 im PORTB löschen [1A], um Invertierung am [2A] zu vermeiden
15 PORTB &= ~ ( 1 << PB0 ); //PB0 im PORTB löschen [4A], um Invertierung am [3A] zu vermeiden
16 unsigned char duty_cyc_a , duty_cyc_b ;
17 duty_cyc_a = 0 ; // Initial Duty Cycle for Channel A
18 duty_cyc_b = 0 ; // Initial Duty Cycle for Channel B
19
20
21 // erster Motor start: (PB1 im PORTB setzten [2A])
22
23 TCCR2B = ( 1 << CS21 ) | ( 1 << CS20 ); //Clock select
24 TCCR2A = ( 1 << COM2A1 ) | ( 1 << WGM21 ) | ( 1 << WGM20 ); //Waveform generation mode
25 OCR2A = 0 ;
26 OCR2B = 0 ;
27 while ( duty_cyc_a < 255 ) //hochfahren
28 {
29 OCR2A = duty_cyc_a ++ ;
30 OCR2B = duty_cyc_b -- ;
31 _delay_ms ( 100 );
32 }
33
34 while ( duty_cyc_b < 255 ) //runterfahren
35 {
36 OCR2A = duty_cyc_a -- ;
37 OCR2B = duty_cyc_b ++ ;
38 _delay_ms ( 200 );
39 }
40 // erster Motor stop, Timer reseten
41 PORTB &= ~ ( 1 << PB1 ); // PB1 im PORTB löschen [2A]
42 TCCR2A = 0 ; // Timer auf 0 reseten
43 TCCR2B = 0 ; // Timer auf 0 reseten
44 TCNT2 = 0 ; // clear
45 TIFR2 = 0xFF ; // clear interrupt-flags
46 //zweiter Motor start (PB3 im PORTB setzten [3A])
47
48 TCCR2B = ( 1 << CS21 ) | ( 1 << CS20 ); //Clock select
49 TCCR2A = ( 1 << COM2A1 ) | ( 1 << WGM21 ) | ( 1 << WGM20 ); //Waveform generation mode
50 OCR2A = 0 ;
51 OCR2B = 0 ;
52 while ( duty_cyc_a < 255 )
53 {
54 OCR3A = duty_cyc_a ++ ;
55 OCR3B = duty_cyc_b -- ;
56 _delay_ms ( 100 );
57 }
58
59 while ( duty_cyc_b < 255 )
60 {
61 OCR3A = duty_cyc_a -- ;
62 OCR3B = duty_cyc_b ++ ;
63 _delay_ms ( 200 );
64 }
65 // zweiter Motor stop
66 PORTB &= ~ ( 1 << PB3 ); // PB3 im PORTB löschen [3A]
67
68 return 0 ;
69 }
M
mecker
Gast
24.10.2015 17:48
#4322302
Julia W schrieb:
> Was ich noch immer nicht verstehe, warum kann ich nicht mit Timer2 die
> Ausgänge PB1, PB2, PB3 steuern?
Schau dir im Datenblatt das Kapitel "18.11.1 TCCR2A – Timer/counter
control register A" und dort speziell die COM Bits auf Bitposition 7, 6,
5, 4 an.
Die Tabellen darunter zeigen dir, daß man nur die OC2A und OC2B Pins für
die HW-PWM beim Timer2 nutzen kann. Entsprechenden Kapitel gibt es auch
für Timer1 und Timer0.
DF
Dieter F.
Gast
24.10.2015 19:44
#4322425
Julia W schrieb:
> @ Dieter: Also ich kann PB1, PB2, PB3 für PWM benutzen, richtig?
Ja, wenn Du Timer 1 UND Timer 2 einsetzt. Dann kannst Du auch PD3 nutzen
(mit Timer 2). Für PD5 und PD6 müsstetst Du zusätzlich Timer 0
aktivieren.
Hast Du Dir das Bild angeschaut und den Zusammenhang verstanden?
DF
Dieter F.
Gast
24.10.2015 19:49
#4322430
Julia W schrieb:
> OCR3A=duty_cyc_a++;
> OCR3B=duty_cyc_b--;
Es gibt keinen Timer 3 (und auch keinen Timer 4) bei ATMega 168. Es gibt
nur Timer 0, 1 , 2. Auch da gibt es wieder den Zusammenhang mit der
Timer-Nr. OCRxA, OCRxB (x = Timer-Nr.).
Hast Du Dir eigentlich das Bild (aus dem Datenblatt) angeschaut und
verstanden?
-> Datenblatt
JW
Julia W
Gast
24.10.2015 20:50
#4322488
Ich habe mich nach dem Datenblatt gerichtet, und die einzelnen Bits
äquivalent zu Timer2 gesetzt, weil hier ja wenigstens ein Motor lief.
Jetzt laufen hoffentlich beide ;) 1 #include <avr/io.h>
2 //#define F_CPU 20000000UL //Taktfrequenz 20MHz
3 #include <util/delay.h> // Verzögerung
4
5 int main ( void )
6 {
7 DDRB |= ( 1 << PB2 ); //initialisieren Output 16 [Motor rechtslauf]
8 DDRB |= ( 1 << PB1 ); //initialisieren Output 15 [Motor linkslauf]
9 DDRB |= ( 1 << PB0 ); //initialisieren Output 14 [Motor rechtslauf]
10 DDRB |= ( 1 << PB3 ); //initialisieren Output 17 [Motor linkslauf]
11 DDRD |= ( 1 << PD5 ); //initialisieren Output 11 [LED]
12 PORTD |= ( 1 << PD5 ); //LED einschalten
13 PORTB &= ~ ( 1 << PB2 );
14 PORTB &= ~ ( 1 << PB0 );
15 PORTB &= ~ ( 1 << PB1 );
16 PORTB &= ~ ( 1 << PB3 );
17 unsigned char duty_cyc_a , duty_cyc_b ;
18 duty_cyc_a = 0 ; // Initial Duty Cycle for Channel A
19 duty_cyc_b = 0 ; // Initial Duty Cycle for Channel B
20
21
22 // erster Motor start:
23
24 TCCR2B = ( 1 << CS21 ) | ( 1 << CS20 ); //Clock select
25 TCCR2A = ( 1 << COM2A1 ) | ( 1 << WGM21 ) | ( 1 << WGM20 ); //Waveform generation mode
26 OCR2A = 0 ;
27 OCR2B = 0 ;
28 while ( duty_cyc_a < 255 ) //hochfahren
29 {
30 OCR2A = duty_cyc_a ++ ;
31 OCR2B = duty_cyc_b -- ;
32 _delay_ms ( 100 );
33 }
34
35 while ( duty_cyc_b < 255 ) //runterfahren
36 {
37 OCR2A = duty_cyc_a -- ;
38 OCR2B = duty_cyc_b ++ ;
39 _delay_ms ( 200 );
40 }
41 // erster Motor stop, Timer reseten
42
43 TCCR2A = 0 ; // Timer auf 0 reseten
44 TCCR2B = 0 ; // Timer auf 0 reseten
45 TCNT2 = 0 ; // clear
46 TIFR2 = 0xFF ; // clear interrupt-flags
47 //zweiter Motor start
48
49 TCCR1B = ( 1 << CS11 ) | ( 1 << CS10 ); //Clock select
50 TCCR1A = ( 1 << COM1A1 ) | ( 1 << WGM11 ) | ( 1 << WGM10 ); //Waveform generation mode
51 OCR1A = 0 ;
52 OCR1B = 0 ;
53 while ( duty_cyc_a < 255 )
54 {
55 OCR1A = duty_cyc_a ++ ;
56 OCR1B = duty_cyc_b -- ;
57 _delay_ms ( 100 );
58 }
59
60 while ( duty_cyc_b < 255 )
61 {
62 OCR1A = duty_cyc_a -- ;
63 OCR1B = duty_cyc_b ++ ;
64 _delay_ms ( 200 );
65 }
66 // zweiter Motor stop, Timer reseten
67
68 TCCR1A = 0 ; // Timer auf 0 reseten
69 TCCR1B = 0 ; // Timer auf 0 reseten
70 TCNT1 = 0 ; // clear
71 TIFR1 = 0xFF ; // clear interrupt-flags
72 return 0 ;
73 }
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.
Noch kein Account?
Die Registrierung ist kostenlos und dauert nur eine Minute.
Jetzt registrieren