Hallo liebes Forum,

Ich habe ein Verständnisproblem bezüglich der Timer (8 u. 16 bit).
Ich habe versucht ein PWM-Signal zu generieren, jedoch zeigt das oszi keins an.

Was ich erwartet habe: alle 20ms wird eine entsprechende Pulsbreite von den Timern erzeugt. 0,6ms bis 2,6ms sollte die range der Breite sein.
Die pulsbreite wird über LDRs realisiert, die einen Spannungsteiler bilden. So liegen am ADC1 werte von 0V bis 5V an. Wenn beide LDRs gleich stark beleuchtet sind, liegen ca. 2,5V am ADC1 an. Der Teil des Speicherns in eine Variable funktioniert soweit (0...1024 -> 2,5V = 512).

Ich habe es versucht mit einem Timer1 (16-Bit) zu realisieren aber ich bekomme es einfach nicht hin.
Ich benutze einen Atmega1284p-pu der mit dem internen Clock von 8Mhz arbeitet.

Hier mein Code:

Code:
#define F_CPU 8000000UL
#include <avr/io.h>
#include <stdint.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include "ADC.h"

ISR	(TIMER1_COMPA_vect)		 //Interrupt sub routine 
{
	OCR1A = 10000 - OCR1A;	 // hier werden die 20ms erzeugt die der servo benötigt
}

int main(void)
{	
        DDRD = (1<<PIND5);                  //Der Ausgang

	ADC_Init();					//ADC initialisieren

        double	adcwert_1_LDRs;        //speicherort für den ADCwert

        TCCR1A = (1<<COM1A1) | (1<<COM1B1);		//CTC Modus (Clear OC1A on compare match), set OC1A at bottom non-inverting
	TCCR1B = (1<<WGM13) | (1<<CS11);	               //(1<<WGM12) vllt raus, (ICRn aktivieren), OCR1A auf direkt, TOV1 Flag auf MAX, prescaler=8
        OCR1A = 799;		                                      //(8Mhz/(2*8*(1+799)))=625Hz=1,6ms Mittelstellung, (8Mhz/(2*8*(1+750)))=665,7Hz=1,5ms Mittelstellung,
	TIMSK1 = (1<<OCIE1A);//(1<<TOIE1); 		      //Timer-compare-Interrupt an 

 	_delay_ms(2000);

        while(1)
        {
		adcwert_1_LDRs = ADC_Read(1);
		if (adcwert_1_LDRs <= 490 && OCR1A > 301)	          //servo dreht links bis max. 0,6ms
		{					//(8MHz/(2*8*(1+9699)))=51,54Hz;20ms-0,6ms=19,4ms->1/19,4ms=51,54Hz->(8MHz/(2*8*51,54Hz))-1=9699->10000-9699=301!
							 //(8MHz/(2*8*(1+301)))=1655,6Hz=0,6ms
 			cli();			        //interrupts global deaktivieren 
			OCR1A -= 5;		//OCR1A so lange um 5 verringern, bis panel direkt zur sonne gerichtet ist				
			sei();			        //interrupts globl aktiviren
			_delay_ms(50);	        //50ms warten
		}
		
		if (adcwert_1_LDRs >= 530 && OCR1A < 1301)	//servo dreht rechts
		{
			cli();
			OCR1A += 5;		//1301;
			sei();
			_delay_ms(50);
		}
        }
}
Ich hoffe Ihr könnt mir helfen.

Mit freundlichen Grüßen

Technik_Amateur