Hola benito, por lo que veo no comprendes como es que funciona una interrupcion. Asi que mejor en ves de complicarnos por ahora sobre como hacer un PWM variable, presiento que es mejor explicar como es que funciona una interrupcion, y como es que debe programarse.
Tu micro, comienza a ejecutar instruccion es en el vector de reset, el vector de reset es el punto de memoria a la que va el micro al momento de producirse un reset, la vuelta de tension, etc.
De alli hace un par de cosas internas para comenzar a manejar el lenguaje C y se llama a la funcion main. Nosotros ponemos un loop infinito alli. Es decir nunca saldria de alli ( por mas que se llame a una funcion volveria al loop infinito) si la ejecucion fuera normal.
Y aqui es donde entra la interrupcion.
Voy a usar una imagen para que se entienda mejor.
La interrupcion ocurre por hardware, y al producirse el micro guarda donde estaba (la instruccion que le tocaba ejecutar) y salta a la posiciion de memoria que maneja las interrupcion, en tu caso pensalo como si fuera la funcion de interrupcion. Ejecuta la funcion esa, y vuelve a donde dejo.
En la imagen podes ver las 2 funciones, el main a la izquierda y la interrupcion a la derecha, cuando se produce la interrupcion el micro guarda la posicion de memoria de la instruccion numero 5 del main. Y se va a ejecutar la interrupcion, cuando sale vuelve donde habia quedado. Y asi continua.
Si uno lo viera "rapidamente" Podria pensar que esas 2 funciones estan ejecutandose de forma "paralela", es decir al mismo tiempo. Pero lo mas importante ahora, es que NUNCA pero NUNCA desde el main, se llama a la funcion de interrupcion como vos estas haciendo, sino que el mismo Timer es quien le avisa al CPU del microcontrolador y este es quien manda a ejecutar esa funcion.
Supongamos que queremos hacer titilar un led con una interrupcion:
void TIMER_0(void){
set_timer0(0); //Le puse 0 , pero podria ser cualquier numero
output_toggle(PIN_B0);
}
void main(void){
// Configuracion del timer
// Activo interrupcion del timer
while(true){
}
}
Como observas, en el main, nuestro micro se pasaria haciendo nada, encerrado en ese while, pero que gracias a la interrupcion sale de alli y ejecuta el toggle, luego vuelve al main.
Pienso que primero deberias comenzar con esto asi.. Luego haces un PWM como lo tenes realizado
int cont; //Variable de Contador
int pwm0;
#int_timer0
void TIMER_0(void){ //PWM0
set_timer0(200); //Seteo de interrupcion
if(cont>50) //Si cont 50 se inicializa
cont=0; //Cont = 0
else //Caso contrario
cont++; //Incrementa en una unidad cont
if(cont>0&&cont<pwm0) //Si 0<Cont<PWM0
output_high(PIN_a0); //Salida PWM0 a nivel alto
else //Caso contrario
output_low(PIN_a0); //Salida PWM0 a nivel bajo
}
Un par de cambios y otros que no hice pero que deberias.
- Usa las llaves { } en los if y else
- el set_timer siempre al comienzo
- la funcion de interrupcion al uno no deber llamarla, no se le puede pasar valores, por lo tanto sus parametros son void.
- El int cont, deberia ser global, sino donde esta declarado apenas termina la funcion TIMER_0 procede a borrarse, y crearse de nuevo cuando entre. Entonces nunca llegaria a 50.
- Declare otra variable global llamada pwm0, en tu main ahora vas a modificar esa variable en ves de "llamar" a la funcion de interrupcion.
void main(){ //Funcion principal
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
set_timer0(200);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
while(true){
int b;
for(b=0;b<50;b++){
pwm0 = b;
delay_ms(50);
}
for(b=50;b>1;b--){
pwm0 = b;
delay_ms(50);
}
}
}