Bueno como no obtuve respuesta aqui voy a decir como lo hice buscando , para que otro que tenga mi mismo problema lo solucione.
El problema: no puedo generar una onda de 140hz mediante hardware a partir de un FOSC (oscilador) de 8MHZx4PLL=32mhz FOSC.
Uso el Timer0 como timer de Periodo de la onda de 140hz (ocupa unos 7,14ms) y luego el Timer2 como timer de Ciclo a 1 (duty cycle) de 0,0ms a 7.14ms -> 0% a 100% , ejemplo 5%->0,357ms.
Bien una vez definido como y cuales aqui es como los configuro.
Timer0:
// Temporización = [(256 - ValorprecargadoTMR0)*Prescalador+2]*4/Fosc= tiempo temporizado en seg
// Temporización = [(256 - 33)*256+2]*4/32000000=0,00713625 seg ->7,13625ms->1/0,00713625 =140,129hz
Código:
T0CS = 0;//Cojo señal del reloj del interno (FOSC).
T0SE = 0;//Conteo cuando estemos en el flanco de subida.
PSA = 0;//Asignar prescaler al timer0
T0PS2 = 1;T0PS1 = 1;T0PS0 = 1;//Prescalado a 1:256
TMR0 = 33;//Valor precargado para que la interrupcion salte cada 140hz(7,14ms) aprox.
TMR0IE=1;//Habilito interrupciones en timer0
TMR0ON=1;//Enciendo temp.
En la rutina de interrupcion:
Código:
if((TMR0IF)&&(TMR0IE)) {
PORTBbits.RB0=1; //Pongo el pin RB0 a 5v (1)
TMR2IF=0;//Limpio el flag interrupcion del timer2
TMR2ON=1;//Inicio el timer2 del duty cicle
//Limpio flag interrupcion del timer0
TMR0IF=0;
}
Ahora toca el reloj del duty cicle o tiempo a 1 que se encarga el timer2, preconfiguro el timer2 para tener un duty cicle que pueda variarlo en intervalos de 5% -> 0%,5%,10%....95%,100%.
Para ello divido el periodo de la señal de 140hz (1/140=7,14ms) con una regla de tres, si 100% es 7,14ms cuanto es 5% -> 5*7,14/100 =0,357ms es un 5%.
Entonces tengo que calcular el timer2 para que me genere una interrupción cada 0.357ms para poder tener saltos de 5% en la rutina de interrupcion y ya luego si quiero tener 50% de pwm, basta con esperar 10 interrupciones en la subrutina a ON y ya tendre 5%*10=50% = 0.357*10=3,57ms.
Como configuro timer2 para obtener 0.357ms:
//Quiero incrementos de 5%-> 100/5=20saltos ->Timer0 overflow cuando 256/20=12,8 de PR2
//Entonces 12,8 -> 13 entero , entonces 13 es el 5,078125%.
//Precarcamos para 5,078125% 256-PR2=13 ->243
// Temporización = [(256 - PR2)*Prescaler*Postcaler+2]*4/Fosc=Tiempo en seg
// Temporización = [(256 - 243)*16*14+2]*4/32000000=0,00036425seg ->0,36425ms
Código:
T2OUTPS3=1;T2OUTPS2=1;T2OUTPS1=0;T2OUTPS0=1;//Postscaler puesto a 14
T2CKPS1 = 1;T2CKPS0 = 0;// Prescaler selecionado 16
PR2 = 243; // Valor precargado PR2 para pwm 5.078125%.
TMR2IE=1; //Habilito interrupciones
Luego en la rutina:
Código:
if((TMR2IF)&&(TMR2IE)) {
cont_overflw_duty++;//Contador de overflows de 5%
if(cont_overflw_duty==10) {//10*5,07%=50,7%
PORTBbits.RB0=0;
cont_overflw_duty = 0; //Reset Contador
}
TMR2ON=0;//Deshabilito el timer ya que ya ha creado la onda
TMR2IF=0;//Limpio el flag de interrupciones.
}
Espero que haya sido de ayuda.