;**********************************************************************
|
; Controllo Relay - Versione telecomando *
|
;**********************************************************************
|
; *
|
; Filename: P16F684_Telec_ac.asm *
|
; Date: *
|
; File Version: 1.00 *
|
; *
|
; Author: InTeAS WebMaster *
|
; Company: https://www.inteas.it *
|
; *
|
; *
|
;**********************************************************************
|
; *
|
; Files Required: P16F684.INC *
|
; *
|
;**********************************************************************
|
;
|
list p=16f684 ; list directive to define processor
|
#include <P16F684.inc> ; processor specific variable definitions
|
__CONFIG _CP_OFF & _CPD_OFF & _BOD_OFF & _PWRTE_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_ON & _FCMEN_OFF & _IESO_OFF
|
;
|
; '__CONFIG' directive is used to embed configuration word within .asm file.
|
; The lables following the directive are located in the respective .inc file.
|
; See respective data sheet for additional information on configuration word.
|
;
|
;***** EEPROM MAP
|
;
|
; 00-5D Sequenza contatori durata tasto di comando
|
; 5E-FE Non usati
|
; FF Stato del Relay (OFF=0, ON=1)
|
;
|
;
|
;***** LOCAL VARIABLE DEFINITIONS
|
;
|
; 0x20 - 0x7F: Bank 0
|
;
|
VALFL EQU 0x20
|
PCOUNT1 EQU 0x21
|
;
|
; 0x22 - 0x7F: Sequenza Comando
|
;
|
; 0xA0 - 0xBF: Bank 1
|
;
|
COUNT1 EQU 0xBF
|
COUNT2 EQU 0xBE
|
ITERAZ EQU 0xBD
|
BYTVAL EQU 0xBC
|
CONFR EQU 0xBB
|
;
|
;**********************************************************************
|
; PROGRAM AREA
|
;**********************************************************************
|
;
|
ORG 0x000 ; processor reset vector
|
goto INIT ; go to beginning of program
|
;
|
ORG 0x004 ; interrupt vector location
|
goto INTERRUPT
|
;
|
INIT:
|
;
|
; OPTION Register, on reset all bits = 1
|
;
|
; bit 7 (NOT_RAPU) Weak Pull-Ups (Enabled=0)
|
; bit 6 (INTEDG) Interrupt Edge Select on RA2(Falling Edge=0)
|
; bit 5 (T0CS) Timer0 Source Selection:
|
; 1= T0CKI Transition (default)
|
; 0= Internal Instruction (CLKOUT)
|
; bit 4 (T0SE) Timer0 Source Edge Selection: 1 = H-to-L (default), 0= L-to-H
|
; bit 3 (PSA) Prescaler Assignment: 1= to WDT (default), 0= to Timer0
|
; bits 2:0 (PS2,PS1,PS0) Prescaler Rate Selection: 1:128 default
|
movlw b'00011111' ; T0CS= 0 : Internal Timer0
|
bsf STATUS,RP0 ; Bank 1
|
movwf OPTION_REG
|
;
|
; INTCON: INTERRUPT CONTROL REGISTER
|
;
|
; bit 7 (GIE) Global Interrupt Enable bit (Enabled=1)
|
; bit 6 (PEIE) Peripheral Interrupt Enable bit (Disabled=0)
|
; bit 5 (T0IE) Timer0 Overflow Interrupt Enable bit (Disabled=0)
|
; bit 4 (INTE) RA2/INT External Interrupt Enable bit (Disabled=0)
|
; bit 3 (RAIE) PORTA Change Interrupt Enable bit (Disabled=0)
|
; bit 2 (T0IF) Timer0 Overflow Interrupt Flag bit (not used)
|
; bit 1 (INTF) RA2/INT External Interrupt Flag bit (used:Active on 1)
|
; bit 0 (RAIF) PORTA Change Interrupt Flag bit (not used)
|
movlw b'10000000'
|
movwf INTCON
|
;
|
; I/O Summary
|
;
|
; PORTA,5 INPUT (pin 2) : NC
|
; PORTA,4 INPUT (pin 3) : NC
|
; PORTA,3 INPUT (pin 4) : NC
|
; PORTA,2 INPUT (pin 11) : Infra Red Interrupt (attivo su 0)
|
; PORTA,1 INPUT (pin 12) : NC
|
; PORTA,0 INPUT (pin 13) : Programming Input (attivo su 0)
|
;
|
; PORTC,5 OUTPUT (pin 5) : Power Supply Control (attivo su 0)
|
; PORTC,4 INPUT (pin 6) : NC
|
; PORTC,3 INPUT (pin 7) : AC Signal
|
; PORTC,2 OUTPUT (pin 8) : Program Led (attivo su 1)
|
; PORTC,1 INPUT (pin 9) : NC
|
; PORTC,0 INPUT (pin 10) : NC
|
;
|
; *******************************
|
; Set of the PORTA I/O (bit 5:0)
|
; *******************************
|
;
|
bcf STATUS,RP0 ; Bank 0
|
movlw h'07' ; Set RA<2:0> and RC<4,1:0> to digital I/O
|
movwf CMCON0
|
bsf STATUS,RP0 ; Bank 1
|
clrf ANSEL ; Digital I/O
|
; 1=input 0=output
|
movlw b'11111111'
|
movwf TRISA ; write in TRISA register
|
;
|
; *******************************
|
; Set of the PORTC I/O (bit 5:0)
|
; *******************************
|
;
|
; 1=input 0=output
|
movlw b'11011011'
|
movwf TRISC ; write in TRISC register
|
bcf STATUS,RP0 ; Bank 0
|
bsf PORTC,5 ; inattiva Power Supply
|
bcf PORTC,2 ; spegne Probe Led
|
;
|
btfss PORTA,0 ; salta se non c'è Programming Input
|
goto PROGRAM ; va alla Programming routine
|
;
|
; Va in stand-by
|
;
|
STAND_BY:
|
bsf INTCON,4 ; abilita l'interrupt su RA2
|
sleep
|
|
;
|
;***********************************************
|
; INTERRUPT: routine di interrupt
|
;***********************************************
|
;
|
INTERRUPT:
|
bcf STATUS,RP0 ; Bank 0
|
bcf INTCON,1 ; spegne il flag di interrupt
|
bcf INTCON,4 ; disabilita l'interrupt
|
btfss PORTA,0 ; salta se non c'è Programming Input
|
goto PROGRAM ; va alla Programming routine
|
;
|
; Acquisizione comando
|
;
|
call ACQUISIZIONE
|
;
|
; Verifica di comando completo (FSR=h'80')
|
;
|
btfss FSR,7 ; salta se FSR=80
|
goto STAND_BY; comando incompleto
|
;
|
; Analisi comando
|
;
|
movlw h'22'
|
movwf FSR ; Inizializzazione puntatore sequenza
|
bsf STATUS,RP0 ; Bank 1
|
clrf CONFR ; inizializza a zero flag
|
clrf EEADR ; Inizializzazione puntatore EEPROM
|
CmdAnLoop:
|
call EEREAD ; valore corrente in w
|
subwf INDF,0 ; esegue w = f - w
|
btfsc STATUS,Z ; salta se f diverso da w (Z=0)
|
goto EndCmdAn ; f=w (Z=1)
|
btfsc STATUS,C ; salta se w maggiore di f (C=0)
|
goto PosDiff ; w minore di f
|
; Risultato negativo
|
addlw h'05' ; massima differenza accettabile
|
btfsc STATUS,C ; salta se C=0 cioè diff. NON accettabile
|
goto EndCmdAn ; C=1 differenza accettabile
|
incf CONFR ;
|
goto EndAnalysis
|
; Risultato positivo
|
PosDiff:
|
sublw h'05'
|
btfsc STATUS,C ; salta se C=0 cioè diff. accettabile
|
goto EndCmdAn ; C=1 differenza NON accettabile
|
incf CONFR ;
|
goto EndAnalysis
|
;
|
EndCmdAn:
|
incf EEADR,1
|
incf FSR,1
|
btfss FSR,7 ; salta se FSR=80
|
goto CmdAnLoop
|
;
|
; Fine Analisi
|
;
|
EndAnalysis:
|
btfsc CONFR,0; salta se CONFR=0 (comando valido)
|
goto STAND_BY ; comando NON valido
|
;
|
; Comando valido
|
;
|
movlw h'FF'
|
movwf EEADR
|
call EEREAD ; valore attuale relay in w (0=OFF 1=ON)
|
bcf STATUS,RP0 ; Bank 0
|
movwf VALFL ; salva valore attuale in VALFL
|
;
|
movlw b'00000001'
|
xorwf VALFL,f ; salva lo stato opposto del relay
|
call ACTCNT ; attuazione sul relay del nuovo stato
|
movf VALFL,w
|
bsf STATUS,RP0 ; Bank 1
|
call STATUS_SAVE ; memorizza in EEPROM il nuovo stato
|
bcf STATUS,RP0 ; Bank 0
|
bsf PORTC,2 ; accende Probe Led
|
bsf STATUS,RP0 ; Bank 1
|
call DELAY_MAX
|
bcf STATUS,RP0 ; Bank 0
|
bcf PORTC,2 ; spegne Probe Led
|
bsf STATUS,RP0 ; Bank 1
|
call DELAY_MAX
|
goto STAND_BY
|
;
|
;***********************************************
|
; PROGRAM: routine di programmazione comando
|
;***********************************************
|
;
|
PROGRAM:
|
; Lampeggio d'attesa (16 cicli max,)
|
bsf STATUS,RP0 ; Bank 1
|
movlw h'10'
|
movwf ITERAZ
|
PrgLoop:
|
bcf STATUS,RP0 ; Bank 0
|
bsf PORTC,2 ; accende Probe Led
|
bsf STATUS,RP0 ; Bank 1
|
movlw h'FF'
|
movwf COUNT2
|
PrgDly2:
|
movlw h'FF'
|
movwf COUNT1
|
PrgDly1:
|
bcf STATUS,RP0 ; Bank 0
|
btfss PORTA,2 ; salta se non c'è comando
|
goto COMMAND_ACQ
|
bsf STATUS,RP0 ; Bank 1
|
decfsz COUNT1,1
|
goto PrgDly1
|
decfsz COUNT2,1
|
goto PrgDly2
|
bcf STATUS,RP0 ; Bank 0
|
bcf PORTC,2 ; spegne Probe Led
|
bsf STATUS,RP0 ; Bank 1
|
PrgDly4:
|
movlw h'FF'
|
movwf COUNT1
|
PrgDly3:
|
bcf STATUS,RP0 ; Bank 0
|
btfss PORTA,2 ; salta se non c'è comando
|
goto COMMAND_ACQ
|
bsf STATUS,RP0 ; Bank 1
|
decfsz COUNT1,1
|
goto PrgDly3
|
decfsz COUNT2,1
|
goto PrgDly4
|
decfsz ITERAZ,1
|
goto PrgLoop
|
;
|
; Tempo scaduto
|
;
|
goto STAND_BY
|
;
|
; Acquisizione Comando
|
;
|
COMMAND_ACQ:
|
bcf PORTC,2 ; spegne Probe Led
|
call ACQUISIZIONE
|
;
|
; Verifica di comando completo (FSR=h'80')
|
;
|
btfss FSR,7 ; salta se FSR=80
|
goto PROGRAM; comando incompleto
|
;
|
; Salvataggio comando in EEPROM
|
;
|
bsf STATUS,RP0 ; Bank 1
|
call INTEE_WR
|
;
|
; Memorizzazione stato OFF del relay
|
;
|
movlw h'00'
|
call STATUS_SAVE
|
bcf STATUS,RP0 ; Bank 0
|
clrf VALFL
|
call ACTCNT ; attuazione sul relay dello stato OFF
|
;
|
; Segnalazione avvenuta memorizzazione
|
;
|
|
bsf PORTC,2 ; accende Probe Led
|
bsf STATUS,RP0 ; Bank 1
|
;
|
movlw h'10'
|
call LDELAY
|
;
|
bcf STATUS,RP0 ; Bank 0
|
bcf PORTC,2 ; spegne Probe Led
|
bsf STATUS,RP0 ; Bank 1
|
;
|
movlw h'10'
|
call LDELAY
|
;
|
goto STAND_BY
|
;
|
;
|
;###############################################
|
;# ROUTINES #
|
;###############################################
|
;
|
;
|
;***********************************************
|
; ACQUISIZIONE
|
;***********************************************
|
;
|
ACQUISIZIONE:
|
movlw h'22'
|
movwf FSR ; inizializzazione puntatore sequenza
|
ZeroCount:
|
clrf INDF ; azzera contatore corrente
|
ZeroLoop:
|
call PAUSE
|
btfsc PORTA,2 ; salta se IR = 0
|
goto EndZeroCount
|
incf INDF ; incrementa contatore corrente
|
btfss STATUS,Z ; salta se Z=1 (>255)
|
goto ZeroLoop ; Z=0 (<256)
|
;
|
; Overflow on Zero
|
;
|
ZOLoop:
|
btfss PORTA,2 ; salta se IR = 1
|
goto ZOLoop ; aspetta fino a che IR=0
|
;
|
EndZeroCount:
|
incf FSR,1
|
;
|
OneCount:
|
clrf INDF ; azzera contatore corrente
|
OneLoop:
|
call PAUSE
|
btfss PORTA,2 ; salta se IR = 1
|
goto EndOneCount
|
incf INDF ; incrementa contatore corrente
|
btfss STATUS,Z ; salta se Z=1 (>255)
|
goto OneLoop ; Z=0 (<256)
|
;
|
; Overflow on One
|
;
|
; Se il comando si interrompe a metà, va a 1
|
; per impedire che il software rimanga all'infinit oin loop
|
; va definito un Tempo max. di attesa e poi fine comando
|
;
|
movlw h'FF'
|
movwf COUNT2
|
OODly:
|
movlw h'FF'
|
movwf COUNT1
|
OOLoop:
|
btfss PORTA,2 ; salta se IR = 1
|
goto EndOneCount ; IR=0
|
decfsz COUNT1,1
|
goto OOLoop
|
decfsz COUNT2,1
|
goto OODly
|
;
|
; Comando incompleto: fine prematura
|
;
|
return
|
;
|
EndOneCount:
|
incf FSR,1
|
btfss FSR,7 ; salta se FSR=80
|
goto ZeroCount
|
return
|
;
|
;***********************************************
|
; PAUSE
|
;***********************************************
|
;
|
PAUSE:
|
movlw h'01' ; può essere aumentato
|
; se troppi overflow in sequenza (intervalli lunghi)
|
movwf PCOUNT1
|
Pse1:
|
decfsz PCOUNT1,1
|
goto Pse1
|
return
|
;
|
;***********************************************
|
; DELAY Routine max 196,65 msec, min 0,771 msec
|
;***********************************************
|
;
|
DELAY_MAX:
|
movlw h'FF'
|
DELAY:
|
movwf COUNT2
|
Dly2:
|
movlw h'FF'
|
movwf COUNT1
|
Dly1:
|
decfsz COUNT1,1
|
goto Dly1
|
decfsz COUNT2,1
|
goto Dly2
|
return
|
;
|
;****************************************************
|
; LDELAY Routine lungo ritardo 1 ciclo circa 196 msec; max 49.8 sec circa
|
;****************************************************
|
;
|
LDELAY_STD:
|
movlw h'02'
|
LDELAY:
|
movwf ITERAZ
|
Dly3:
|
call DELAY_MAX
|
decfsz ITERAZ,1
|
goto Dly3
|
return
|
;
|
;*****************
|
; ACTUATOR CONTROL
|
;*****************
|
;
|
ACTCNT:
|
;
|
; Syncronization VALFL=0 Negative Polarity (Status Off)
|
; VALFL=1 Positive Polarity (Status On)
|
;
|
btfsc VALFL,0
|
goto Syncr2
|
; Negative Polarity
|
Syncr1:
|
btfss PORTC,3
|
goto Syncr1 ; waiting for AC=1
|
goto LdPr
|
; Positive Polarity
|
Syncr2:
|
btfsc PORTC,3
|
goto Syncr2 ; waiting for AC=0
|
;
|
; Loading procedure
|
;
|
LdPr:
|
call TRANSDET ; 0-->1
|
call PWSPCNT
|
return
|
;
|
; **********************
|
; Transition Detection
|
; **********************
|
;
|
TRANSDET:
|
btfsc PORTC,3
|
goto Tr10 ; jump if AC Signal=1
|
; AC Signal=0
|
Tr01:
|
btfss PORTC,3
|
goto Tr01 ; waiting for AC=1
|
return
|
Tr10:
|
btfsc PORTC,3
|
goto Tr10 ; waiting for AC=0
|
return
|
;
|
; **************************
|
; Power Supply Control Signal
|
; **************************
|
;
|
PWSPCNT:
|
movlw h'FF'
|
movwf PCOUNT1
|
PDly1:
|
decfsz PCOUNT1
|
goto PDly1
|
;
|
; Spike Emission
|
;
|
bcf PORTC,5 ; Signal Active
|
movlw h'10' ; durata spike
|
movwf PCOUNT1
|
Spk1:
|
decfsz PCOUNT1
|
goto Spk1
|
bsf PORTC,5 ; Signal Inactive
|
return
|
;
|
;******************************************
|
; GESTIONE EEPROM INTERNA (256 BYTE)
|
;******************************************
|
;
|
;******************************************
|
; EEREAD Routine: indirizzo in EEADR
|
;******************************************
|
;
|
EEREAD:
|
bsf EECON1,RD ;EE Read
|
movf EEDAT,W ;risultato in w
|
return
|
;
|
;*************************************************************
|
; EEWRITE Routine: byte in EEDAT, indirizzo in EEADR
|
;*************************************************************
|
;
|
EEWRITE:
|
bsf EECON1,WREN ;Enable write
|
movlw h'55' ;Unlock write
|
movwf EECON2
|
movlw h'AA'
|
movwf EECON2
|
bsf EECON1,WR ;Start the write
|
movlw h'0A' ; 06 è il minimo
|
call DELAY
|
return
|
;
|
;********************************************************************************
|
; INTEE_WR ROUTINE da RAM a EEPROM
|
;********************************************************************************
|
;
|
INTEE_WR:
|
movlw h'22'
|
movwf FSR ; inizializzazione puntatore di sequenza
|
clrf EEADR ; inizializzazione puntatore EEPROM
|
IntEEWrLoop:
|
movf INDF,w
|
movwf EEDAT
|
call EEWRITE
|
incf EEADR,1
|
incf FSR,1
|
btfss FSR,7 ; salta se FSR=80
|
goto IntEEWrLoop
|
return
|
;
|
; ************************************************************
|
; STATUS_SAVE: Memorizzazione in EEPROM; stato del relay in w
|
;*************************************************************
|
;
|
STATUS_SAVE:
|
movwf EEDAT
|
movlw h'FF'
|
movwf EEADR
|
call EEWRITE ; salva lo stato relay in EEPROM
|
return
|
;
|
;******************************************************************************
|
END ; directive 'end of program'
|
;****************************************************************************** |