¿Cómo generar una señal pwm que varíe al menos 20 veces entre el rango de 0-5V usando Atmeaga32 avr mcu?

5

Estoy haciendo un proyecto de Data Logger fotovoltaico (PV) en esto, una potencia MOSFET (IRFZ34N) se puede utilizar como carga. Por lo tanto, quiero variar el voltaje de la compuerta utilizando una señal PWM (rango 0-5v) de MCU & Necesito al menos 2o puntos variables. así que estoy confundido al escribir un código 'C' para generar la señal PWM. como 1. ¿Cuál debería ser el período de tiempo de PWM?     2. ¿Cómo puedo variar el ciclo de trabajo de pwm en diferentes pasos? y etc ..

Y por favor, ayúdame, si hay algo más que tenga que hacer para hacer mi Proyecto exitoso completo. Estaría muy agradecido, si algún cuerpo me ayudara con la respuesta.

    
pregunta Nagu Bhanoth

2 respuestas

7

Puede hacer esto en el software y realizar un seguimiento de todos los tiempos necesarios, pero la mayoría de los microcontroladores tienen hardware que puede generar PWM de forma autónoma después de inicializarlo. Las cosas básicas son un temporizador / contador y un Registro de comparación de salida (OCR):

Elcontadoraumentacontinuamente,representadoporlapendiente,ysecomparaconelOCR.LasalidadePWMbajacuandoelcontadorsuperaelOCRyvuelveaseraltacuandosereinicia.Laresolucióndel5%quenecesita(20pasos)noesunproblema;untemporizadorde16bitspuedegenerarPWMconunaresoluciónmejorque0.002%,einclusountemporizadorde8bitspuedehacer0.4%.

TodoloquetienequehaceresprogramarunnuevovalorenelOCR.Cuantomenorseaelvalor,menorseráelanchodelpulso.Lasiguienteanimaciónesde este sitio :

Lecturasadicionales
Uso de PWM de alta velocidad del AVR , un La nota de la aplicación Atmel.
Hoja de datos de ATMega32 se describe en la página 69 y siguientes. cómo utilizar Timer0 para la operación PWM.

    
respondido por el stevenvh
3

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();
    
respondido por el Oli Glaser

Lea otras preguntas en las etiquetas