Forum: Mikrocontroller und Digitale Elektronik 2 Modellbauservos an AVR mit CTC top=ICR1


von Gast (Gast)


Lesenswert?

Hallo,

bin wieder mit einem typischen Anfängerfehler unterwegst glaub ich.

Und zwar möchte ich 2 Modellbauservos an eiem Mega16 betreiben.

Zum erzeugen der PWM verwende ich den CTC top=ICR1 mode des Timer 1.

In die beiden compare Register schreibe ich mein gewünschtes 
Taktverhältniss. Bei einem Match werden die Ports "gecleart".

leider funktioniert der code nicht. Die Servos bewegen sich nicht. Ich 
könnt natrürlich das auch mit timeroverflow machen, aber ich denk so 
ists sauberer wenns funktioniert.
1
#include <stdio.h>
2
#include <string.h>  
3
#include <avr/io.h>  
4
#include <avr/interrupt.h>
5
#include <util/delay.h>
6
#include <stdlib.h>
7
#include <ctype.h>
8
9
// Standard Input/Output functions
10
#include <stdio.h>
11
12
#define ADC_VREF_TYPE 0x00
13
// Read the AD conversion result
14
unsigned int read_adc(unsigned char adc_input)
15
{
16
ADMUX=adc_input|ADC_VREF_TYPE;
17
// Start the AD conversion
18
ADCSRA|=0x40;
19
// Wait for the AD conversion to complete
20
while ((ADCSRA & 0x10)==0);
21
ADCSRA|=0x10;
22
return ADCW;
23
}
24
25
// Declare your global variables here
26
27
void main(void)
28
{
29
// Declare your local variables here
30
31
// Input/Output Ports initialization
32
// Port A initialization
33
// Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In Func7=In
34
// State0=T State1=T State2=T State3=T State4=T State5=T State6=T State7=T
35
PORTA=0x00;
36
DDRA=0x00;
37
38
// Port B initialization
39
// Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In Func7=In
40
// State0=T State1=T State2=T State3=T State4=T State5=T State6=T State7=T
41
PORTB=0x00;
42
DDRB=0x00;
43
44
// Port C initialization
45
// Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In Func7=In
46
// State0=T State1=T State2=T State3=T State4=T State5=T State6=T State7=T
47
PORTC=0x00;
48
DDRC=0x00;
49
50
// Port D initialization
51
// Func0=In Func1=In Func2=In Func3=In Func4=Out Func5=Out Func6=In Func7=In
52
// State0=T State1=T State2=T State3=T State4=0 State5=0 State6=T State7=T
53
PORTD=0x00;
54
DDRD=0x30;
55
56
// Timer/Counter 0 initialization
57
// Clock source: System Clock
58
// Clock value: Timer 0 Stopped
59
// Mode: Normal top=FFh
60
// OC0 output: Disconnected
61
TCCR0=0x00;
62
TCNT0=0x00;
63
OCR0=0x00;
64
65
// Timer/Counter 1 initialization
66
// Clock source: System Clock
67
// Clock value: 2000,000 kHz
68
// Mode: CTC top=ICR1
69
// OC1A output: Clear
70
// OC1B output: Clear
71
// Noise Canceler: Off
72
// Input Capture on Falling Edge
73
TCCR1A=0xA0;
74
TCCR1B=0x1A;
75
TCNT1H=0x00;
76
TCNT1L=0x00;
77
ICR1=0x9c40;
78
OCR1A=30000;
79
OCR1B=1500;
80
81
82
// Timer/Counter 2 initialization
83
// Clock source: System Clock
84
// Clock value: Timer 2 Stopped
85
// Mode: Normal top=FFh
86
// OC2 output: Disconnected
87
ASSR=0x00;
88
TCCR2=0x00;
89
TCNT2=0x00;
90
OCR2=0x00;
91
92
// External Interrupt(s) initialization
93
// INT0: Off
94
// INT1: Off
95
// INT2: Off
96
GICR|=0x00;
97
MCUCR=0x00;
98
MCUCSR=0x00;
99
100
// Timer(s)/Counter(s) Interrupt(s) initialization
101
TIMSK=0x00;
102
103
// USART initialization
104
// Communication Parameters: 8 Data, 1 Stop, No Parity
105
// USART Receiver: On
106
// USART Transmitter: On
107
// USART Mode: Asynchronous
108
// USART Baud rate: 9600
109
UCSRA=0x00;
110
UCSRB=0x18;
111
UCSRC=0x86;
112
UBRRH=0x00;
113
UBRRL=0x67;
114
115
// Analog Comparator initialization
116
// Analog Comparator: Off
117
// Analog Comparator Input Capture by Timer/Counter 1: Off
118
// Analog Comparator Output: Off
119
ACSR=0x80;
120
SFIOR=0x00;
121
122
// ADC initialization
123
// ADC Clock frequency: 125,000 kHz
124
// ADC Voltage Reference: AREF pin
125
// ADC High Speed Mode: Off
126
// ADC Auto Trigger Source: None
127
ADMUX=ADC_VREF_TYPE;
128
ADCSRA=0x87;
129
SFIOR&=0xEF;
130
131
while (1)
132
      {
133
      // Place your code here
134
135
      };
136
}

