2 Modellbauservos an AVR mit CTC top=ICR1

Gast #1184705
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?
Gast #1185083
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...)
#1185123
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.
Gast #1185134
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.
Gast #1185142
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren