0% encontró este documento útil (0 votos)
109 vistas7 páginas

Configuración PWM en AVR C

El documento describe cómo configurar un temporizador (timer 1) en un microcontrolador AVR para generar una señal PWM con diferentes frecuencias y tiempos de pulso. Se explica la configuración del timer en modo Fast PWM y en modo frecuencia y fase correcta para lograr la señal deseada variando el valor de OCR1A y otros registros de configuración del timer. El código muestra cómo cambiar dinámicamente los parámetros de la señal PWM en función de la entrada del usuario a través de un switch.

Cargado por

Victor Procel
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como TXT, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
109 vistas7 páginas

Configuración PWM en AVR C

El documento describe cómo configurar un temporizador (timer 1) en un microcontrolador AVR para generar una señal PWM con diferentes frecuencias y tiempos de pulso. Se explica la configuración del timer en modo Fast PWM y en modo frecuencia y fase correcta para lograr la señal deseada variando el valor de OCR1A y otros registros de configuración del timer. El código muestra cómo cambiar dinámicamente los parámetros de la señal PWM en función de la entrada del usuario a través de un switch.

Cargado por

Victor Procel
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como TXT, PDF, TXT o lee en línea desde Scribd

#include <inttypes.

h>
#ifdef F_CPU
#undef F_CPU
#define F_CPU 8000000L
#endif

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/io.h>
#include<util/delay.h>
#include<stdbool.h>
//Queremos generar una señal PWM con una frecuencia de 50Hz con un periodo de 20ms
//y que la parte alta de la señal dure entre 1 y 2 milisegundos.
//Tenemos que configurar el modo de operacion a Fast-PWM
// De todos los modos Fast-PWM que podemos configurar, queremos definir cuando
//el contador se reiniciará, esto nos permite hacer que se reinicie cada 20ms
//Asi que elegimos los que tienen TOP=ICR1 y el único que tiene ese modo de
//configuración es el Modo 14, Fast PWM.
//WGM10=0,WGM11=1,WGM12=1,WGM13=1
//Además, queremos que la salida se ponga a alto desde el inicio del pulso, hasta
que el contador valga lo que queremos.
//Sin embargo, para controlar la salida, vemos que hay dos registros,
//y es que este temporizador puede controlar dos salidas, son los pines OC1A y
OC1B.
//Como salida configuramos el pin PB1 (OC1A)
//Tendremos que configurar el PB1 en modo OUTPUT , luego, configurar el COM1A1 y
COM|A0
//Para que cuando se reinicie el contador, la salida esté en alto , y cuando llegue
a la comparación se ponga en bajo.
//COM1A0=0 y COM1A1=1
//Con un preescaler de 8, el máximo periodo es de 32ms.
//Tenemos que decidir hasta que valor tiene que subir el contador principal antes
de reiniciarse.
// Fpwm= fclk/ N* (1+TOP), TOP=fclk/N*fpwm-1.
//=16,000,000/8*50-1=39999
void Iniciallizar_PWM();
bool DECREMENTAR;
int INC=50;
int main()

