miren en este foro encontre un dato muy importante donde graba datos de un control remoto, este proyecto lo encontre el el de DImmer a control remoto
// PROYECTO DIMMER DIGITAL
#include <16F84A.h>
#use delay(clock=4000000)
#use fast_io(A)
#use fast_io(B)
#rom 0x2100={0x0A,0x94,0x92,0x55,0x09,0x4A,0x49,0x2A,0x09,0x4A,0x92,0x55}
/*2708 / 37461 = 0A 94 92 55
2378 / 18730 = 09 4A 49 2A
2378 / 37461 = 09 4A 92 55*/
#fuses XT,NOWDT,NOPUT
#byte PORTA = 0x05
#byte PORTB = 0x06
#bit TRIAC = PORTB.1
#bit LED_VERDE = PORTA.0
#bit LED_ROJO = PORTA.2
#bit PULSADOR = PORTA.3
#bit INTERRUPTOR_PARED = PORTB.2
#bit MANDO = PORTB.3
#byte ANSEL = 0x9B
#byte OPTIONREG = 0x81
#define LimiteInf 40
#define LimiteSup 150
#define Periodo 86//86
#define PausaTrasEnvio 4
#define RelacionMandoDimmer 8
#define LimiteAntirrebotes 350
#define ModoEjecucion 0
#define ModoProgramacion 1
#define PausaCorta 100
#define PausaMedia 200
// arriba 2708, 37461
// abajo 2378,18730
// derecha 2346,19029
// izda 2708,38058
// ok 2378,37461
/**************************************** VARIABLES ******************************************/
int Recibiendo; // está a 0 en reposo, y a 1 mientras recibe una pulsación del mando
// al finalizar la pulsación se incrementa 1 cada ciclo hasta final de pausa
int Pasos; // se incrementa en 1 cada X vueltas del timer, coincidendo con la captura de bits del mando
int PasosDimmer; // se incrementa con cada vuelta del timer
// se pone a 0 en la detección del cruce por 0
int Intensidad; // almacena el valor de disparo del triac.
// Cuando PasosDimmer llega al valor de Intensidad se dispara el Triac
int i,j; // genéricas
int par; // se incrementa en 1 cada vuelta del dimmer
// sirve para saber cada cuantas vueltas hay que ejecutar lectura de mando
int Modo; // distingue si el circuito está en modo ejecución o en modo programación
int EstadoProceso; // en Modo Programación, va pasando por todos las teclas que se están programando
// en primera pasada se captura la tecla
// en segunda pasada se captura de nuevo y se comprueba
int Direccion; // Dirección de la EEprom donde se está almacenando un valor en cada momento
int UltimoEstadoInterruptor; // 0 si el interruptor estaba apagado y 1 si estaba encendido
long Antirrebotes; // se pone a 0 tras la pulsación del mando
// y se va incrementando en cada ciclo del timer
// Se utiliza en teclas donde no queremos autorrepetición, como la tecla OnOff
long Lectura1, Lectura2, CapturaTemporal1, CapturaTemporal2; // valores temporales de las lecturas del mando
// Valores de las teclas almacenadas en la EEProm
long BajaIntMSB,BajaIntLSB,SubeIntMSB,SubeIntLSB,OnOffMSB,OnOfFLSB,P1MSB,P1LSB,P2MSB,P2LSB;
/*************************************************************************/
/* Lee de la EEPROM los códigos de mando que se hayan memorizado */
/*************************************************************************/
void LeeCodigosMando(void)
{
i=read_eeprom(0);
BajaIntMSB=i*256+read_eeprom(1);
i=read_eeprom(2);
BajaIntLSB=i*256+read_eeprom(3);
i=read_eeprom(4);
SubeIntMSB=i*256+read_eeprom(5);
i=read_eeprom(6);
SubeIntLSB=i*256+read_eeprom(7);
i=read_eeprom(;
OnOffMSB=i*256+read_eeprom(9);
i=read_eeprom(10);
OnOffLSB=i*256+read_eeprom(11);
i=read_eeprom(12);
P1MSB=i*256+read_eeprom(13);
i=read_eeprom(14);
P1LSB=i*256+read_eeprom(15);
i=read_eeprom(16);
P2MSB=i*256+read_eeprom(17);
i=read_eeprom(18);
P2LSB=i*256+read_eeprom(19);
}
/*************************************************************************/
/* Se ha capturado una pulsación del mando. Actuamos en consecuencia */
/*************************************************************************/
void ProcesaTecla ()
{
if (Lectura1==BajaIntMSB & Lectura2==BajaIntLSB) // Ha pulsado la tecla ARRIBA
{
Intensidad=Intensidad-2; // acortamos la variable intensidad para que ilumine más
if (Intensidad<LimiteInf) // y si ha llegado al límite inferior, no se baja más
Intensidad=LimiteInf;
}
if (Lectura1==SubeIntMSB & Lectura2==SubeIntLSB) // Ha pulsado la tecla ABAJO
{
Intensidad=Intensidad+2; // alejamos la variable intensidad para que ilumine menos
if (Intensidad>LimiteSup) // y si ha llegado al límite superior, no se baja más
Intensidad=LimiteSup;
}
if (Lectura1==OnOffMSB & Lectura2==OnOffLSB & Antirrebotes>LimiteAntirrebotes) // Ha pulsado la tecla OnOff
if (Intensidad<((LimiteSup-LimiteInf)/2+LimiteInf)) // si está por debajo de la media
Intensidad=LimiteSup; // enciendo
else
Intensidad=LimiteInf; // en caso contrario, apago
// printf ("%lu / %lu: %u
",Lectura1,Lectura2,Intensidad);
}
/****************************************************************************/
/* Captura las pulsaciones de un mando y las almacena en EEPROM */
/* El proceso de grabación es el siguiente: */
/* - las teclas a almacenar serán, en este orden: ARRIBA,ABAJO,ONOFF,P1 y P2*/
/* para cada tecla, la secuencia será: */
/* 1- hay un parpadeo del led rojo de 200ms */
/* 2- se lee la tecla y parpadea rojo 100ms */
/* 3- se lee de nuevo y se compara con la anterior. */
/* 4- Si Ok parpadeo de 200ms y siguiente tecla */
/* 5- Si no Ok hay 5 parpadeos de 100 ms y vuelta a 2 */
/****************************************************************************/
void AlmacenaTecla()
{
LED_VERDE=0;
if (EstadoProceso%2==1) // impar
{
// Captura de la tecla
CapturaTemporal1=Lectura1;
CapturaTemporal2=Lectura2;
// Parpadeo del Led Rojo
LED_ROJO=1;
Delay_Ms(PausaCorta);
LED_ROJO=0;
EstadoProceso++;
// break;
}
else // par
{
// comprobación de la tecla
if (CapturaTemporal1==Lectura1 & CapturaTemporal2==Lectura2)
{ // comprobación OK
Direccion=EstadoProceso*2-4;
write_eeprom(Direccion,Lectura1/256);
write_eeprom(Direccion+1,Lectura1%256);
write_eeprom(Direccion+2,Lectura2/256);
write_eeprom(Direccion+3,Lectura2%256);
EstadoProceso++;
LED_ROJO=1;
Delay_Ms(PausaMedia);
LED_ROJO=0;
}
else
{ // comprobación fallida
for (i=0;i<5; i++)
{
LED_ROJO=1;
Delay_Ms(PausaCorta);
LED_ROJO=0;
Delay_Ms(PausaCorta);
}
EstadoProceso--;
CapturaTemporal1=0;
CapturaTemporal2=0;
}
}
if (EstadoProceso==11) // ya se han capturado las cinco teclas
{
// leemos los nuevos valores de la eeprom y cambiamos a modo ejecución
LeeCodigosMando();
Modo=ModoEjecucion;
EstadoProceso=0;
LED_ROJO=0;
LED_VERDE=1;
Delay_MS(PausaMedia); // antirrebotes
LED_VERDE=0;
}
}
/****************************************************************************/
/* En la interrupción del Timer se ejecuta el núcleo principal del programa */
/* Se ha establecido un ciclo de repetición que es adecuado para el dimmer */
/* y 8 veces más rápido que la frecuencia de pulsos del mando */
/* De esta manera, cada vez que se ejecuta la interrupción del Timer */
/* se procesa el Dimmer, pero sólo una de cada 8 veces se procesa el mando */
/****************************************************************************/
#INT_TIMER0
void tempo()
{
set_timer0(Periodo);
PasosDimmer++;
if (PasosDimmer==Intensidad & Modo==ModoEjecucion) // cuando se ha llegado a la altura del semiciclo deseada
TRIAC=0; // se enciende el triac
if (!Recibiendo) // cuenta los ciclos en pausa para evitar autorrepetición
if (Antirrebotes<2000) // la variable Antirrebotes se pone a 0 tras una pulsación del mando
Antirrebotes++;
if (MANDO==0 & !Recibiendo) // se detecta pulsación en el mando si la señal baja a 0
{
Recibiendo=1; // comienzo de la recepción de una pulsación
Pasos=0;
LED_VERDE=1;
};
if (Recibiendo==1 & (par%RelacionMandoDimmer)==0) // mientras Recibiendo sea 1, se está leyendo el mando
{
if (Pasos<16) // se usan dos word de 16 bits cada una
Lectura1=Lectura1*2+MANDO;
else
Lectura2=Lectura2*2+MANDO;
Pasos=Pasos+1;
if (Pasos==32) // fin de la captura
{
// el ruido suele ser un pulso que baja a 0 y luego permanece a 1 durante todo el tiempo
// por tanto, se detecta como una cadena con esta forma 01111...1111
if ((Lectura1!=0xEFFF & Lectura2!=0xFFFF) & (Lectura1!=0 & Lectura2!=0)) // con esto evitamos la mayoría de los ruidos
{
if (Modo==ModoEjecucion)
ProcesaTecla ();
else
{
AlmacenaTecla();
Delay_Ms(PausaMedia);
}
}
Recibiendo=2; // fin de lectura de la pulsación
Lectura1=0;
Lectura2=0;
Pasos=0;
Antirrebotes=0;
LED_VERDE=0;
}
};
if (Recibiendo>1 & (par%RelacionMandoDimmer)==0)
{
// puede que algunos mandos envíen más pulsos que los capturados,
// por lo que hacemos una pausa tras la captura
Recibiendo++;
if (Recibiendo>=PausaTrasEnvio)
Recibiendo=0;
};
if (!PULSADOR) // Se ha pulsado la tecla
{
if (Modo==ModoEjecucion)
{
Modo=ModoProgramacion;
EstadoProceso=1;
LED_ROJO=1;
Delay_MS(PausaMedia); // antirrebotes
LED_ROJO=0;
Recibiendo=0;
}
else
{
Modo=ModoEjecucion;
EstadoProceso=0;
LED_ROJO=0;
LED_VERDE=1;
Delay_MS(PausaMedia); // antirrebotes
LED_VERDE=0;
}
}
if (UltimoEstadoInterruptor!=INTERRUPTOR_PARED) // se ha pulsado el interruptor de la pared
{
// eso tiene el mismo efecto que la tecla OnOff
Lectura1=OnOffMSB;
Lectura2=OnOffLSB;
ProcesaTecla();
UltimoEstadoInterruptor!=INTERRUPTOR_PARED;
}
par++;
TRIAC=1; // cortamos la señal que se envía al TRIAC
// ya que permanecerá encendido hasta el próximo cruce por 0
}
/****************************************************************************/
/* El ciclo del TRIAC comienza de nuevo con cada cruce por 0 */
/* por ello en la interrupción externa se pone a 0 la cuenta de PasosDimmer */
/* y se cambia la detección de flanco de la entrada */
/****************************************************************************/
#INT_EXT
void CrucePor0()
{
PasosDimmer=0;
if (j==0){
j=1;
ext_int_edge(H_TO_L); // Cambio la detección del flanco, para que la proxima sea de bajada
}
else {
j=0;
ext_int_edge(L_TO_H); // La próxima interrupción será de subida
}
}
/****************************************************************************/
/* En el main lo único que hay es la inicialización */
/****************************************************************************/
void main()
{
set_tris_B(0b00001101);
set_tris_A(0b00011000);
ANSEL=0;
OPTIONREG=OPTIONREG & 0x7F; // activa las pullups internas
LeeCodigosMando();
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_2);
enable_interrupts(INT_TIMER0);
enable_interrupts(INT_EXT);
ext_int_edge(L_TO_H);
enable_interrupts(GLOBAL);
set_timer0(Periodo);
Intensidad=LimiteSup;
Modo=ModoEjecucion;
LED_VERDE=0;
LED_ROJO=0;
UltimoEstadoInterruptor=INTERRUPTOR_PARED;
while(1);
}
mi unico problema es que al parecer esta en C alguien podria dar una manito al cambio a ASM .. es el unico q entiendo mejor