Suponiendo que su microcontrolador tiene un módulo PWM, entonces es bastante simple. Debe leer la hoja de datos y configurar su módulo en consecuencia, y luego cargar los valores apropiados en el registro del ciclo de trabajo (generalmente "comparar"). Aquí hay un ejemplo aproximado:
Usted configura un temporizador para su frecuencia PWM (fija) deseada, y luego modifica un registro para cambiar el tiempo de encendido / apagado en este período.
Digamos que tienes un módulo PWM de 10 bits. 10 bits = 2 ^ 10 = 1024. Por lo tanto, para un ciclo de trabajo del 50%, debe cargar 512 en el registro, para 25% 256 y así sucesivamente (la operación específica de su módulo PWM puede ser un poco diferente)
Luego agrega un filtro de paso bajo (el filtro RC simple por lo general será suficiente) delante del PWM para promediar el PWM y produce una tensión de CC variable:
Para el filtro, debe asegurarse de que la frecuencia PWM se atenúe en gran medida, dejando las frecuencias más bajas, ya que dice que todo lo que necesita es DC, entonces algo como R = 10k C = 0.1uF será suficiente. Esto creará un corte de 1 / (2pi * 10k * 0.1uF) = 159Hz. Elija una frecuencia PWM muy por encima de esta (por ejemplo, 10 kHz)
Noté la etiqueta AVR: no uso AVR (por lo que no puedo responder personalmente por la siguiente información) pero busqué en Google y encontré un par de tutoriales bastante buenos:
Aquaticus PWM guide
AVR Freaks PWM guide
PWM sine wave example
En caso de que no quiera usar el módulo PWM (o necesite PWM en un pin específico), aquí hay un código PWM "suave":
// The following two ISRs are doing "poor man's PWM"
// but this allows it to be on a pin of my choice
ISR(TIMER0_COMP_vect) {
// clear the output pin on OCR0 match
PORTC &= ~(1<<PC0);
}
ISR(TIMER0_OVF_vect) {
// set the output pin at timer overflow
PORTC |= (1<<PC0);
}
int main(void) {
// going to use PORTC.0 to PWM the contrast voltage
DDRC = (1<<DDC0);
TIMSK |= ((1<<OCIE0) | (1<<TOIE0)); // use both interrupts
OCR0 = 10; // 10 out of 256 means very short on period (low voltage)
TCCR0 = (1<<CS00); // timer on - nice high PWM frequency
// Might later consider PWMing the backlight voltage too
// so it would also be adjustable ...
sei();