📄 windowlift20.asm
字号:
;**********************************************************************
; *
; Filename: WindowLift *
; Date: 05.01.28 *
; File Version: 1.0 *
; *
; Author: Chuck Simmers *
; Company: Microchip Technology, Inc. *
; *
;**********************************************************************
; *
; Files required: *
; *
;**********************************************************************
; *
; Notes: *
; *
;**********************************************************************
list p=16F688 ; list directive to define processor
#include <P16F688.inc> ; processor specific variable definitions
LIST
; P16F688.INC Standard Header File, Version 1.00 Microchip Technology, Inc.
LIST
errorlevel -302,-305 ; suppress message 302 from list file
__CONFIG _CP_OFF & _WDT_OFF & _MCLRE_OFF & _PWRTE_OFF &_BOD_OFF & _INTRC_OSC_NOCLKOUT
;***** VARIABLE DEFINITIONS
; ***********************************************************************
; * Register definitions ; ***********************************************************************
cblock 0x20
DLY_CNT0
DLY_CNT1
CNT_LW
CNT_HI
ADDRESS
w_temp ; variable used for context saving
status_temp ; variable used for context saving
PENUM
ButtonImage
WindowLiftStatus
endc
#Include <UART688i.inc>
VoltageThreshold equ LOW(.12500 /(.50000 / .256)) ; set for 1.25V
; ***********************************************************************
; * Other definitions *
; ***********************************************************************
#define PA_ADC0CON B'00000001' ; channel 0, A/DC ON, Left-justified, ADCS2=0
#define PA_ADC1CON B'00000101' ; channel 1, A/DC ON, Left-justified, ADCS2=0
; PORTA definitions
#define AnalogIn0 PORTA,0
#define AnalogIn1 PORTA,1
; #define Button2 PORTA,2
; #define Button1 PORTA,3
#define UpButton PORTA,4
#define DwnButton PORTA,5
#define TRISAset b'11111011'
#define ButtonMask b'00110000'
; PORTC definitions
#define UpDirection PORTC,0
#define DwnDirection PORTC,1
#define LINCS PORTC,2
;no connect #define LINfault PORTC,3
#define LINTX PORTC,4
#define LINRX PORTC,5
#define TRISCset b'11100000'
;**********************************************************************
; Function ID bit definitions
; 7 6 5 4 3 2 1 0
; | | | | |_____|___ Data Type Tag Code
; | | |_|___________ Number of bytes in the data frame 0=2 bytes, 1=2 bytes, 2=4 bytes, 3=8 bytes
; |_|_______________ Not Used
#define Slave0out 0x05 ;
;
; First Data Byte : Operation Code
; 7 6 5 4 3 2 1 0
; | |___ 1 = Window DOWN
; |_____ 1 = Window UP
;
; *********************************************************************
; ***********************************************************************
; * Program Start *
; ***********************************************************************
ORG 0x00
goto main
; ***********************************************************************
; * Interrupt Service *
; ***********************************************************************
ORG 0x04 ; interrupt vector location
; **** Save status and wreg ****
movwf w_temp ; save off current W register contents
movf STATUS,w ; move status register into W register
bcf STATUS,RP0 ; ensure file register bank set to 0
bcf STATUS,RP1 ; ensure file register bank set to 0
movwf status_temp ; save off contents of STATUS register
bsf STATUS,RP0
btfss PIE1,RCIE ; is EAUSART receive interrupt enabled?
goto CheckXmitFlag ; no, go check transmit
bcf STATUS,RP0
btfsc PIR1,RCIF ; did a receive inerrupt happen?
goto LINHandler ; yes, handle it
bsf STATUS,RP0
CheckXmitFlag
btfss PIE1,TXIE ; is transmit interrupt enabled?
goto CheckTMR0Flag ; no, return from interrupt
bcf STATUS,RP0
btfsc PIR1,TXIF ; yes,
goto PutDATAbyte ; send a byte of data
CheckTMR0Flag
btfss INTCON,T0IF
goto RestoreStatus
; **** INCREASE 16 BIT CLOCK TIMER *******
INCF CNT_LW,1 ; INCREASE 16 COUNTER
BTFSC STATUS,Z ; INCR MS BYTE IF ZERO (OVERFLOW)
INCF CNT_HI,1
bcf INTCON,T0IF
RestoreStatus
; **** Restore status and wreg ****
CLRWDT ; RESET WATCHDOG TIMER
bcf STATUS,RP0 ; ensure file register bank set to 0
movf status_temp,w ; retrieve copy of STATUS register
movwf STATUS ; restore pre-isr STATUS register contents
swapf w_temp,f
swapf w_temp,w ; restore pre-isr W register contents
retfie ; return from interrupt
; ***********************************************************************
; * Initialization *
; ***********************************************************************
main
clrf ADDRESS
movlw B'00000111' ; comparators off
movwf CMCON0
bsf STATUS,RP0
movlw B'00000000' ; Set calibration of internal oscillator
movwf OSCTUNE ; update register with factory cal value
movlw B'00000010' ; AN1 - analogue channel
movwf ANSEL
movlw B'00010000' ; ADC conversion clock - Fosc/8
movwf ADCON1
movlw B'00010011' ; pullups=ON, int=falling edge, T0=timer, T0prescale=1:256
; @4MHz, T0 is clocked every 64us and rollover every 16.384mS
movwf OPTION_REG
movlw TRISAset
movwf TRISA ;
movlw TRISCset ;
movwf TRISC ;
bcf STATUS,RP0
movlw B'11111111'
movwf PORTA
movlw b'11111100'
movwf PORTC ; all outputs off, LINRX and TX high
movlw PA_ADC1CON ; Setup A/D Converter
movwf ADCON0
bsf ADCON0,GO ; start conversion
clrf CNT_LW ; clear long timer
clrf CNT_HI
clrf WindowLiftStatus
call SetupLINUSART
clrf ID_TEMP
clrf DATAPOINTER
; ***********************************************************************
; * Main routine. *
; ***********************************************************************
MainRoutine
bsf INTCON,T0IE
bsf INTCON,PEIE
bsf INTCON,GIE
MainLoop
CheckSeekID
movfw MESSAGE_COUNTER ; if message counter not equal to 12
xorlw .12
btfss STATUS, Z
goto Main_0 ; then, message reception not complete, return
movfw ID_TEMP ; copy ID_TEMP into w-register
andlw 0x3F
xorlw Slave0out ; check if this ID is acceptable
btfss STATUS, Z ; check zero flag
goto Main_0 ; no, not correct ID
movfw DATAPOINTER ; get first data byte
xorlw 0x02 ; is this a DOWN command
btfsc STATUS,Z
goto BusWindowUp
movfw DATAPOINTER ; get first data byte
xorlw 0x01 ; is this a UP command
btfsc STATUS,Z
goto BusWindowDown
goto Main_0
BusWindowDown
comf DATAPOINTER,f
goto WindowDown
BusWindowUp
comf DATAPOINTER,f
goto WindowUp
Main_0
call ReadSwitchInput ;
movfw ButtonImage
andlw 0x01 ; is this a DOWN command
btfss STATUS,Z
goto WindowDown
movfw ButtonImage
andlw 0x02 ; is this a UP command
btfss STATUS,Z
goto WindowUp
StopWindow
movfw ButtonImage
btfss STATUS,Z
goto MainLoop
movfw DATAPOINTER
btfss STATUS,Z
goto MainLoop
bcf UpDirection
bcf DwnDirection
clrf WindowLiftStatus
goto MainLoop
;------------------------------------------------------------------------------
WindowUp
bcf DwnDirection
bsf UpDirection ;
comf WindowLiftStatus,w ; get complement of status
btfss STATUS,Z ; if previus status was not up
goto InitialSpike ; then wait some time for current spike
call FastReadInput ; get current value acroos shunt
sublw VoltageThreshold ; subtract value from constant
btfsc STATUS,C ; if V <= Threshold
goto $+2 ; then, continue
goto EmergencyReverse ; else, reverse motor
RunState
movlw 0xff ;
movwf WindowLiftStatus
goto Main_0 ; return
InitialSpike
call Wait20 ; wait until into initial ramp
call FastReadInput ; get current value acroos shunt
sublw VoltageThreshold ; subtract value from constant
btfsc STATUS,C ; if V <= Threshold
goto RunState ; then, continue
clrf WindowLiftStatus
goto Main_0 ; return
EmergencyReverse
bcf UpDirection
bsf DwnDirection ;
call WAIT250
call WAIT250
bcf DwnDirection ; stop motor
bcf UpDirection
call WAIT250
call WAIT250
movlw 0x80 ; else, continue
movwf WindowLiftStatus
goto Main_0 ; return
;------------------------------------------------------------------------------
WindowDown
bcf UpDirection
bsf DwnDirection ;
goto Main_0 ; return
;------------------------------------------------------------------------------
; FUNCTION ; ReadXInput (ADRESH) X = Wreg
; DESCRIPTION ; Read X-position pot ADC channel and return value in W
; REGISTERS USED ; Wreg,ADCON0,ADRESH,ADRESL
;------------------------------------------------------------------------------
ReadXInput
movwf ADCON0 ; Setup A/D Converter
ADCSetupDelay
movlw .3
movwf DLY_CNT0
decfsz DLY_CNT0,F
goto $-1
FastReadInput
bsf ADCON0,GO ; start another conversion
RXI1
btfsc ADCON0,GO ; wait for conversion to complete
goto RXI1
movfw ADRESH ; get conversion value
return
;------------------------------------------------------------------------------
; FUNCTION ; ReadFastInput (ADRESH) X = Wreg
; DESCRIPTION ; Read X-position pot ADC channel and return value in W
; ; Assume channel was selected and conversion was started previously
; REGISTERS USED ; Wreg,ADCON0,ADRESH,ADRESL
;------------------------------------------------------------------------------
ReadFastInput
btfsc ADCON0,GO ; wait for conversion to complete
goto $-1
movfw ADRESH ; get conversion value
bsf ADCON0,GO ; start another conversion
return
;------------------------------------------------------------------------------
; FUNCTION ; ReadSwitchInput (ADRESH)
; DESCRIPTION ; Read switched through ADC channel and return value in W
; REGISTERS USED ; Wreg,ADCON0,ADRESH,ADRESL
;------------------------------------------------------------------------------
ReadSwitchInput
comf PORTA,0
andlw ButtonMask
movwf ButtonImage
swapf ButtonImage,1
movfw ButtonImage
btfsc STATUS,Z ; if zero flag set,
retlw 0 ; then, no buttons down
return ; one or more buttons down
;------------------------------------------------------------------------------
;
; FUNCTION : WAIT ()
;
; DESCRIPTION : WAIT FOR DLY_CNT0 TIMES 1 MS
; DLY_CNT1 = OSC/[4*6*1000] [ 1MS ]
;
; PAGE : 2
;
;------------------------------------------------------------------------------
Wait20
MOVLW D'20' ; DELAY COUNTER FOR 20 MS
MOVWF DLY_CNT0
goto WAIT001
Wait125
MOVLW D'125' ; DELAY COUNTER FOR 125 MS
MOVWF DLY_CNT0
goto WAIT001
WAIT250
MOVLW D'250' ; DELAY COUNTER FOR 250 MS
MOVWF DLY_CNT0
WAIT001
MOVLW D'200' ; DELAY COUNTER FOR 1 MS
MOVWF DLY_CNT1
WAIT1
NOP ; [1] WASTE TIME
CLRWDT ; [1]
DECFSZ DLY_CNT1,F ; [1]
GOTO WAIT1 ; [2]
DECFSZ DLY_CNT0,F ; [1]
GOTO WAIT001 ; [2]
RETLW 0
;------------------------------------------------------------------------------
subtitle "EEPROM Access Routines"
page
;------------------------------------------------------------------------------
;
; FUNCTION : EEWRITE ()
;
; DESCRIPTION : WRITE 8 BIT VALUE TO EEPROM
;
;------------------------------------------------------------------------------
EE_CLEAR
MOVLW 00H ; CLEAR 8 BIT W-REGISTER
; ******** WRITE 8-BIT WORD TO EEPROM *********
EEWRITE
BSF STATUS,RP0 ; Select Bank 1
MOVWF EEDATA ; Data value to write
BCF STATUS,RP0 ; Re-Select Bank 0
MOVFW ADDRESS ; GET EEPROM ADDRESS
BSF STATUS,RP0 ; Select Bank 1
MOVWF EEADR ; Data memory to write
EEWRITE2
BCF EECON1,EEPGD ; Select Data Memory (E2)
BSF EECON1,WREN ; Command Write Enable
MOVLW 55H
MOVWF EECON2 ; Write 55H
MOVLW 0AAH
MOVWF EECON2 ; Write AAH
BSF EECON1,WR ; Command Write
WR_WAIT
CLRWDT
BTFSC EECON1,WR ; Wait for write to complete
GOTO WR_WAIT
; ******* EEPROM WRITE DISABLE ****************
EEWRITE3
BCF EECON1,WREN ; Disable writes
BCF STATUS,RP0 ; Select Bank 0
INCF ADDRESS,F ; Auto-increase Address Pointer
RETLW 0H
;------------------------------------------------------------------------------
;
; FUNCTION : EEREAD ()
;
; DESCRIPTION : READ 8 BIT VALUE FROM EEPROM
;
;------------------------------------------------------------------------------
EEREAD
MOVFW ADDRESS
BSF STATUS,RP0 ; Select Bank 1
MOVWF EEADR ; Data memory address to read
BCF EECON1,EEPGD ; Select Data Memory (E2)
BSF EECON1,RD ; Command read
MOVF EEDATA,W ; Get data
BCF STATUS,RP0 ; Select Bank 0
INCF ADDRESS,F ; Auto-increase Address Pointer
RETURN ; Return without changing w-register
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
ORG ((HIGH $)+1) * 100H
#Include <UART688i.asm>
;------------------------------------------------------------------------------
#include <IDtable.inc>
;------------------------------------------------------------------------------
END ; directive 'end of program'
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -