'******************************************************************************* '* Programa PORTAOAUTO_ARNEBASIC2K.BAS '* Desenvolvido por Márcio José Soares - 16/08/2010 '* Arne Basic 2k '* '* Obs.: Este programa foi desenvolvido para controle de um motor AC ou DC '* aplicado a um portão automático para garagens residênciais ou outras. '* '* S1 - chave final de curso "portão aberto" '* S2 - chave final de curso "portão fechado" '* RL1 - relé para ligar motor '* RL2 - relé para inverter motor '* LP1, LP2 - Saída coletor aberto para lâmpadas 12V - aviso "entrada/saída veículo" '* LPH - saída coletor aberto para alerta - "problemas na garagem" (opcional) '* '* O motor utilizado pode ser AC ou DC. Veja no artigo o esquema de ligação '* dos mesmos '* '******************************************************************************* '******************************************************************************* 'Configs necessários ao microcontrolador $crystal = 10000000 $regfile = "attiny2313.dat" 'Config para pinos de I/O Config Portb = &B00001111 'msb - entrada; lsb - saída Config Portd = &B11100010 'PD0, PD2, PD3 e PD4 - entrada, o resto saída '******************************************************************************* 'Variáveis globais Dim EstadoP As Byte 'sentido atual do portão - 1 aberto, 2 fechado Dim Cod As Byte 'aviso de código válido Dim Motor As Byte 'aviso de motor ligado/desligado Dim avisoH as Byte 'aviso para entrada/saída de veículos Dim aux1 as byte 'vars para uso na decodificação dos códigos enviados Dim aux2 as byte Dim aux3 as byte '******************************************************************************* 'Configura Timer 1 - usado para lâmpadas de aviso 'Timer, modo assincrono, preescale 128 'clock externo 10 MHz '10MHz / 1024(prescale) = 9.7656kHz => T = 1 / 9.7656kHz = 102.4 us '102.4 us x 48828 = 500 ms 'entao haverá uma int a cada 500 ms Config Timer1 = Timer , Prescale = 1024 Timer1 = 65535 - 4882 'valor inicial da contagem '******************************************************************************* 'Configura INT0 - int acontece na rampa de subida (0 -> 1) Config Int0 = RISING '******************************************************************************* 'Liga pinos de I/O's a "nomes" mais fáceis ao entendimento humano ;-) LP1 Alias Portb.0 'saída para LP1 - aviso saída de veículo LP2 Alias Portb.1 'saída para LP2 - aviso saída de veículo LPH Alias Portb.2 'saída para LPH - aviso problemas na garagem CD1 Alias Pinb.4 'código recebido - bit 0 CD2 Alias PINB.5 ' bit 1 CD3 Alias PINB.6 ' bit 2 CD4 Alias PINB.7 ' bit 3 VT Alias Pind.2 'código válido presente S1 Alias Pind.3 'pino de entrada para chave 1 - fim de curso aberto S2 Alias Pind.4 'pino de entrada para chave 2 - fim de curso fechado RL1 Alias Portd.5 'rele liga motor RL2 Alias Portd.6 'rele inverte motor '******************************************************************************* 'Declaração das subrotinas Declare Sub Check_cod() 'verifica código Declare Sub On_motor() 'liga motor de acordo com sentido Declare Sub Off_motor() 'desliga motor '******************************************************************************* 'Início do programa 'zera vars EstadoP = 0 'portão ??? 'zera vars Cod = 0 'nenhum código válido Motor = 0 'motor desligado avisoH = 0 'aviso desativado Cod = 0 'desliga pinos de I/O Reset LP1 'LP1 desligada Reset LP2 'LP2 desligada Reset LPh 'LPH desligada Reset RL1 'rele 1 desligado Reset RL2 'rele 2 desligado Waitms 500 'espera iniciar 'verifica se portão está aberto ou fechado If S1 = 0 Then 'se final de curso aberto, indica portão aberto EstadoP = 1 End If If S2 = 0 Then 'se final de curso fechado, indica portão fechado EstadoP = 2 End If 'portão não está nem aberto, nem fechado... inicia como fechado! If EstadoP = 0 Then 'portão não esta aberto nem fechado, EstadoP = 1 'seta portao como aberto set RL2 'configura sentido no rele 2 waitms 50 'espera relé 2 set LP2 'liga lâmpada 2 reset LP1 'desliga lâmpada 1 avisoH = 1 'habilita aviso motor = 1 'avisa motor ligado End If On TIMER1 MyISR_T1 'quando houver uma interrupção do timer 1, desvia para MyISR_T1 On Int0 MyISR_INT0 'quando houver uma interrupção externa em INT0, desvia para MyISR_INT0 Enable Int0 'habilita interrupção INT0 em PD2 Enable TIMER1 'habilita timer 1 Enable INTERRUPTS 'habilita interrupções '******************************************************************************* 'Laço principal 'Algumas operções do programa operam via interrupções (timer1 e int0) Do if EstadoP = 1 and motor = 1 then 'se portão estava aberto e motor ligado, fecha set RL1 'ativa portão if S2 = 0 then 'chave fim de curso? reset LP1 'desliga lâmpadas reset LP2 Reset LPH 'sem problemas na garagem avisoH = 0 'desabilita aviso call off_motor() 'desliga motor motor = 0 end if else if EstadoP = 2 and motor = 1 then 'se portão estava fechado, e motor ligado, abre set RL1 'ativa portão if S1 = 0 then 'chave fim de curso? call off_motor() 'desliga motor motor = 0 end if end if end If Loop '******************************************************************************* 'Label para tratamento da interrupção do Timer1 'Usado para alerta de saída/entrada de veículo 'Tempo de acionamento em 500ms MyISR_T1: if avisoH = 1 then 'se aviso está autorizado toggle LP1 'troca estado da Lâmpada 1 e 2 toggle LP2 end if Timer1 = 65535 - 4882 'retorna valor para nova contagem return 'gera um RETI return 'gera um RET '******************************************************************************* 'Label para tratamento da interrupção externa em PD2 'Usado na recepção de código válido MyISR_INT0: call Check_cod() 'verifica código If Cod = 1 Then 'código normal válido motor = 1 'aviso de motor ligado Reset LPH 'sem problemas na garagem ElseIf Cod = 2 then 'código que indica problemas válido motor = 1 'aviso de motor ligado Set LPH 'avisa problema End If if Motor = 1 then 'se código ok call off_motor() 'pára motor If EstadoP = 1 Then 'portão aberto, então fecha EstadoP = 2 'configura novo sentido Reset RL2 'configura sentido no rele 2 Else If EstadoP = 2 Then 'portão fechado EstadoP = 1 'configura novo sentido Set RL2 'configura sentido no rele 2 end if End If Waitms 50 'espera bobina RL2 ligar/desligar set LP2 'liga lâmpada 2 reset LP1 'desliga lâmpada 1 avisoH = 1 'habilita aviso end if return 'gera RETI return 'gera RET '******************************************************************************* 'Subrotina para verificar código Sub Check_cod() As Byte waitms 50 'espera até codigo estabilizar aux1 = 0 'zera var Restore Cods 'aponta para ponteiro dos dados Read aux2 'Lê código normal Read aux3 'Lê código help if CD1 = 1 then 'verifica estado dos bits e configura var de acordo aux1 = aux1 + 1 end if if CD2 = 1 then aux1 = aux1 + 2 end if if CD3 = 1 then aux1 = aux1 + 4 end if if CD4 = 1 then aux1 = aux1 + 8 end if if aux1 = aux2 then 'se igual, avisa que tudo está normal cod = 1 else if aux1 = aux3 then 'se igual, avisa que há problemas cod = 2 else cod = 0 'se diferente de ambos, ignora end if end if End Sub '******************************************************************************* 'Subrotina para desligar motor Sub Off_motor() Reset RL1 'desliga motor Reset RL2 'desliga RL2 Cod = 0 'limpa último código válido wait 1 'espera para evitar tranco no motor End Sub '******************************************************************************* end 'fim do programa '******************************************************************************* 'Códigos armazenados na FLASH (área de programa) do microcontrolador 'Troque os valores de acordo com o desejado 'Veja o artigo para saber mais sobre os valores possíveis Cods: Data 9 , 5