#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
}