Ich verwende einen atmega328p und möchte das PWM-Tastverhältnis mit einem Potentiometer steuern.
Die Frequenz beträgt 20 ms und das Tastverhältnis liegt zwischen 0 ms und 2 ms. Problem: Wenn ich das in Proteus simuliere, hat die PWM nicht funktioniert, das ist mein Code:
#ifndef F_CPU
#define F_CPU 16000000UL // 16 MHz clock speed
#endif
#include <avr/io.h>
#include <avr/interrupt.h>
int main(void)
{
DDRB |= 1<< PINB1 ;
TCCR1A |= 1<< COM1A0 | 1<< COM1A1 | 1<<WGM11 ;
TCCR1B |= 1<< WGM12 | 1<<WGM13 | 1<<CS10 | 1<<CS11 ;
ICR1 = 4999 ; // 50 Hz
ADCSRA |= 1<<ADEN | 1<< ADIE | 1<<ADPS2 | 1<<ADPS1 ; // 64 prescaler
ADMUX |= REFS0 ;
sei();
ADCSRA |= 1<<ADSC ;
while (1)
{
}
}
ISR(ADC_vect)
{
uint8_t low = ADCL ;
uint16_t tenvar = ADCH << 8 | low ; // value from potentiometer 10 bit
OCR1A = 4999 - ((499/1024)*tenvar ); // OCR1A is between 4999 and 4500 (4500 represent 2ms )
ADCSRA |= 1<< ADSC ;
}
((499/1024)*tenvar )
Hoppla.
(tenvar * 499L / 1024)
Es sei denn, es ist Ihnen wirklich egal, dass das Ergebnis immer 0 ist.
L
macht es zu einer langen (32-Bit, um einen Überlauf zu verhindern) Konstante und (499/1024)
ist 0. Weil ganze Zahlen.Ich habe das Problem gefunden: Ich habe vergessen zu setzen
1<<REFS0
im ADMUX-Register
und der Einfachheit halber hätte ich verwenden können
OCR1A = 4999 - (ADC * 499L / 1024 ) ;
anstatt
uint8_t low = ADCL ;
uint16_t tenvar = ADCH << 8 | low ;
OCR1A = 4999 - (tenvar * 499L / 1024);
Chris Stratton