//////////////////////////////////////////////////////////////////////////////// // // RECEPTOR_GENÉRICO_FLEX.C // // RECEPTOR PARA PT2240B/2262/HT6P20B/HCS200 ...301 (SEM HOPPING CODE) // USANDO PIC 12F675/629 PARA DECODIFICAÇÃO DOS SINAIS // // PODERÁ SER MONTADO EM ATÉ 4 CANAIS DE SAÍDAS DE ACIONAMENTO (3 SAÍDAS NO // HT6P20B E HCS) // // DEVERÁ SER USADO RECEPTOR COMERCIAL NA MESMA FREQUENCIA DO TRANSMISSOR (TX) // // CARACTERISTICAS: FLEXIBILIDADE PARA AS VÁRIAS NECESSIDADES DO HOBISTA, QUE // PODERÃO SER ALTERADAS NAS DEFINIÇÕES DE USUÁRIO ABAIXO, COMO: // 1) ESCOLHA DE COMPILAÇÃO PARA PIC12F675 OU 12F629 // 2) ESCOLHA DE PROTOCOLO A OPERAR (PARA CI PT2262,2240B,HT6P20B E HCS NO TX) // 3) ESCOLHA INDIVIDUAL POR PINO, PARA MODO RETENÇÃO OU PULSO // 4) ESCOLHA INDIVIDUAL POR PINO, PARA SAIDA NORMAL OU INVERTIDA // 5) POSSIBILIDADE DE INTERCAMBIAR OS PINOS DE SAÍDA (EM DEFINIÇÕES GERAIS) // 6) ESCOLHA DE APRENDIZADO ÚNICO DE TODOS OS BOTÕES OU INDIVIDUAL // 7) OPÇÃO PARA FUNCIONAR COM PIC SEM O BYTE DE CALIBRAÇÃO (APAGADO) // // ALTERE CONFORME A NECESSIDADE E RECOMPILE COM COMPILADOR CCS C. // AUTOR: CLÁUDIO LÁRIOS // INÍCIO: 05/11/2013 TÉRMINO: 10/11/2013 // LIBERADO USO PARA FINS DIDÁTICOS APENAS. // SUJEITO A BUGS AINDA NÃO OBSERVADOS EM USO. MONTAGEM REALIZADA E TESTADA // SOMENTE EM PLACA DE PROTOBOARD. //============================================================================== // DEFINIÇOES DO USUÁRIO //============================================================================== //ESCOLHA DO MICROCONTROLADOR: // Para usar o PIC12F675, descomente o abaixo e comente para usar o 12F629 #define F675 //============================================================================== //ESCOLHA O TIPO DE CI DO TRANSMISSOR: // O transmissor poderá ter qualquer dos integrados abaixo: // PT2240B / PT2262 / HT6P20B //Descomente o CHIP desejado e comente os outros usando '//'. // #DEFINE CHIP_PT2240B #DEFINE CHIP_PT2262 // #DEFINE CHIP_HT6P20B // #DEFINE CHIP_HCS // OBS: Apenas um poderá estar descomentado, sob pena de não funcionar. //============================================================================== // MODO DE APRENDIZADO DOS BOTÕES DE UM CONTROLE #define aprender_todos_botoes //Deixe descomentado o acima p/ aprender todos os botões em uma única operação. // Exemplo: // 1) Aperte botão 'learn'. // 2) Aperte qualquer botão. Todos serão aprendidos pelo receptor e aceitos. // Este modo deverá ser usado quando temos apenas um receptor. // Se for comentado este define, terá que aprender cada botão e também as suas // possíveis combinações de acionamento (16 possibildades). // EX: // 1) Aperte botão 'learn'. // 2) Aperte um botão. Somente este será aprendido e aceito. // 3) Aperte outros para também aprende-los. // 4) para funcionar dois ou mais botões juntos, terá que aprender com eles // apertados juntos, em cada possível combinação. // Esta opção deverá ser usada quando um controle remoto deverá funcionar com // vários receptores diferentes, sendo cada tecla para um receptor. //============================================================================== // NOTA IMPORTANTE PARA OBTER O FUNCIONAMENTO DESTE SOFTWARE //============================================================================== // ATENÇÃO: CERTIFIQUE DE EXISTIR O BYTE DE CALIBRAÇÃO NO ENDEREÇO 3FFH DA FLASH // Caso tenha sido apagado acidentalmente, ao ligar, após a programação do pic, // NÃO funcionará. O programa irá fazer um 'call'para buscar o byte de calibra- // ção, mas não encontrará a instrução de retorno 'retlw xx'. Isto fará o progra- // se perder, resetando continuamente. // COMO SABER SE TENHO O BYTE DE CALIBRAÇÃO NO PIC? // LENDO A FLASH COM UM PROGRAMADOR, DEVERÁ SER ENCONTRADO NO ENDEREÇO 0X3FF, UM // VALOR COMEÇANDO COM 34 SEGUIDO DE 2 DIGITOS. EX. 3480. (34=RETLW 80= LITERAL // QUE SERÁ RETORNADO EM 'W' PARA CARGA DO REGISTRADOR '0SCCAL'. // #define PERDI_BYTE_CALIBRACAO //Descomente o acima se você tem um pic que foi apagado o byte de calibração. //Será substituido por valor padrão que permita a operação do circuito. // //============================================================================== // MODO DE OPERAÇÃO DAS SAIDAS QUANDO SE ACIONA A RESPECTIVA TECLA NO TX // Poderá optar antes da compilação, se a saída será 'pulso' ou 'retençao' // Comente para 'modo pulso' e descomente para 'modo retenção'. // #define s0_ret // #define s1_ret // #define s2_ret // #define s3_ret //============================================================================== // MODO DE OPERAÇÃO DAS SAIDAS INVERTIDAS OU MODO NORMAL // Poderá optar antes da compilação, se a saída será 'pulso' ou 'retençao' com // saídas invertidas ('1' já ao ligar o vcc e atua com '0' ao apertar botão do // TX) ou modo normal ('0' já ao ligar vcc e atua com '1' ao apertar botão do // tx). // Comente para 'modo normal' e descomente para 'modo invertido'. // #define s0_invertido // #define s1_invertido // #define s2_invertido // #define s3_invertido //============================================================================== //////////////////////////////////////////////////////////////////////////////// // // FIM DAS DEFINIÇÕES DO USUÁRIO // // Obs. Não altere o programa a seguir, a menos que saiba o que está fazendo // //////////////////////////////////////////////////////////////////////////////// //============================================================================== // // DEFINIÇÕES GERAIS DO PROGRAMA // //============================================================================== #ifdef F675 #include <12F675.h> // includes #else #include <12F629.h> // includes #endif #ignore_warnings 203 //desconsidera mensagem de 'condition always true' #fuses INTRC_IO,NOWDT,NOPROTECT, NOMCLR ,BROWNOUT, PUT // palavra configuração #use delay(clock=4000000) // clock para 4 mhz #use fast_io(A) // sentido das portas feita pelo programador #ifdef PERDI_BYTE_CALIBRACAO // calibração do oscilador interno do pic #ROM 0X3FF = {0X34FC}//máxima freq= 0x34fc ;média=0x3480; minima=0x3400 #endif #BYTE GPIO = 0X05 //============================================================================== //ALTERE ABAIXO, OS PINOS QUE DESEJAR COMO SAÍDAS (SOMENTE GPIO 1,2,4,5) // COM CUIDADO: #bit _s0 = 0X05.5 // PINO 2 #bit _s1 = 0X05.1 // PINO 6 #bit _s2 = 0X05.2 // PINO 5 #bit _s3 = 0X05.4 // PINO 3 //------------------------------------------------------------------------------ // TRIS-STATE GPIO 543210 PINOS 2,3,4,5,6,7 -> '0' SAÍDA E '1' ENTRADA byte const TRIS_LED = 0b001000; //SENTIDO DAS PORTAS P/ ACENDER LED 'LEARN' byte const TRIS_BOT = 0b001001; //SENTIDO DAS PORTAS P/ LER BOTÃO 'LEARN' //============================================================================== #define RFIN PIN_A3 // não alterar aqui #define BOT PIN_A0 // IDEM #define LED PIN_A0 // IDEM #byte TRISIO = 0X85 #byte timer0 = 0x01 // declara timer 0 #byte flags = 0x5e //registrador para flags gerais #byte flags1 = 0x5f //registrador para flags gerais #define flag_h flags,0 // flags usados na recepção do sinal pt2240b #define flag_l flags,1 #define flag_first flags,2 #define flag_aux flags,3 #define flag_rok flags,4 #define flag_acao flags,5 #define flag_gr flags,6 #define flag_s0 flags1,0 //flags para modo retenção apenas #define flag_s1 flags1,1 #define flag_s2 flags1,2 #define flag_s3 flags1,3 #ifdef CHIP_HT6P20B byte const tmax_ht= 80; //somente ht6p20b #endif #ifndef CHIP_HCS #ifndef CHIP_HT6P20B byte const tmax= 80;// somente pt2240b e pt2262 #endif #endif #ifdef CHIP_HCS byte const tmax_hcs= 40;//somente hcs (intervalo apos cabeçalho) #endif byte const TMAX_LED=0x03; //20SEG DE LED LEARN ACESO APÓS APERTAR BOTÃO 'LEARN' byte const TMAX_SAIDAS_LIGADAS = 0x10;//tempo q/ saida fica ligada (modo pulso) int8 hc,lc,qb,tm1,tm2,tm3,tl1,tl2,botoes, snumber_lsb ; // variaveis globais #locate hc=0x49 #locate lc=0x4a #locate qb=0x4b #locate snumber_lsb =0x3f //antes do buffer (somente hcs) int8 buffer[3]= {0,0,0}; int8 sbuffer[3]={0,0,0}; #locate buffer=0x40 #locate sbuffer=0x43 //============================================================================== // DECLARAÇÃO DE PROTÓTIPOS DE SUBROTINAS E FUNÇÕES //============================================================================== void init_ram(); void acionar (); int procura_3bytes_gravados_eeprom (int *pont); void reset_rx (); int procura_3bytes_livres_eeprom () ; void grava_3bytes_eeprom (int address_init, int *pont); void apagar_eeprom(); //============================================================================== //////////////////////////////////////////////////////////////////////////////// // // SUBROTINAS E FUNÇÕES DO PROGRAMA // //////////////////////////////////////////////////////////////////////////////// //============================================================================== //============================================================================== // INICIALIZAÇÃO DE REGISTRADORES NA RAM //============================================================================== void init_ram(){ TRISIO= TRIS_BOT;// ajusta trisio #IFDEF chip_hcs qb=64; #ELSE qb=24; #ENDIF lc,hc,tm1,tm2,tm3,flags,flags1=0; #ifdef s0_invertido _s0=1; #else _s0=0; #endif #ifdef s1_invertido _s1=1; #else _s1=0; #endif #ifdef s2_invertido _s2=1; #else _s2=0; #endif #ifdef s3_invertido _s3=1; #else _s3=0; #endif } //============================================================================== // APAGAR EEPROM //============================================================================== void apagar_eeprom(){ int a; for(a=0;a<128;a++) write_eeprom(a,0xff); } //============================================================================== // GRAVAR TX RECEBIDO NA EEPROM //============================================================================== void grava_3bytes_eeprom (int address_init, int *pont){ // onde int_addres = endereço inicial da gravação // *pont = endereço inicial da informação (3 bytes seguidos) int a; for (a=0;a<3;++a){ // copia buffer para sbuffer write_eeprom(address_init + a,*pont++); // ++pont; } } //============================================================================== // LOCALIZA ENDEREÇO LIVRE NA EEPROM PARA GRAVAR TX RECEBIDO //============================================================================== int procura_3bytes_livres_eeprom () { int a; for (a=0;a<128;a+=3){ // copia buffer para sbuffer if(read_eeprom(a)==0xff){ if(read_eeprom(a+1)==0xff) { if(read_eeprom(a+2)==0xff) { return a; } } } } return 0xff; } //============================================================================== // LOCALIZA TX RECEBIDO SE GRAVADO NA EEPROM //============================================================================== int procura_3bytes_gravados_eeprom (int *pont) { int a; for (a=0;a<123;a+=3){ // copia buffer para sbuffer if(read_eeprom(a)==*pont){ if(read_eeprom(a+1)==*(pont +1)) { if(read_eeprom(a+2)==*(pont+2)) { return 0xaa; } } } } return 0xff; } //============================================================================== // TX RECEBIDO ENCONTRADO NA EEPROM - ACIONAR SAÍDAS //============================================================================== void acionar (){ if(procura_3bytes_gravados_eeprom(&buffer[0])==0xaa){ tl1,tl2=0;//reseta contadores de tempo de saidas ligadas bit_clear(flag_gr);//reseta flag de gravação //============================================================================== // ACIONAMENTOS DE SAÍDAS EM MODO PROGRAMADO PARA 'PULSO' - HCS //============================================================================== #ifdef CHIP_HCS #ifndef s2_ret #ifdef s2_invertido if((bit_test(botoes,6))&&(bit_test(botoes,5))) _s2=0; else _s2=1;// pino 5 '0' #else if((bit_test(botoes,6))&&(bit_test(botoes,5))) _s2=1; else _s2=0;// pino 5 '1' #endif #endif #ifndef s0_ret #ifdef s0_invertido if((bit_test(botoes,6))&&(!bit_test(botoes,5)))_s0=0; else _s0=1;// pino 2 '0' #else if((bit_test(botoes,6))&&(!bit_test(botoes,5)))_s0=1; else _s0=0;// pino 2 '1' #endif #endif #ifndef s1_ret #ifdef s1_invertido if((bit_test(botoes,5))&&(!bit_test(botoes,6)))_s1=0; else _s1=1;// pino 3 '0' #else if((bit_test(botoes,5))&&(!bit_test(botoes,6)))_s1=1; else _s1=0;// pino 3 '1' #endif #endif #endif //============================================================================== // ACIONAMENTOS DE SAÍDAS EM MODO PROGRAMADO PARA 'PULSO' - HT6P20B //============================================================================== #ifdef CHIP_HT6P20B #ifndef s2_ret #ifdef s2_invertido if((bit_test(botoes,6))&&(bit_test(botoes,7))) _s2=0; else _s2=1;// pino 5 '0' #else if((bit_test(botoes,6))&&(bit_test(botoes,7))) _s2=1; else _s2=0;// pino 5 '1' #endif #endif #ifndef s0_ret #ifdef s0_invertido if((bit_test(botoes,7))&&(!bit_test(botoes,6)))_s0=0; else _s0=1;// pino 2 '0' #else if((bit_test(botoes,7))&&(!bit_test(botoes,6)))_s0=1; else _s0=0;// pino 2 '1' #endif #endif #ifndef s1_ret #ifdef s1_invertido if((bit_test(botoes,6))&&(!bit_test(botoes,7)))_s1=0; else _s1=1;// pino 3 '0' #else if((bit_test(botoes,6))&&(!bit_test(botoes,7)))_s1=1; else _s1=0;// pino 3 '1' #endif #endif #endif //============================================================================== // ACIONAMENTOS DE SAÍDAS EM MODO PROGRAMADO PARA 'PULSO' - PT2240B //============================================================================== #ifdef CHIP_PT2240B #ifndef s3_ret #ifdef s3_invertido if(bit_test(botoes,6)) _s3=0; else _s3=1;//liga led pino 6 #else if(bit_test(botoes,6)) _s3=1; else _s3=0;//liga led pino 6 #endif #endif #ifndef s2_ret #ifdef s2_invertido if(bit_test(botoes,5)) _s2=0; else _s2=1;//liga led pino 5 #else if(bit_test(botoes,5)) _s2=1; else _s2=0;//liga led pino 5 #endif #endif #ifndef s1_ret #ifdef s1_invertido if(bit_test(botoes,4)) _s1=0; else _s1=1;//liga led pino 3 #else if(bit_test(botoes,4)) _s1=1; else _s1=0;//liga led pino 3 #endif #endif #ifndef s0_ret #ifdef s0_invertido if(bit_test(botoes,7)) _s0=0; else _s0=1;//liga led pino 2 #else if(bit_test(botoes,7)) _s0=1; else _s0=0;//liga led pino 2 #endif #endif #endif //============================================================================== // ACIONAMENTOS DE SAÍDAS EM MODO PROGRAMADO PARA 'PULSO' - PT2262 //============================================================================== #ifdef CHIP_PT2262 #ifndef s3_ret #ifdef s3_invertido if(bit_test(botoes,5)) _s3=0; else _s3=1;//liga led pino 6 #else if(bit_test(botoes,5)) _s3=1; else _s3=0;//liga led pino 6 #endif #endif #ifndef s2_ret #ifdef s2_invertido if(bit_test(botoes,3)) _s2=0; else _s2=1;//liga led pino 5 #else if(bit_test(botoes,3)) _s2=1; else _s2=0;//liga led pino 5 #endif #endif #ifndef s1_ret #ifdef s1_invertido if(bit_test(botoes,1)) _s1=0; else _s1=1;//liga led pino 3 #else if(bit_test(botoes,1)) _s1=1; else _s1=0;//liga led pino 3 #endif #endif #ifndef s0_ret #ifdef s0_invertido if(bit_test(botoes,7)) _s0=0; else _s0=1;//liga led pino 2 #else if(bit_test(botoes,7)) _s0=1; else _s0=0;//liga led pino 2 #endif #endif #endif //============================================================================== // CHIP HCS - ACIONAMENTOS DE SAÍDAS EM MODO PROGRAMADO PARA 'RETENÇÃO' //============================================================================== #ifdef CHIP_HCS #ifdef s2_ret if(!bit_test(flag_s2)){ if((bit_test(botoes,6))&&(bit_test(botoes,5))){ _s2=!_s2;bit_set(flag_s2);} } #endif #ifdef s0_ret if(!bit_test(flag_s0)){if((bit_test(botoes,6))&&(!bit_test(botoes,5))){ _s0=!_s0; bit_set(flag_s0); } } #endif #ifdef s1_ret if(!bit_test(flag_s1)){if((bit_test(botoes,5))&&(!bit_test(botoes,6))) { _s1=!_s1; bit_set(flag_s1); } } #endif #ENDIF //============================================================================== // CHIP HT6P20B - ACIONAMENTOS DE SAÍDAS EM MODO PROGRAMADO PARA 'RETENÇÃO' //============================================================================== #ifdef CHIP_HT6P20B #ifdef s2_ret if(!bit_test(flag_s2)){ if((bit_test(botoes,6))&&(bit_test(botoes,7))){ _s2=!_s2;bit_set(flag_s2);} } #endif #ifdef s0_ret if(!bit_test(flag_s0)){if((bit_test(botoes,7))&&(!bit_test(botoes,6))){ _s0=!_s0; bit_set(flag_s0); } } #endif #ifdef s1_ret if(!bit_test(flag_s1)){if((bit_test(botoes,6))&&(!bit_test(botoes,7))) { _s1=!_s1; bit_set(flag_s1); } } #endif #ENDIF //============================================================================== // CHIP PT 2240B - ACIONAMENTOS DE SAÍDAS EM MODO PROGRAMADO PARA 'RETENÇÃO' //============================================================================== #ifdef CHIP_PT2240B #ifdef s0_ret if(!bit_test(flag_s0)){ if(bit_test(botoes,7)){ _s0=!_s0; bit_set(flag_s0); } } #endif #ifdef s1_ret if(!bit_test(flag_s1)){ if(bit_test(botoes,4)){ _s1=!_s1; bit_set(flag_s1); } } #endif #ifdef s2_ret if(!bit_test(flag_s2)){ if(bit_test(botoes,5)){ _s2=!_s2; bit_set(flag_s2); } } #endif #ifdef s3_ret if(!bit_test(flag_s3)){ if(bit_test(botoes,6)){ _s3=!_s3; bit_set(flag_s3); } } #endif #endif //============================================================================== // CHIP PT2262 - ACIONAMENTOS DE SAÍDAS EM MODO PROGRAMADO PARA 'RETENÇÃO' //============================================================================== #ifdef CHIP_PT2262 #ifdef s0_ret if(!bit_test(flag_s0)){ if(bit_test(botoes,7)){ _s0=!_s0; bit_set(flag_s0); } } #endif #ifdef s1_ret if(!bit_test(flag_s1)){ if(bit_test(botoes,1)){ _s1=!_s1; bit_set(flag_s1); } } #endif #ifdef s2_ret if(!bit_test(flag_s2)){ if(bit_test(botoes,3)){ _s2=!_s2; bit_set(flag_s2); } } #endif #ifdef s3_ret if(!bit_test(flag_s3)){ if(bit_test(botoes,5)){ _s3=!_s3; bit_set(flag_s3); } } #endif #endif botoes=0; } //============================================================================== // TESTA SE DEVE GRAVAR O TX DESCONHECIDO QUE FOI RECEBIDO //============================================================================== else { if(bit_test(flag_gr)){ //gravar na eeprom o buffer grava_3bytes_eeprom (procura_3bytes_livres_eeprom(),buffer); bit_clear(flag_gr); } } bit_clear(flag_first); bit_clear(flag_rok); //libera nova recepção } //============================================================================== // ZERA REGISTRADORES APÓS RECEPÇÃO DE UM BIT //============================================================================== void reset_rx (){ lc=0; hc=0; bit_clear(flag_h); bit_clear(flag_l);} //============================================================================== //////////////////////////////////////////////////////////////////////////////// // ROTINA DE INTERRUPÇÃO DO TIMER 0 //////////////////////////////////////////////////////////////////////////////// //============================================================================== #int_rtcc VOID isr(){ timer0= 155; // recarga para nova interrupção com 100 useg //============================================================================== // TEMPO QUE FICA ACESO O LED LEARN AO APERTAR BOTÃO LEARN //============================================================================== if(++tm1==0){ if(++tm2==0) { if(++tm3>=TMAX_LED) bit_clear(flag_gr); } } //============================================================================== // TEMPO PARA DESLIGAMENTO DAS SAIDAS //============================================================================== if(++tl1==0){ if(++tl2==TMAX_SAIDAS_LIGADAS) { tl2=0; tl1=0; //============================================================================== // DESLIGA AS SAÍDAS EM MODO PROGRAMADO PARA 'PULSO' //============================================================================== #ifndef s0_ret #ifdef s0_invertido _s0=1; #else _s0=0; //desliga s0 em modo pulso #endif #endif #ifndef s1_ret #ifdef s1_invertido _s1=1; #else _s1=0; //desliga s0 em modo pulso #endif #endif #ifndef s2_ret #ifdef s2_invertido _s2=1; #else _s2=0; //desliga s0 em modo pulso #endif #endif #ifndef s3_ret #ifdef s3_invertido _s3=1; #else _s3=0; //desliga s0 em modo pulso #endif #endif //============================================================================== // RESETA OS FLAGS DAS SAÍDAS EM MODO PROGRAMADO PARA 'RETENÇÃO' //============================================================================== #ifdef s0_ret bit_clear(flag_s0); //desliga flag_s0 em modo retenção #endif #ifdef s1_ret bit_clear(flag_s1);//desliga flag_s1 em modo retenção #endif #ifdef s2_ret bit_clear(flag_s2);//desliga flag_s2 em modo retenção #endif #ifdef s3_ret bit_clear(flag_s3);//desliga flag_s3 em modo retenção #endif } } //============================================================================== //////////////////////////////////////////////////////////////////////////////// // // ROTINA DE RECEPÇÃO DOS 24 BITS DA TRANSMISSÃO P/PT2240B/2262 // //////////////////////////////////////////////////////////////////////////////// //============================================================================== #IFNDEF CHIP_HT6P20B // SOMENTE PARA PT2240B E PT2262 #IFNDEF CHIP_HCS //============================================================================== // SINCRONIZANDO O FRAME PARA RECEPÇÃO //============================================================================== if (!bit_test(flag_rok) && input(RFIN)){ if (lc>=tmax){ qb=24; reset_rx (); } //============================================================================== // RECEBENDO UM BIT //============================================================================== if(bit_test(flag_h) && bit_test(flag_l) ){ shift_right(&buffer[0],3,(hc>lc)) ;//captura um bit recebido reset_rx (); //zera lc/hc/flag_h if (--qb==0){ qb=24; botoes=buffer[2];//salva botões #ifdef aprender_todos_botoes #ifdef CHIP_PT2240B buffer[2]&=0x0f; //apaga botões no buffer #endif #ifdef CHIP_PT2262 buffer[2]&=0x00; //apaga botões no buffer #endif #endif bit_set(flag_rok); // há uma recepção no buffer } } } //============================================================================== // CAPTURANDO INTERVALOS '0' E '1' NOS REGISTRADORES 'LC' E 'HC' //============================================================================== if (!bit_test(flag_rok)){ if (input(RFIN)) { if (bit_test (flag_h)) bit_set (flag_l); //seta flag_l se flag_h for '1' if(++hc==0) --hc; // mantém o máximo em 0xff } else { bit_set (flag_h); // seta flag_h if(++lc==0) --lc; // mantém o máximo em 0xff } } #ENDIF #ENDIF //============================================================================== //////////////////////////////////////////////////////////////////////////////// // // ROTINA DE RECEPÇÃO DOS 24 BITS DA TRANSMISSÃO P/HT6P20B // //////////////////////////////////////////////////////////////////////////////// //============================================================================== #IFDEF CHIP_HT6P20B if(input(RFIN)&&(!bit_test(flag_rok))){ bit_set(flag_h); if(++hc==0) --hc; } else { if(!bit_test(flag_h)){if(++lc==0) --lc;} // incrementa lc e limita 0xff else { if(lc>tmax_ht) {reset_rx (); qb=24;} else { shift_right(&buffer[0],3,(lc>hc)) ; if (--qb==0){ qb=24; botoes=buffer[2];//salva botões #ifdef aprender_todos_botoes buffer[2]&=0x3f; //apaga botões no buffer #endif bit_set(flag_rok);} // há uma recepção no buffer reset_rx(); } } } #endif //============================================================================== //////////////////////////////////////////////////////////////////////////////// // // ROTINA DE RECEPÇÃO DOS 64 BITS DA TRANSMISSÃO P/HCS (SEM HOPCODE, FIXO) // // OBS. FAZENDO USO DE APENAS 24 BITS (4 BITS=BOTÕES + 20 DO SERIAL NUMBER ), // DESPREZANDO O BYTE MEDIANO DO SERIAL P/ DAR COMPATIBILIDADE C/ APRENDIZADO // DE TX NA MEMÓRIA, USANDO 3 BYTES POR CONTROLE. // //////////////////////////////////////////////////////////////////////////////// //============================================================================== #IFDEF CHIP_HCS if(!input(RFIN)&&(!bit_test(flag_rok))){ if(++lc==0) --lc; bit_set(flag_l);} else { if(!bit_test(flag_l)){if(++hc==0) --hc; } // incrementa hc e limita 0xff else { if(lc>tmax_hcs) {qb=64; reset_rx();} else { shift_right(&snumber_lsb,4,(lc>hc)) ;//desloca snumber+buffer if (--qb==0){ qb=64; botoes=buffer[2];//salva botões buffer[0]=snumber_lsb;//usa lsb do serial no lugar do byte mediano #ifdef aprender_todos_botoes buffer[2]&=0x0f; //apaga botões no buffer #endif bit_set(flag_rok);} // há uma recepção no buffer reset_rx(); } } } #endif }//void isr() //============================================================================== // FIM DA ROTINA DE INTERRUPÇÃO DO TIMER 0 //============================================================================== //============================================================================== /////////////////////////////////////////////////////////////////////////////// // ROTINA PRINCIPAL //////////////////////////////////////////////////////////////////////////////// //============================================================================== //============================================================================== // INICIALIZAÇÃO DE PORTAS E REGISTRADORES //============================================================================== void main(){ #ifdef F675 setup_adc_ports(no_analogs); //somente pic12f675 SETUP_ADC(ADC_OFF); //DESLIGA ADC #endif setup_comparator(nc_nc_nc_nc); // desliga comparadores setup_counters (RTCC_INTERNAL,RTCC_DIV_1); //timer 0 interno /1 ENABLE_INTERRUPTS(int_timer0); // liga interrupção por overflow do timer0 enable_interrupts(GLOBAL); // liga interrupção geral PORT_A_PULLUPS(TRUE); init_ram(); //============================================================================== // LOOP PRINCIPAL DE REPETIÇÃO //============================================================================== while (TRUE) { int a; //============================================================================== // TESTA BOTÃO 'LEARN' SE FOI APERTADO //============================================================================== TRISIO= TRIS_BOT;// ajusta trisio if(!input(bot)){ tm3=0; //reseta contadores de apagamento do led 'learn' em tm2=0; //modo de gravação de tx tm1=0; bit_set(flag_gr); //aciona flag p/ gravação (irá ligar led 'learn') for (a=0;!input(bot);a++) { delay_ms(50); if(a==100){ apagar_eeprom(); bit_clear(flag_gr); TRISIO= TRIS_LED;// ajusta trisio=saida p/ led for(a=0;a<5;a++){ output_low(LED); delay_ms(250); output_high(LED); delay_ms(250); } break; } } } //============================================================================= // liga led 'learn' em modo de gravação de TX //============================================================================= TRISIO= TRIS_LED;// ajusta trisio=saida p/ led if(bit_test(flag_gr)){ output_low(LED); } else { output_high(LED); } //============================================================================== // DESCARTA RECEPÇÃO FFFFFF //============================================================================== if(!bit_test(flag_first) && bit_test(flag_rok)){ if ((buffer[0]==0xff)&& (buffer[1]==0xff)&&(buffer[2]==0xff)){ bit_clear(flag_rok); } } //============================================================================== // DESCARTA RECEPÇÃO 000000 //============================================================================== if(!bit_test(flag_first) && bit_test(flag_rok)){ if ((buffer[0]==0x00)&& (buffer[1]==0x00)&&(buffer[2]==0x00)){ bit_clear(flag_rok); } } //============================================================================== // SALVA A PRIMEIRA RECEPÇÃO PARA PODER COMPARAR COM A PRÓXIMA //============================================================================== if(!bit_test(flag_first) && bit_test(flag_rok)){ for(a=0;a<3;a++) sbuffer[a]=buffer[a]; //salva a primeira recepção for(a=0;a<3;a++) buffer[a]=0; //zera buffer bit_set(flag_first); //seta bit de primeira recepção bit_clear(flag_rok); } //============================================================================== // COMPARA A PRIMEIRA RECEPÇÃO COM A SEGUNDA - ACIONA SE IGUAIS //============================================================================== if(bit_test(flag_first) && bit_test(flag_rok) ){ for(a=0;(a<3) && (sbuffer[a]==buffer[a]);a++){ if (a==2) { acionar(); //temos uma recepção correta, acionar saídas } } bit_clear(flag_first); //zera bit de primeira recepção bit_clear(flag_rok); } //============================================================================== // fim da rotina de recepção pt2240b //============================================================================== }// while (TRUE) }//void main()