mikrocontroller.net

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


Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
#include <stdio.h>
#include <string.h>  
#include <avr/io.h>  
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdlib.h>
#include <ctype.h>

// Standard Input/Output functions
#include <stdio.h>

#define ADC_VREF_TYPE 0x00
// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input|ADC_VREF_TYPE;
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}

// Declare your global variables here

void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In Func7=In
// State0=T State1=T State2=T State3=T State4=T State5=T State6=T State7=T
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In Func7=In
// State0=T State1=T State2=T State3=T State4=T State5=T State6=T State7=T
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In Func7=In
// State0=T State1=T State2=T State3=T State4=T State5=T State6=T State7=T
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func0=In Func1=In Func2=In Func3=In Func4=Out Func5=Out Func6=In Func7=In
// State0=T State1=T State2=T State3=T State4=0 State5=0 State6=T State7=T
PORTD=0x00;
DDRD=0x30;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 2000,000 kHz
// Mode: CTC top=ICR1
// OC1A output: Clear
// OC1B output: Clear
// Noise Canceler: Off
// Input Capture on Falling Edge
TCCR1A=0xA0;
TCCR1B=0x1A;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1=0x9c40;
OCR1A=30000;
OCR1B=1500;


// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
GICR|=0x00;
MCUCR=0x00;
MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud rate: 9600
UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x67;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
// Analog Comparator Output: Off
ACSR=0x80;
SFIOR=0x00;

// ADC initialization
// ADC Clock frequency: 125,000 kHz
// ADC Voltage Reference: AREF pin
// ADC High Speed Mode: Off
// ADC Auto Trigger Source: None
ADMUX=ADC_VREF_TYPE;
ADCSRA=0x87;
SFIOR&=0xEF;

while (1)
      {
      // Place your code here

      };
}

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

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Peter Bünger (pbuenger)
Datum:

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

Gruß,
Peter

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...)

Autor: Peter Bünger (pbuenger)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.