Iniciallizar_PWM();
while(1)
{
switch (PIND & 15)
{

//
******************************************************************************USAND
O FRECUENCIA Y FASE CORRECTA TEMPORIZADOR
1**********************************************************************************
***********************************************************************************
case 0:
//USANDO EL MODO FRECUENCIA Y FASE CORRECTA (MODO 8) PREESCALER 8,
FRECUENCIA 8MHZ TIMER 1
//=(8,000,000/2*8*50)-1=??
ICR1=9999;
TCCR1A = (1 << COM1A1) | (0 << COM1A0) ; // Ponemos a 'bajo' el OCR1A
cuando coincida el Compare Match
TCCR1A |= (0 << WGM11) | (0 << WGM10) ; // MODO FRECUENCIA Y FASE
CORREC: TOP: ICR1
TCCR1B = (1 << WGM13) | (0 << WGM12); // // MODO FRECUENCIA Y FASE
CORREC: TOP: ICR1
TCCR1B |= (0 << CS12) | (1 << CS11) | ( 0 << CS10 ); // Preesc = 8
//OCR1A = 2000; // pulso de 1 ms
OCR1A =500; // pulso de 1.5 ms
break;

case 1:

//USANDO EL MODO FRECUENCIA Y FASE CORRECTA (MODO 8) PREESCALER 8,


FRECUENCIA 8MHZ TIMER 1
//=(8,000,000/2*8*50)-1=??
ICR1=9999;
TCCR1A = (1 << COM1A1) | (0 << COM1A0) ; // Ponemos a 'bajo' el OCR1A
cuando coincida el Compare Match
TCCR1A |= (0 << WGM11) | (0 << WGM10) ; // MODO FRECUENCIA Y FASE
CORREC: TOP: ICR1
TCCR1B = (1 << WGM13) | (0 << WGM12); // // MODO FRECUENCIA Y FASE
CORREC: TOP: ICR1
TCCR1B |= (0 << CS12) | (1 << CS11) | ( 0 << CS10 ); // Preesc = 8
//OCR1A = 2000; // pulso de 1 ms
OCR1A =625; // pulso de 1.5 ms
break;

case 2:

//USANDO EL MODO FRECUENCIA Y FASE CORRECTA (MODO 8) PREESCALER 8,


FRECUENCIA 8MHZ TIMER 1
//=(8,000,000/2*8*50)-1=??
ICR1=9999;
TCCR1A = (1 << COM1A1) | (0 << COM1A0) ; // Ponemos a 'bajo' el OCR1A
cuando coincida el Compare Match
TCCR1A |= (0 << WGM11) | (0 << WGM10) ; // MODO FRECUENCIA Y FASE
CORREC: TOP: ICR1
TCCR1B = (1 << WGM13) | (0 << WGM12); // // MODO FRECUENCIA Y FASE
CORREC: TOP: ICR1
TCCR1B |= (0 << CS12) | (1 << CS11) | ( 0 << CS10 ); // Preesc = 8
//OCR1A = 2000; // pulso de 1 ms
OCR1A =750; // pulso de 1.5 ms
break;

case 3:
//USANDO EL MODO FRECUENCIA Y FASE CORRECTA (MODO 8) PREESCALER 8,
FRECUENCIA 8MHZ TIMER 1
//=(8,000,000/2*8*50)-1=??
ICR1=9999;
TCCR1A = (1 << COM1A1) | (0 << COM1A0) ; // Ponemos a 'bajo' el OCR1A
cuando coincida el Compare Match
TCCR1A |= (0 << WGM11) | (0 << WGM10) ; // MODO FRECUENCIA Y FASE
CORREC: TOP: ICR1
TCCR1B = (1 << WGM13) | (0 << WGM12); // // MODO FRECUENCIA Y FASE
CORREC: TOP: ICR1
TCCR1B |= (0 << CS12) | (1 << CS11) | ( 0 << CS10 ); // Preesc = 8
//OCR1A = 2000; // pulso de 1 ms
OCR1A =875; // pulso de 1.5 ms
break;

case 4:
//USANDO EL MODO FRECUENCIA Y FASE CORRECTA (MODO 8) PREESCALER 8,
FRECUENCIA 8MHZ TIMER 1
//=(8,000,000/2*8*50)-1=??
ICR1=9999;
TCCR1A = (1 << COM1A1) | (0 << COM1A0) ; // Ponemos a 'bajo' el OCR1A
cuando coincida el Compare Match
TCCR1A |= (0 << WGM11) | (0 << WGM10) ; // MODO FRECUENCIA Y FASE
CORREC: TOP: ICR1
TCCR1B = (1 << WGM13) | (0 << WGM12); // // MODO FRECUENCIA Y FASE
CORREC: TOP: ICR1
TCCR1B |= (0 << CS12) | (1 << CS11) | ( 0 << CS10 ); // Preesc = 8
//OCR1A = 2000; // pulso de 1 ms
OCR1A =1000; // pulso de 1.5 ms
break;
//
******************************************************************************USAND
O FAST PWM TEMPORIZADOR
1**********************************************************************************
***********************************************************************************
case 5:

//=16,000,000/8*50-1=39999
//ICR1=39999;
ICR1=19999;
TCCR1A = (1 << COM1A1) | (0 << COM1A0) ; // Ponemos a 'bajo' el OCR1A
cuando coincida el Compare Match
TCCR1A |= (1 << WGM11) | (0 << WGM10) ; // Fast PWM: TOP: ICR1
TCCR1B = (1 << WGM13) | (1 << WGM12); // // Fast PWM: TOP: ICR1
TCCR1B |= (0 << CS12) | (1 << CS11) | ( 0 << CS10 ); // Preesc = 8
//OCR1A = 2000; // pulso de 1 ms
OCR1A=1000;
break;

case 6:

//=16,000,000/8*50-1=39999
//ICR1=39999;
ICR1=19999;
TCCR1A = (1 << COM1A1) | (0 << COM1A0) ; // Ponemos a 'bajo' el OCR1A
cuando coincida el Compare Match
TCCR1A |= (1 << WGM11) | (0 << WGM10) ; // Fast PWM: TOP: ICR1
TCCR1B = (1 << WGM13) | (1 << WGM12); // // Fast PWM: TOP: ICR1
TCCR1B |= (0 << CS12) | (1 << CS11) | ( 0 << CS10 ); // Preesc = 8
//OCR1A = 2500; // pulso de 1.25ms
OCR1A = 1250; // pulso de 1.25ms
break;

case 7:

//=16,000,000/8*50-1=39999
//ICR1=39999;
ICR1=19999;
TCCR1A = (1 << COM1A1) | (0 << COM1A0) ; // Ponemos a 'bajo' el OCR1A
cuando coincida el Compare Match
TCCR1A |= (1 << WGM11) | (0 << WGM10) ; // Fast PWM: TOP: ICR1
TCCR1B = (1 << WGM13) | (1 << WGM12); // // Fast PWM: TOP: ICR1
TCCR1B |= (0 << CS12) | (1 << CS11) | ( 0 << CS10 ); // Preesc = 8
//OCR1A = 3000; // pulso de 1.5 ms
OCR1A = 1500; // pulso de 1.5 ms
break;

case 8:

//=16,000,000/8*50-1=39999
//ICR1=39999;
ICR1=19999;
TCCR1A = (1 << COM1A1) | (0 << COM1A0) ; // Ponemos a 'bajo' el OCR1A
cuando coincida el Compare Match
TCCR1A |= (1 << WGM11) | (0 << WGM10) ; // Fast PWM: TOP: ICR1
TCCR1B = (1 << WGM13) | (1 << WGM12); // // Fast PWM: TOP: ICR1
TCCR1B |= (0 << CS12) | (1 << CS11) | ( 0 << CS10 ); // Preesc = 8
//OCR1A = 3500; // pulso de 1.75 ms
OCR1A = 1750; // pulso de 1.75 ms
break;

case 9:

//=16,000,000/8*50-1=39999
//ICR1=39999;
ICR1=19999;
TCCR1A = (1 << COM1A1) | (0 << COM1A0) ; // Ponemos a 'bajo' el OCR1A
cuando coincida el Compare Match
TCCR1A |= (1 << WGM11) | (0 << WGM10) ; // Fast PWM: TOP: ICR1
TCCR1B = (1 << WGM13) | (1 << WGM12); // // Fast PWM: TOP: ICR1
TCCR1B |= (0 << CS12) | (1 << CS11) | ( 0 << CS10 ); // Preesc = 8
// OCR1A = 4000; // pulso de 2 ms
OCR1A=1998;
break;

case 10:
//=16,000,000/8*50-1=39999
//ICR1=39999;
ICR1=19999;
TCCR1A = (1 << COM1A1) | (0 << COM1A0) ; // Ponemos a 'bajo' el OCR1A
cuando coincida el Compare Match
TCCR1A |= (1 << WGM11) | (0 << WGM10) ; // Fast PWM: TOP: ICR1
TCCR1B = (1 << WGM13) | (1 << WGM12); // // Fast PWM: TOP: ICR1
TCCR1B |= (0 << CS12) | (1 << CS11) | ( 0 << CS10 ); // Preesc = 8
// OCR1A = 4000; // pulso de 2 ms
if (OCR1A>=2000 )
{ OCR1A=1000;
}
++OCR1A ;

break;

case 11:
//=16,000,000/8*50-1=39999
//ICR1=39999;
ICR1=19999;
TCCR1A = (1 << COM1A1) | (0 << COM1A0) ; // Ponemos a 'bajo' el OCR1A
cuando coincida el Compare Match
TCCR1A |= (1 << WGM11) | (0 << WGM10) ; // Fast PWM: TOP: ICR1
TCCR1B = (1 << WGM13) | (1 << WGM12); // // Fast PWM: TOP: ICR1
TCCR1B |= (0 << CS12) | (1 << CS11) | ( 0 << CS10 ); // Preesc = 8
// OCR1A = 4000; // pulso de 2 ms
if ((!DECREMENTAR) && OCR1A>=2000 )
{
DECREMENTAR=true;
}

if (DECREMENTAR&& OCR1A<=1000 )
{
DECREMENTAR=false;
}
if (DECREMENTAR)
{ --OCR1A;}

if (!DECREMENTAR)
{ ++OCR1A;}
break;

case 12:
//=16,000,000/8*50-1=39999
//ICR1=39999;
ICR1=19999;
TCCR1A = (1 << COM1A1) | (0 << COM1A0) ; // Ponemos a 'bajo' el OCR1A
cuando coincida el Compare Match
TCCR1A |= (1 << WGM11) | (0 << WGM10) ; // Fast PWM: TOP: ICR1
TCCR1B = (1 << WGM13) | (1 << WGM12); // // Fast PWM: TOP: ICR1
TCCR1B |= (0 << CS12) | (1 << CS11) | ( 0 << CS10 ); // Preesc = 8
// OCR1A = 4000; // pulso de 2 ms
if ((!DECREMENTAR) && OCR1A>=1500 )
{
DECREMENTAR=true;
}

if (DECREMENTAR&& OCR1A<=1000 )
{
DECREMENTAR=false;
}
if (DECREMENTAR)
{ --OCR1A;}

if (!DECREMENTAR)
{ ++OCR1A;}
break;

case 13:
//=16,000,000/8*50-1=39999
//ICR1=39999;
ICR1=19999;
TCCR1A = (1 << COM1A1) | (0 << COM1A0) ; // Ponemos a 'bajo' el OCR1A
cuando coincida el Compare Match
TCCR1A |= (1 << WGM11) | (0 << WGM10) ; // Fast PWM: TOP: ICR1
TCCR1B = (1 << WGM13) | (1 << WGM12); // // Fast PWM: TOP: ICR1
TCCR1B |= (0 << CS12) | (1 << CS11) | ( 0 << CS10 ); // Preesc = 8
// OCR1A = 4000; // pulso de 2 ms
if ((!DECREMENTAR) && OCR1A>=2000 )
{
DECREMENTAR=true;
}
if (DECREMENTAR&& OCR1A<=1500 )
{
DECREMENTAR=false;
}
if (DECREMENTAR)
{ --OCR1A;}

if (!DECREMENTAR)
{ ++OCR1A;}
break;

/******************************************************************MODIFICACION DE
INTENSIDAD DE LED*, USO DE TEMPORIZADOR 2 CON PREESCALER
8*******************************************************************/
switch (PIND &192)
{
case 64:
//fmax= fckl / 8* 2( MAX+1) para este ejemplo MAX=512 (no se puede
modificar el tope., con un preescaler de 8 MAX=0...255
cuenta total 256 ___________.5ms

if (OCR2A <=255-INC ){ OCR2A+=INC;} //255->1953.00 128->976


0.24MS
if (OCR2A>=255 ) {OCR2A=255;}

TCCR2A = (1 << COM2A1) | (0 << COM2A0) ; // Ponemos a 'bajo' el OCR1A


cuando coincida el Compare Match
TCCR2A |= (0<< WGM21) | (1<< WGM20) ; // Fast PWM: TOP: ICR1
TCCR2B = (0<< WGM22); // // Fast PWM: TOP: ICR1
TCCR2B |= (0 << CS22) | (1 << CS21) | ( 0 << CS20 ); // Preesc = 8
// OCR1A = 4000; // pulso de 2 ms
_delay_ms(3000);
break;

case 128:
//fmax= fckl / 8* 2( MAX+1) para este ejemplo MAX=512 (no se puede
modificar el tope., con un preescaler de 8
if (OCR2A >=INC ){ OCR2A-=INC;}
if (OCR2A<=0 ) {OCR2A=0;}

TCCR2A = (1 << COM2A1) | (0 << COM2A0) ; // Ponemos a 'bajo' el OCR1A


cuando coincida el Compare Match
TCCR2A |= (0<< WGM21) | (1<< WGM20) ; // Fast PWM: TOP: ICR1
TCCR2B = (0<< WGM22); // // Fast PWM: TOP: ICR1
TCCR2B |= (0 << CS22) | (1 << CS21) | ( 0 << CS20 ); // Preesc = 8
// OCR1A = 4000; // pulso de 2 ms
_delay_ms(3000);
break;
}

_delay_ms(3);
}
}

void Iniciallizar_PWM(){

DDRB |= ( 1<< PB1 | 1<<PB3); // Configuramos el PB1 como salida OC21 y PB3 como
salida par OC2A.
DDRD=0XFF;
TCNT1 = 0; // Reiniciamos el contador inicial
//=16,000,000/8*50-1=39999
//=8,000,000/8*50-1=???
//ICR1 = 39999; // Configuramos el periodo de la señal (el TOP de nuestra PWM)
ICR1 = 19999; // Configuramos el periodo de la señal (el TOP de nuestra PWM)
TCCR1A = (1 << COM1A1) | (0 << COM1A0) ; // Ponemos a 'bajo' el icr1 cuando
coincida el Compare Match
TCCR1A |= (1 << WGM11) | (0 << WGM10) ; // Fast PWM: TOP: ICR1
TCCR1B = (1 << WGM13) | (1 << WGM12); // // Fast PWM: TOP: ICR1
TCCR1B |= (0 << CS12) | (1 << CS11) | ( 0 << CS10 ); // Preesc = 8
//OCR1A = 2000; // pulso de 1 ms
OCR1A = 1000; // pulso de 1 ms
}

También podría gustarte