/************************************************************************** ; PLACA PARA CONTROLE REMOTO DE PORTÃO PARA 2 MOTORES INDEPENDENTES ; VERSÃO 'C' PARA COMPILADOR 'PCW C COMPILER IDE' ; ; COMO TRANSMISSOR, USAR QUALQUER TRANSMISSOR ('CHAVEIRINHO') ; COM INTEGRADO HT6P20B. ; PARA DECODIFICAR UTILIZA UM PIC 12F675. ; UTILIZA 4 RELES PARA CONTROLAR 2 MOTORES LIGADO A 2 PORTÕES POR CREMALHEIRA. ; TRABALHA COM 4 FINS DE CURSO TIPO RED SWITCH (COM IMÃS) LIGADOS A M1, M2, ; M3 E M4 , VIA RESISTORES DE PROTEÇÃO. ; APÓS ACIONAR RELE DO MOTOR, TEM UMA TEMPORIZAÇÃO MAXIMA (TMAX) DE MODO ; QUE ESTE FICA LIGADO POR APENAS 35 SEG., SENDO REGULAVEL NO PROGRAMA, ; ALTERANDO A CONSTANTE 'C_TEMPO_SAIDA_ON '. ; OBS. NÃO USA INTERRUPÇÕES. ; ; CLAUDIO LÁRIOS INICIO: 21-05-2013 TERMINO:22-05-2013 ; ;************************************************************************** ; ; GRAVAR CONTROLE: APERTE UM DOS BOTÕES DO C. REMOTO E MANTENHA APERTADO. ; APERTE TAMBÉM O BOTÃO 'LEARN_A' (CANAL A) OU 'LEARN_B'(CANAL B) NA PLACA E ; SOLTE-O EM MENOS DE 2 SEGUNDOS. DEVERÁ ACIONAR UMA SAIDA DE RELE PARA ; O MOTOR , SE FOI BEM SUCEDIDO O APRENDIZADO. O LED VERMELHO PISCARÁ 1 ; VEZ, PARA INDICAR ISTO. REPITA ISTO COM TODOS OS BOTÕES DO CONTROLE REMO ; TO , UM POR VEZ. ; APAGAR TODOS OS CONTROLES DA MEMÓRIA: APERTAR BOTÃO 'LEARN_A' PARA CANAL ; 'A' E 'LEARN_B' PARA CANAL 'B', NA PLACA E MANTENHA PRESSIONADO POR MAIS DE 10 SEGUNDOS. O LED VERMELHO PISCARÁ 3 VEZES , INDICANDO O PLENO APAGAMENTO DE TODOS OS CONTROLES DA MEMÓRIA. ;******************************************************************************/ //Escolha o modelo de microcontrolador (comente o não usado) #include <12f675.h> //#include <12f629.h> //****************************************************************************** //PALAVRA DE CONFIGURAÇÃO #fuses INTRC_IO,NOWDT,NOPROTECT, NOMCLR #use delay(clock=4000000) //DEFINIÇÕES DE PINOS E CONSTANTES #define LRN PIN_A0 //PINO 7 IN LEARN BOTTON #DEFINE LED PIN_A0 //PINO 7 OUT LED (MESMO PINO DO ACIMA) #DEFINE C_Z1 220 // TEMPO PARA APAGAR EEPROM #DEFINE TMAX 40 // CONTAGEM MÁXIMA PARA VALOR ACEITAVEL #DEFINE C_TEMPO_BOTAO_AP 10 //TEMPO DE ESPERA QUANDO SOLTA BOTÃO DO TX #DEFINE C_TEMPO_SAIDA_ON 3 //PARA 30 SEGUNDOS MÁXIMO LIGADO #BYTE TRISIO = 0X85 #BYTE FLAGS = 0X5F // FIXA POSIÇÃO PARA REGISTRADOR #BYTE FLAGS1 = 0X5E // FIXA POSIÇÃO PARA REGISTRADOR #BIT FLAG = FLAGS.0 // FLAG DE SITUAÇÃO #BIT FLAG1 = FLAGS.1 // FLAG DE NOVA LEITURA #BIT FLAGGR = FLAGS.2 // FLAG DE 'LEARN' APRENDER #BIT FLAG_A = FLAGS.3 // FLAG AUX #BIT FLAG_AE = FLAGS.4 // FLAG AUX #BIT FLAG_BAA = FLAGS.5 // FLAG DE BOTÃO AINDA APERTADO #BIT F_A = FLAGS.6 // FLAG DE CANAL 'A' #BIT C1 = FLAGS.7 // BIT AUXILIAR #BIT FLAG_BAP = FLAGS1.0 // FLAG DE 'PAROU DE APERTAR BOTÃO' #BIT FLAG_TA = FLAGS1.1 // FLAG REED ACIONADO #BIT FLAG_TB = FLAGS1.2 // FLAG REED ACIONADO #BIT TRIS_LRN = 0X85.0 // TRISIO.0 #BIT LEARN = 0X05.0 // LRN #BYTE GPIO = 0X05 #BIT M4 = 0X5.5 //PINO 2 #BIT M3 = 0X5.4 //PINO 3 #BIT M2 = 0X5.2 //PINO 5 #BIT M1 = 0X5.1 //PINO 6 #BIT SIN = 0X5.3 //PINO 4 #BIT TRIS_M4 = 0X85.5 //PINO 2 #BIT TRIS_M3 = 0X85.4 //PINO 3 #BIT TRIS_M2 = 0X85.2 //PINO 5 #BIT TRIS_M1 = 0X85.1 //PINO 6 // VARIAVÉIS GLOBAIS INT RES0,RES1,RES2,RES3,RES0A,RES1A,RES2A,QB,LC,HC,Z1,Z0,Y1,Y0,W0,W1,W2,U0,U1,U2; // MODO DE COMPILAÇÃO #use fast_io(a) //modo rápido de entrada e saída //DECLARAÇÃO DE SUBROTINAS VOID CONFIG_INIT (VOID); VOID TESTA_APAGAR_MEM (VOID); VOID SHIFT_RESULT (INT A, INT1 B); VOID APAGAR (VOID); VOID REG_INIT(VOID); VOID _ERRO (VOID); VOID ERASE_3BYTES (INT I); VOID ESCREVE_RES210 (INT I); INT RECEIVE (VOID); VOID TESTA_FIM_DE_CURSOS (VOID); INT TESTA_LRN (VOID); VOID TESTA_APAGAR_MEM (VOID); VOID PISCA (INT I); VOID APAGAR (VOID); INT GRAVAR_CONTROLE (VOID); INT TESTA_LRN (VOID); VOID SALVA_PRIMEIRA_REC (VOID); VOID GRAVAR_TX_NA_MEM (VOID); VOID RECEBE_TX (VOID); VOID TESTA_TX_ON (VOID); VOID TESTA_TEMPO_MAX_LIG (VOID); VOID TEMPORIZAR_SAIDA_A (VOID); VOID TEMPORIZAR_SAIDA_B (VOID); /******************************************************************************* * SUBROTINAS *******************************************************************************/ /******************************************************************************* CONFIG_INIT *******************************************************************************/ VOID CONFIG_INIT (VOID) { //configurações TRISIO=0b00001001;// Define entradas e saídas setup_comparator (nc_nc_nc_nc); //desliga comparadores #if __device__ == 675 // P/ 12f675, desliga o conversor AD setup_adc_ports(no_analogs); //todas as portas são digitais #endif GPIO=0; //DESLIGAS SAÍDAS FLAGS=0; FLAGS1=0; REG_INIT(); } /******************************************************************************* SHIFT_RESULT *******************************************************************************/ //ROTINA PARA DESLOCAR RES3,RES2,RES1,RES0 PARA DIREITA // SENDO A= NUMERO DE VEZES QUE SERÁ DESLOCADO E B= O BIT // A SER INTRODUZIDO NO DESLOCAMENTO (0 OU 1) VOID SHIFT_RESULT (INT A, INT1 B) { WHILE (A){ SHIFT_RIGHT (&RES0,4,B); A--;} } /******************************************************************************* REG_INIT *******************************************************************************/ VOID REG_INIT(VOID) { QB=28; LC=0; HC=0; FLAG=0;} /******************************************************************************* ERRO *******************************************************************************/ VOID _ERRO (VOID) { RES2A=0; RES1A=0; RES0A=0; REG_INIT(); } /******************************************************************************* ERASE_3BYTES /******************************************************************************/ VOID ERASE_3BYTES (INT I) { write_eeprom (I, 0XFF); write_eeprom (--I, 0XFF); //(I-1, 0XFF) write_eeprom (--I, 0XFF);} /******************************************************************************* ESCREVE 3 BYTES NA EEPROM /******************************************************************************/ VOID ESCREVE_RES210 (INT I) { write_eeprom (I, RES0); // estava I, RES2); write_eeprom (--I, RES1); // estava I, RES1); write_eeprom (--I, RES2); // estava I, RES0); } /******************************************************************************* SALVA_PRIMEIRA_REC *******************************************************************************/ VOID SALVA_PRIMEIRA_REC (VOID) { FLAG1=1; RES2A=RES2; // SALVA A PRIMEIRA RECEPÇÃO RES1A=RES1; RES0A=RES0; REG_INIT(); } /******************************************************************************* RECEIVE *******************************************************************************/ INT RECEIVE (VOID) { IF (SIN) //ENTRADA SIN = 1 { FLAG=1; HC++; IF (!HC) HC--; } ELSE { IF (FLAG) //ENTRADA SIN = 0 { IF (LC>TMAX) { REG_INIT(); RETURN 0 ; } ELSE { IF (LC>HC) //ESTAVA LC0X7F) { IF (F_A) //ESTAVA (F_A==1) ERASE_3BYTES (I); } ELSE { IF (!F_A) //ESTAVA (F_A==0) ERASE_3BYTES (I); } } } /******************************************************************************* GRAVAR_TX _NA_MEM *******************************************************************************/ VOID GRAVAR_TX_NA_MEM (VOID) { INT TEMP,I; IF (FLAGGR) //TESTA FLAG 'LEARN' { I= GRAVAR_CONTROLE (); // GRAVA NA MEMÓRIA RES2..0 , CONFORME O FLAG_A IF (I) {PISCA(1);} //OK, GRAVOU ,PISCA 1 VEZ O LED LEARN ELSE { PISCA (10);} //MEMÓRIA CHEIA, NÃO GRAVOU, PISCA 10 VEZES TEMP=1; WHILE (TEMP) { TEMP= TESTA_LRN(); //ESPERA SOLTAR BOTÃO 'LEARN_A'OU 'B' } } } /******************************************************************************* BUSCA POSIÇÃO LIVRE PARA GRAVAR CONTROLE /******************************************************************************/ INT GRAVAR_CONTROLE (VOID) { INT VALUE,I; FOR (I=0X7D;I!=0XFF;I=I-3) { VALUE = read_eeprom (I); {IF (VALUE==0XFF) VALUE = read_eeprom (I-1); {IF (VALUE==0XFF) VALUE = read_eeprom (I-2); {IF (VALUE==0XFF) {IF (F_A)// ESTAVA IF (F_A==1) { RES2= RES2|0X80; //SETA RES2.7 ESCREVE_RES210 (I); F_A=0; FLAGGR=0; RETURN (1); } ELSE { RES2=RES2 & 0X7F; //ZERA RES2.7 ESCREVE_RES210 (I); FLAGGR=0; RETURN (1); } } } } } { continue;} } RETURN (0); } /******************************************************************************* RECEBE_TX /******************************************************************************/ VOID RECEBE_TX (VOID) { INT TEMP,I; //variavéis locais TEMP= RECEIVE(); //rotina de recepção de sinal rf IF (TEMP) { IF (!FLAG1) SALVA_PRIMEIRA_REC(); ELSE { IF (!((RES2^0XFF) | (RES1^0XFF) | (RES0^0XFF)))//ELIMINA FALSA RECEPÇÃO { _ERRO();} ELSE { // SEGUNDA RECEPÇÃO, COMPARA COM A PRIMEIRA FLAG1=0; //RESETA FLAG1 IF (((RES2^RES2A) | (RES1^RES1A) | (RES0^RES0A))) {_ERRO();} // RECEPÇÃO 1 DIFERENTE DA 2; ERRO DE RECEPÇÃO //RECEPÇÃO 1 IGUAL RECEPÇÃO 2; SEGUE COMPARANDO RES2...0 COM EEPROM IF (RES2>0X7F) {FLAG_A=1; RES2= RES2 & 0X7F;} //APAGA RES2.7 ELSE {FLAG_A=0;} FOR (I=0X7D; I>0; I=I-3) {RES3= READ_EEPROM(I-2); RES3= RES3 & 0X7F; //APAGA RES2.7 IF ((RES0^READ_EEPROM(I))|(RES1^READ_EEPROM(I-1))|(RES2^RES3)) { CONTINUE; } // PASSA PARA O PRÓXIMO CICLO DO LAÇO 'FOR' ELSE { // ENDEREÇO ENCONTRADO ; ACIONAR // QUAL CANAL ACIONAR ? RES3= READ_EEPROM(I-2); //TESTA RES2.7, CANAL A=1 / B='0' IF (RES3 > 0x7F) FLAG_A=1; ELSE FLAG_A=0; IF (!FLAG_BAP) { { IF (RES2 & 0X40) //SE RES2.6 = '1' ACIONA M1 OU M2 DO 'A' {M1=FLAG_TA; //ACIONA M1 OU M2 M2=!M1; FLAG_TA=M2; TEMPORIZAR_SAIDA_A();} ELSE {M3=FLAG_TB; //ACIONA M3 OU M4 M4=!M3; FLAG_TB=M4; TEMPORIZAR_SAIDA_B();} } FLAG_BAP=1; } Y1= C_TEMPO_BOTAO_AP; FLAGGR=0; //APAGA REG_INIT(); BREAK; //ENCERRA LOOP 'FOR' ANTECIPADO } } GRAVAR_TX_NA_MEM (); } } } } /******************************************************************************* TESTA_TEX_ON *******************************************************************************/ VOID TESTA_TX_ON (VOID) { IF (!--Y0) //DECREMENTA,SE '0' { IF(!--Y1) //DECREMENTA,SE '0' { Y1= C_TEMPO_BOTAO_AP; FLAG_BAP=0;} } } /******************************************************************************* TESTA_TEMPO_MAX_LIG *******************************************************************************/ VOID TESTA_TEMPO_MAX_LIG (VOID) { IF (!--W0) //DECREMENTA,SE '0' { IF(!--W1) //DECREMENTA,SE '0' { IF (!--W2) {M1=0; M2=0; W0=1; W1=1; W2=1;} } } IF (!--U0) //DECREMENTA,SE '0' { IF(!--U1) //DECREMENTA,SE '0' { IF(!--U2) {M3=0; M4=0; U0=1; U1=1; U2=1;} } } } /******************************************************************************* TEMPORIZAR_SAIDA_A *******************************************************************************/ VOID TEMPORIZAR_SAIDA_A (VOID) { W0= 0; W1= 0; W2= C_TEMPO_SAIDA_ON; } /******************************************************************************* TEMPORIZAR_SAIDA_B *******************************************************************************/ VOID TEMPORIZAR_SAIDA_B (VOID) { U0= 0; U1= 0; U2= C_TEMPO_SAIDA_ON; } /******************************************************************************* FIM DAS SUBROTINAS *******************************************************************************/ /******************************************************************************* MAIN - ROTINA PRINCIPAL /******************************************************************************/ void main() { CONFIG_INIT(); // CONFIGURAÇÕES INICIAIS DE PORTAS // loop principal continuo WHILE(TRUE) { TESTA_TEMPO_MAX_LIG(); //tESTA TEMPO PARA DESLIGAR SAÍDAS ACIONADAS TESTA_TX_ON(); //TESTA SE AINDA TEM UMA TRANSMISSÃO DO TX TESTA_FIM_DE_CURSOS(); //TESTA OS FINS DE CURSO (REED SWITCH) TESTA_APAGAR_MEM(); //TESTA SE DEVE FAZER APAGAMENTO DA MEMÓRIA RECEBE_TX(); //RECEBE TX E ACIONA SAIDAS } }