Dejame entender.
De 0 a 9 incrementa, siendo 9 el maximo, si seguis presionando empieza a disminuir hasta que llegas a 18=0.
1 pulsador incrementa R 0-18 (Max 9)
1 pulsador incrementa B 0-18 (Max 9)
1 pulsador incrementa G 0-18 (Max 9)
1 pulsador incrementa R,B y G 0-18, el contador va de 0 a 19, aunque 0 deberia entrar 1 sola ves, solo entraria a 0 si es que queres que si se presion R o G o B vuelva a resetearse y mover todos juntos
Entiendo que intentaste hacer en algunas partes, pero creo que si pudieras explicar que son la variable rbg, esto:
if(PORTBbits.RB4==0 && PORTBbits.RB5==0){rgb=1;}
else{rgb=0;}
if(PORTBbits.RB4==0 && PORTBbits.RB6==0){rgb=1;}
else{rgb=0;}
if(PORTBbits.RB5==0 && PORTBbits.RB6==0){rgb=1;}
else(rgb=0);
if(PORTBbits.RB4==0 && PORTBbits.RB5==0 && PORTBbits.RB6==0){rgb=1;}
else{rgb=0;}
Y el codigo de tu interrupcion seria un poco mas pasable. Y facil de entender, ademas de explicar que variables hay y para que las estas usando, por ejemplo por lo que veo pw2n es un contador que tenes en la funcion del color B, y lo que maneja realmente el PWM es pw2, es asi ?.
Otra cosa mas, tendrias el inverso como esta planteado actualmente donde el maximo seria 1 y el 9 o 0 seria tu valor minimo, segun la interrupcion que tenes, ademas tenes 2 preguntas a cada pwx que hacen conflicto ahi.
Tenes puesto en mal lugar el tema del contador de time. a mi parecer, pero todo depende de como queres que funcione.
En fin Pienso que para arreglarlo deberias:- Quitar eso de la variable rgb, que realmente no aporta nada..
Lo de tu variable rgb es simple por que quitarlo, si en algun momento presionas un boton este va a quedar atrapado en la funcion del boton hasta que no se suelte el mismo, por ende jamas vas a poder presionar 2 juntos, seria MUY pero MUY mucha casualidad que lo hagas, y aun asi si los presionas los 2 juntos va a entrar a la 1ra funcion y quedar atrapada ahi y no a ambas funciones.
Por otra parte le pondria un pequeño delay entre if y el while de los botones para un "antirebote" de unos 5/10 ms.
////// BOTON R //////////////////
if(!PORTBbits.RB3){
__delay_ms(10); //Antirebote
while(!PORTBbits.RB3); // Espero que suelte
if(c==19){PORTBbits.RB0=0;PORTBbits.RB1=0;PORTBbits.RB2=0; c=0;}
por esto
if(c==19){pw0=0; pw1=0; pw2=0; c=1;}
La explicacion es simple, vos unicamente manejas ahi los valores de pw0,pw1 y pw2, no sus puertos. De eso se encarga la interrupcion. Si modificas sus puertos y no su pwx cuando entre a la interrupcion se encenderia o no segun el valor que tengan.
Si queres que una ves presionado cualquiera de los botones R,G o B vuelva a reiniciar los valores, usa c=0; dentro de esas funciones. Asi cuando presiones de nuevo W este reinicie los valores a 0
Observaras ademas que puse c=1, ya que si pongo c=0, cuando entre nuevamente va a incrementar y no va a pasar nada, es decir vas a tener que pulsar 2 veces para que comienze a incrementar.
- Modificar tu rutina de interrupcion, eliminar esa doble pregunta sobre los pwx
Tu rutina de interrupcion tiene un problema y es que estas preguntando por 2 cosas a la ves. Me refiero a estos:
if(pw0==0){PORTBbits.RB0=0;}
else{ PORTBbits.RB0=1;}
Voy a suponer que time va de 0 a 9, apenas incrementas time deberias de preguntar si es 10 y volverlo a 0, pero esto lo estas haciendo despues lo cual ES un error por como lo tenes programado.
PORTBbits.RB7=!PORTBbits.RB7;
if(time==10){time=0; PORTBbits.
RB0=1; PORTBbits.
RB1=1; PORTBbits.
RB2=1;} if(pw0
==time){PORTBbits.
RB0=0;} if(pw1
==time){PORTBbits.
RB1=0;} if(pw2
==time){PORTBbits.
RB2=0;}
Asi como lo puse va a producir un pequeño glitch de unos microsegundos, es decir un pulso de ese tiempo, sino:
PORTBbits.RB7=!PORTBbits.RB7;
if(pw0
>=time){PORTBbits.
RB0=0;} else {PORTBbits.
RB0=1;} if(pw1
>=time){PORTBbits.
RB1=0;} else {PORTBbits.
RB1=1;} if(pw2
>=time){PORTBbits.
RB2=0;} else {PORTBbits.
RB2=1;}
y se soluciona