Empecemos con que el pic16f84a NO posee modulo CCP ( por lo tanto no tenes PWM en hardware ) pero si podes hacerlo en software.
ESTO POR SOFTWARE - Sin interrupcionesComo tu software tiene que controlar el periodo, jamas podes tener un __delay_ms(100); , el cual los 100ms son mas grandes que el periodo mismo de la señal. Que para 50hz son 20ms.
Me imagino el programa asi:
while(1) {
Encender led
Esperar X tiempo
apagar led
Esperar Periodo - X tiempo
}
Siempre y cuando X sea menor que tiempo que el periodo.
Eso te daria algo aproximado. Pero tendrias muchos problemas para agregar si quisieras hacer mas cosas, ya que deberias contar el tiempo que necesitas para hacer lo demas para restarselo.
Con interrupcionesEntonces si quisieras hacer algo mas aparte de eso y quisieras algo mas exacto deberias usar interrupciones. Tal como lo hiciste.
Lo que podrias hacer es dividir la cantidad de tiempo en la resolucion que le queres dar. Por ejemplo. si queres 8 bits de resolucion, 256 posibilidades. Haces tu disparo cada (periodo / 256) para el TMR0.
Entonces vos con una variable controlas cuando activa o no, si queres cambiar el duty, cambias DutyPWM
void interrupt PWM(void) {
T0IE = 0;
T0IF = 0;
if (cuentaints < DutyPWM) {
PWM_Pin = 1;
} else {
PWM_Pin = 0;
}
cuentaints ++;
if (cuentaints >= 256) {cuentaints = 0}
T0IE = 1;
}
otro dato, cambie el pic ahora estoy usando un pic16f84a para un proyecto pequeño que tengo en mente pero necesito pwm a 50hz para controlar servomotores, el pic puede correr a 10mhz o a 20mhz.
El pic16f84a puede usar un cristal de 20Mhz segun el datasheet pero recorda que la velocidad maxima esta dividida por 4. No significa que tengas una salida de 20mhz. Ejecuta instrucciones cada 4/20Mhz