No estas comprendiendo lo que estas haciendo. Voy a hacer una explicacion pero sin entrar en mucho detalles y sin preocuparme por la exactitud de los calculos y/o operaciones.
Cuando uno quiere usar un PWM le quedan varias opciones:
- Usar por
Hardware en caso de que tenga 3 salidas independientes
- Crearlo por software, aca hay 2 formas:
- Usar un
delay dentro del while(1). La ventaja es que es mas simple de realizar, la desventaja es que si haces algo mas en el main, ese tiempo extra afecta.
- En ves de usar un delay y poder hacer lo que uno quiera en el main, es usar una
interrupcionCon delay seria algo asi, como vos tenes el main:
for(b=0;b<49;b++){
pwm_duty(c,0,b);
}
PERO llegamos a otro punto de tu programa y vemos que:
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
set_timer0(0);
enable_interrupts(INT_TIMER0);
Estamos usando Interrupciones!!!
NUNCA NUNCA NUNCA llames desde tu main a una interrupcion-------------------------------------------------------------------------------------------------------------------------------
Otra parte erronea es la implementacion del PWM, si vos queres hacer un PWM, tenes que definir una frecuencia y la granularidad del duty.
Ejemplo si quisiera una frecuencia de 100Hz mi PWM deberia tener un periodo de 1/100Hz = 10ms
Ahora si quisiera que yo puedo dividir ese tiempo (con mi duty ) en 50 pedazos aproximadamente, deberia tener una interrupcion cada 10ms / 50 = 200us
Definido los parametros del PWM ya ahora tengo los valores para poder configurar mi Timer ( calcular el overflow y el valor de recarga)
Luego solo debo comparar los valroes que yo le paso con los que va contando el PWM. ¿Como funciona el PWM?
Al principio todas las salidas se encuentran encendidas, luego cuando la cuenta es igual a la definida por nuestra variable PWM procedemos apagarla, asi si definimos un duty de 0 tenemos un minimo.
Como deberias prodecer entonces?
En el main estamos poniendo valores hasta 48 entonces vamos a usar ese valor como maximo. Para eso vamos primero a revisar la funcion de la interrupcion:
#int_timer0
void pwm_duty(void){
set_timer0(0);
if(cont>48)
{
cont=0;
output_high(PIN_A0);
output_high(PIN_A1);
output_high(PIN_A2);
}
if(cont>pwmR)
output_low(PIN_A0);
if(cont>pwmG)
output_low(PIN_A1);
if(cont>pwmB)
output_low(PIN_A2);
cont++;
}
Luego en tu main, solo te importa actualizar los valroes de pwmR,G y B:
La velocidad de cambio va a estar dada por los delay_ms(time), asi que si queres que sea mas lenta, simplemente cambias el valor de ese delay.
while(true)
{
int i;
pwmR = 50;
pwmG = 0;
for(i=0;i<49;i++){
pwmB = i;
}
pwmB = 50;
pwmG = 0;
for(i=48;i>1;i--){
pwmR = i
}
PD:
Afuera de todas las funciones debes declarar las variables:
volatile int pwmR,pwmG,pwmB;
int cont;