Hallo,

ich bin noch ein ziemlicher Neuling wenn es ums uC programmieren geht. Ich weiß auch das hier ältliche Themen über PWM stehen, wie es funktioniert. Naja wie es funktioniert weiß ich in der Regel schon.
Meine Servos kann ich auch ansteuern, aber halt nicht präzise.

Habe ein Atmega644 (6PWM Ausgänge (2x10Bit/4x8Bit)) der mit einen 16 Mhz Quarzoszillator getaktet ist.

Hier versuche ich mal mein Problem zu beschreiben
Habe wie im unteren Bild, oberes Signal, folgende Impulse. Wenn ich für OCR0A den Wert 8 eingebe (Den Wert OCR0A = 8 kann mit Hilfe eines C# Programmes, welches ich geschrieben habe ändern)
habe ich ein Impuls von 0,6ms und der Servo steht ganz links. Wenn ich dagegen den Wert 39 eingebe steht der Servo ganz rechts. Somit habe ich 31 Schritte um den Servo von links nach rechts zu fahren. Dieses ist mir aber zu grob...

Klicke auf die Grafik für eine größere Ansicht

Name:	pwm4.jpg
Hits:	17
Größe:	21,4 KB
ID:	20373

Darum meine Frage: Kann man die Impulse Zählen so das nur jeder 4te Impuls ausgegeben wird? Habe hierzu nochmal ein Bild gezeichnet.
Hier habe ich eine Periode von 4ms. Wenn ich jetzt nur jeden 4ten Impuls durchlasse so kann ich die Servos mit 122 Schritten genauer steuern.

Klicke auf die Grafik für eine größere Ansicht

Name:	pwm3.jpg
Hits:	9
Größe:	28,5 KB
ID:	20374

Ist das möglich? Wenn ja wie realisier ich das?

ich gebe euch mal mein Programm mit rein vielleicht könnt ihr da ein wenig dran rumbasteln und das für ein PWM Signal fertig machen. Ober ein Linkverweis, wo genau das beschrieben ist wäre auch nicht schlecht.

Code:

//-------------------------------------------------------------------------------------------//
//-------------------------------------------------------------------------------------------//
//                                                                                           //
//             Miniprojekt Roboterarm V.1.0                                                  //
//                                      von Thomas B. & André K.                             //
//                                                                                           //
//-------------------------------------------------------------------------------------------//
//-------------------------------------------------------------------------------------------//

//-------------------------------------------------------------------------------------------
// Include Datein
//-------------------------------------------------------------------------------------------    
    
#include <avr/io.h>
#include <inttypes.h>
#include "lcd-routines.h" //LCD-Display
#include <util/delay.h>  

#define BAUD        9600UL           // Baud einstellen 9600
#define UBRR_BAUD   ((F_CPU/(16UL*BAUD))-1)

//-------------------------------------------------------------------------------------------
// Methoden
//-------------------------------------------------------------------------------------------    

// USART initialisieren

uart_init(void)
{
    // Baudrate einstellen (Normaler Modus)
    UBRR0H = (uint8_t) (UBRR_BAUD>>8);
    UBRR0L = (uint8_t) (UBRR_BAUD & 0x0ff);

    // Aktivieren von receiver und transmitter
    UCSR0B = (1<<RXEN0)|(1<<TXEN0);

    // Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit
    UCSR0C = (1<<UCSZ01)|(3<<UCSZ00);
}

//-------------------------------------------------------------------------------------------
// Hauptschleife
//-------------------------------------------------------------------------------------------    

main(void)
{
    
//-------------------------------------------------------------------------------------------
// Initialisierung 
//-------------------------------------------------------------------------------------------    
    
    uart_init();
    lcd_init();
    
// Variablen
    uint8_t buffer=150;

//PWM 1 & PWM 2
    DDRD = (1 << PD4 )|(1 << PD5 );
    
    TCCR1A = (1<<WGM11) | (1<<COM1A1)|(1<<COM1B1);
    TCCR1B = (1<<CS12)|(1<<WGM13)|(1<<WGM12);
    ICR1 = 800;         //Zählt bis zu diesen Wert
    OCR1A = 120;        //Bei diesen Wert wird eine 0 gesetzt
    OCR1B = 200;        //Bei diesen Wert wird eine 0 gesetzt
    
//PWM 3 & PWM 4
    DDRB = (1 << PB3 )|(1 << PB4 );
    TCCR0A = (1<<WGM01) |(1<<WGM00) | (1<<COM0A1) |(1<<COM0B1);
    TCCR0B = (1<<CS00) |(1<<CS02);
    OCR0A = 120;
     OCR0B = 120;
    
//PWM 5 & PWM 6
    DDRD |= (1 << PD6 )|(1 << PD7 );
    TCCR2A = (1<<WGM21) |(1<<WGM20) | (1<<COM2A1) |(1<<COM2B1);
    TCCR2B = (1<<CS20) |(1<<CS21) |(1<<CS22)|(0<<WGM22);      // Datenblatt S.149
    OCR2A = 120;
     OCR2B = 120;

//-------------------------------------------------------------------------------------------
// Display
//-------------------------------------------------------------------------------------------            
            
        //Zeile 1
        lcd_setcursor( 0, 1) ;
        lcd_string("Zeile 1");
        //Zeile 2
        lcd_setcursor( 0, 2 );
        lcd_string("Zeile 2");
        //Zeile 3
        lcd_setcursor( 20, 1 );
        lcd_string("Zeile 3");
        //Zeile 4
        lcd_setcursor( 20, 2 );
        lcd_string("Zeile 4");
//-------------------------------------------------------------------------------------------
// Schleife
//-------------------------------------------------------------------------------------------        

    while (1) 
    {
    
        // Warten bis Daten empfangen wurden
        
        if ( (UCSR0A & (1<<RXC0)) )
        {
         buffer = UDR0;
        }
        else
        {
        
        }
    OCR2B=buffer;
    }
  return 0; // never reached 
}
Hoffe auf schnelle Antwort. Muss in den Ferien noch viel schaffen.

Gruß André