Ist meine Denkweise falsch oder hab ich nur einen kleinen Fehler im 
Programm?

von Gast (Gast)


Lesenswert?

Ach ja hab ich oben vergesen:

OCR1A=30000;
OCR1B=1500;

ergibt natürlich keinen Sinn war nur zur testzwecken.

1ms = 2000 timer-schritte

also sind wärte zwischen 2000 und  4000 sinnvoll!

MFG

von Peter B. (pbuenger)


Lesenswert?

Der CTC-Mode macht aber keine PWM. Nimm' Mode 14 "Fast PWM" und schon 
geht's.

Gruß,
Peter

von STK500-Besitzer (Gast)


Lesenswert?

>Der CTC-Mode macht aber keine PWM.
Diese Aussage ist schon mal falsch. (ich habes es nämlich schon damit 
gemacht...)

>leider funktioniert der code nicht
Kannst du den bitte mal aufräumen, indem du alles rausschmeisst, was zu 
viel ist (also sämtliche durch deinen Wizard erzeugte Kommentare und 
Einstellungen , die nichst machen, was nicht scshon durch den 
Reset-Zustand erledigt ist)?!

Ich habe hier auch irgendwo ein Programm gepostet, das auch zwei Servos 
auf diese Art ansteuert. Leider finde ich es nicht. (Ich könnt es auch 
auf meinem Rechner suchen, was ähnlich lange dauern dürfte...)

von Peter B. (pbuenger)


Lesenswert?

>>Der CTC-Mode macht aber keine PWM.
> Diese Aussage ist schon mal falsch. (ich habes es nämlich schon damit
> gemacht...)
Nö, diese Aussage ist durchaus richtig. Im CTC-Mode toggelt der Ausgang 
auf jeden Compare-Match. Man kann damit durch ständiges Neuladen des 
Compare-Registers auch eine PWM nachbilden, aber warum sollte man dies 
tun, wenn es dazu die Fast-PWM-Modi gibt.

von STK500-Besitzer (Gast)


Lesenswert?

>Nö, diese Aussage ist durchaus richtig.
Nö, immer noch nicht.

>Im CTC-Mode toggelt der Ausgang auf jeden Compare-Match.

Ja, wenn man das COM-Register entsprechend programmiert.
Das Verhalten der OC-Ausgänge wird über dieses Register gesteuert.
Und da ist der Timer-Mode relativ egal.

CTC kann man wunderbar zum Erzeugen einer Zeitbasis benutzen.

Man kann auch einen andere Timer-Mode benutzen. DAS ändert aber nichts 
an der Tatsache, dass das Programm oben total unübersichtlich ist.

von Stefan E. (sternst)


Lesenswert?

Bevor ihr euch die Köpfe einschlagt:

CTC-Mode:
Man muss den Ausgang selber per Software beim Compare-Match und dem 
Overflow setzen/löschen
=> Software-PWM

PWM-Mode:
Die Hardware übernimmt das Setzen/Löschen des Ausgangs
=> Hardware-PWM

von STK500-Besitzer (Gast)


Lesenswert?

>Man muss den Ausgang selber per Software beim Compare-Match und dem
>Overflow setzen/löschen
>=> Software-PWM

Stimmt. So langsam fällt es mir wieder ein.
@Peter: Tut mir leid, dass ich dir nicht geglaubt habe.
Das Programm ist schon etwas her.

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
Noch kein Account? Hier anmelden.