Buenas, pretendo hacer un control de volumen digital con mando a distancia. De momento estoy programando el mando a distancia, tengo este programa de prueba, es muy parecido al dimmer con mando de Nocturno, en el cual pongo dos led de prueba para encenderlos y apagarlos.
El problema es que despues de memorizar las teclas del mando, se encienden o apagan los dos led al mismo tiempo con casi cualquier tecla del mando.
//****************************************************************************//
// Version CCS 3.242
//****************************************************************************//
# include <16F84a.h>
# use delay(clock=4000000)
# fuses XT,NOWDT,NOPUT,NOPROTECT
#byte PORTA = 0x05
#byte PORTB = 0x06
#bit GRABAR = PORTA.0
#bit ZUMBADOR = PORTA.1
#bit SALIDA_1 = PORTA.2
#bit SALIDA_2 = PORTA.3
#bit MANDO = PORTB.0
#define Periodo 190
#define SI 1
#define NO 0
#define ON 1
#define OFF 0
//********************************* VARIABLES ********************************//
int1 PermisoLeer;//Impide la lectura de una tecla despues de acabar de leerla.
int8 Pasos;//se incrementa cada vuelta del timer, capturando un bit del mando.
int32 LecturaMando;//Almacena la lectura de una tecla pulsada.
int32 LecturaMandoTemporal;//Almacena temporalmente la lectura de una tecla
//pulsada, para su posterior comprobación.
int8 EstadoProceso;//Cuando se pulsa la tecla GRABAR, va pasando por todas las
//teclas que se están programando, en primera pasada se
//captura la tecla; en segunda pasada se captura de nuevo y
//se comprueba.
int8 Direccion;//Almacena la dirección de la EEPROM donde se guardan las teclas.
int32 IncVol;//Tecla incrementar volumen.
int32 DecVol;//Tecla decrementar volumen.
int32 CanalSel;//Tecla seleccion del canal.
int32 Bal_L;//Tecla balance hacia el canal L.
int32 Bal_R;//Tecla balance hacia el canal R.
//****************************************************************************//
//****************************************************************************//
//Lee de la EEPROM los códigos de mando que se hayan memorizado //
//****************************************************************************//
void LeerCodigosMando(void){
int8 i;
IncVol=read_eeprom(3);
DecVol=read_eeprom(7);
CanalSel=read_eeprom(11);
Bal_L=read_eeprom(15);
Bal_R=read_eeprom(19);
for(i=2;i!=0xFF;i--){
IncVol=IncVol*256+read_eeprom(i);
DecVol=DecVol*256+read_eeprom(i+4);
CanalSel=CanalSel*256+read_eeprom(i+8);
Bal_L=Bal_L*256+read_eeprom(i+12);
Bal_R=Bal_R*256+read_eeprom(i+16);
}
}
//****************************************************************************//
//Reproduce un pitido corto de 200msg. //
//****************************************************************************//
void PitidoCorto(void){
int8 i;
for(i=0;i<200;i++){
ZUMBADOR=ON;
delay_us(500);
ZUMBADOR=OFF;
delay_us(500);
}
}
//****************************************************************************//
//Reproduce un pitido corto de 600msg. //
//****************************************************************************//
void PitidoLargo(void){
int16 i;
for(i=0;i<600;i++){
ZUMBADOR=ON;
delay_us(500);
ZUMBADOR=OFF;
delay_us(500);
}
}
//****************************************************************************//
//Graba las cinco teclas: Subir volumen, bajar volumen, seleccion del canal, //
//balance L, balance R. //
//****************************************************************************//
void AlmacenaTecla(void){
int8 cont;
if(EstadoProceso%2==1){//Paso impar.
//Captura de tecla.
LecturaMandoTemporal=LecturaMando;
EstadoProceso++;
PitidoCorto();//Indica tecla leida.
}else{//Paso par.
//Comprobacion de tecla.
if(LecturaMandoTemporal==LecturaMando){
//Tecla correcta.
Direccion=EstadoProceso*2-4;
write_eeprom(Direccion,LecturaMando%256);//Parte baja
LecturaMando=LecturaMando/256;
write_eeprom(Direccion+1,LecturaMando%256);
LecturaMando=LecturaMando/256;
write_eeprom(Direccion+2,LecturaMando%256);
LecturaMando=LecturaMando/256;
write_eeprom(Direccion+3,LecturaMando%256);//Parte alta.
EstadoProceso++;
PitidoLargo();//Indica tecla almacenada correctamente.
}else{//Comprobacion fallida.
EstadoProceso--;
LecturaMandoTemporal=0;
for(cont=0;cont<4;cont++){//Indica fallo de lectura, se repite esa tecla.
PitidoCorto();
Delay_ms(200);
}
}
}
if(EstadoProceso==11){//5 teclas grabadas correctamente.
LeerCodigosMando();
EstadoProceso=1;
for(cont=0;cont<4;cont++){//Indica fin de teclas almacenadas.
PitidoLargo();
Delay_ms(200);
}
Delay_ms(4000);
}
}
//****************************************************************************//
//Procesa las pulsaciones de las teclas del mando. //
//****************************************************************************//
void ProcesaTecla(void){
if(LecturaMando==IncVol){
if(SALIDA_1==ON)
SALIDA_1=OFF;
else
SALIDA_1=ON;
Delay_ms(100);
}
if(LecturaMando==DecVol){
if(SALIDA_2==ON)
SALIDA_2=OFF;
else
SALIDA_2=ON;
Delay_ms(100);
}
}
//****************************************************************************//
//En esta interrupción se interpretan y se programan las teclas del mando. //
//En cada pasada de la interrupción se toma una muestra del mando, al llegar //
//a 32 muestras se interpretan o programan las teclas. //
//****************************************************************************//
#INT_TIMER0
void tempo(){
set_timer0(Periodo);
if(PermisoLeer==SI){
Pasos++;
LecturaMando=LecturaMando*2+MANDO;
if(Pasos==32){//Fin de la captura.
PermisoLeer=NO;
if((LecturaMando!=0xEFFFFFFF)&&(LecturaMando!=0)){
//Con esto eliminamos el ruido.
if(GRABAR){
AlmacenaTecla();
}else{
ProcesaTecla();
}
}
Delay_ms(1200);
enable_interrupts(INT_EXT);
}
}
}
//****************************************************************************//
//Esta interrupción detecta que una tecla del mando se ha pulsado y se prepara//
//el timer0 para leer la tecla. //
//****************************************************************************//
#INT_EXT
void CrucePor0(){
set_timer0(Periodo);
disable_interrupts(INT_EXT);
PermisoLeer=SI;
Pasos=0;
}
//****************************************************************************//
//****************************************************************************//
void main(){
set_tris_A(0b11110001);
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_8);
enable_interrupts(INT_TIMER0);
enable_interrupts(INT_EXT);
ext_int_edge(H_TO_L);
enable_interrupts(GLOBAL);
EstadoProceso=1;
LeerCodigosMando();
while(1);
}
Un saludo.