📄 pic.txt
字号:
ENDIF
IFDEF RCSTA
SPEN EQU H'0007'
RC9 EQU H'0006'
NOT_RC8 EQU H'0006'
RC8_9 EQU H'0006'
SREN EQU H'0005'
CREN EQU H'0004'
FERR EQU H'0002'
OERR EQU H'0001'
RCD8 EQU H'0000'
;----- PIE1 and PIR1 RC Bits ------------------------------------------
RCIE EQU H'0005'
RBFL EQU H'0005'
ENDIF
IFDEF SSPCON
WCOL EQU H'0007'
SSPOV EQU H'0006'
SSPEN EQU H'0005'
CKP EQU H'0004'
SSPM3 EQU H'0003'
SSPM2 EQU H'0002'
SSPM1 EQU H'0001'
SSPM0 EQU H'0000'
ENDIF
IFDEF SSPSTAT
D EQU H'0005'
I2C_DATA EQU H'0005'
NOT_A EQU H'0005'
NOT_ADDRESS EQU H'0005'
D_A EQU H'0005'
DATA_ADDRESS EQU H'0005'
P EQU H'0004'
I2C_STOP EQU H'0004'
S EQU H'0003'
I2C_START EQU H'0003'
R EQU H'0002'
I2C_READ EQU H'0002'
NOT_W EQU H'0002'
NOT_WRITE EQU H'0002'
R_W EQU H'0002'
READ_WRITE EQU H'0002'
UA EQU H'0001'
BF EQU H'0000'
ENDIF
IFDEF T1CON
T1CKPS1 EQU H'0005'
T1CKPS0 EQU H'0004'
T1OSCEN EQU H'0003'
T1INSYNC EQU H'0002'
TMR1CS EQU H'0001'
TMR1ON EQU H'0000'
ENDIF
IFDEF T2CON
TOUTPS3 EQU H'0006'
TOUTPS2 EQU H'0005'
TOUTPS1 EQU H'0004'
TOUTPS0 EQU H'0003'
TMR2ON EQU H'0002'
T2CKPS1 EQU H'0001'
T2CKPS0 EQU H'0000'
ENDIF
IFDEF TRISE
IBF EQU H'0007'
OBF EQU H'0006'
IBOV EQU H'0005'
PSPMODE EQU H'0004'
TRISE2 EQU H'0002'
TRISE1 EQU H'0001'
TRISE0 EQU H'0000'
ENDIF
IFDEF TXSTA
CSRC EQU H'0007'
TX9 EQU H'0006'
NOT_TX8 EQU H'0006'
TX8_9 EQU H'0006'
TXEN EQU H'0005'
SYNC EQU H'0004'
BRGH EQU H'0002'
TRMT EQU H'0001'
TXD8 EQU H'0000'
;----- PIE1 and PIR1 TX Bits ------------------------------------------
TXIE EQU H'0004'
TXIF EQU H'0004'
ENDIF
IFDEF VRCON
VREN EQU H'0007'
VROE EQU H'0006'
VRR EQU H'0005'
VR3 EQU H'0003'
VR2 EQU H'0002'
VR1 EQU H'0001'
VR0 EQU H'0000'
ENDIF
LIST
;***************************************
; LIBRARY OF UTILITIES FOR PIC ;
; EDWARD CHEUNG, PH.D. ;
; MITCHELLVILLE, MD ;
; ebc714@rs710.gsfc.nasa.gov ;
;***************************************
; MODIFICATION HISTORY
; Version 0.1, July 1995:
; Compiles under MPASM 1.02.05. Loads with PICSTART 4.02.
; Currently available modules are A/D, LCD, X-10, IR, RS422 and RS232.
;The RS485 code remains to be tested, and is awaiting
;driver chips to test the transmit enable line (R4_TRANON). IR module
;supports SONY (aka SIRCS) format. Each module tested using LCD module.
; Version 0.2, July 1995:
; Compiles under mpasm 1.20. Moved interrupt functions into
;main library. Improved INT_HANDLER to call one module per
;interrupt. Previous version called all enabled modules, which caused timing
;problems. Each module was not guaranteed to be called at a stable frequency.
; Fixed bug with computed gotos. Added assembler code that will give a
;warning if code with computed gotos is placed in program memory above
;location 0xff. See Application Note AN556 in Embedded Control Handbook
;for more details.
; Tested with 14.7456Mhz crystal. This is a commonly available
;frequency that is divisible by 9600 and under 16Mhz.
;15.360Mhz and 15.9744Mhz are also good frequencies (not tested).
;At 14.x Mhz, 57600 interrupts/second is probably the fastest you can
;go. If you need more, use a faster crystal.
; Eliminated use of P16C71.INC file and used defs in P16CXX.INC. This
;should improve support for other processors by substituting the proper
;*.inc file. As far as I know, the only thing you will have to change
;for other processors in the MEM_FIRST and the MEM_LAST variables below,
;and don't enable the A/D if it doesn't exist.
; Version 0.21:
; Invalid commands to TW_SEND are rejected.
GOTO MAIN ;start execution at 'main'
#define __16C71 ;using PIC16C71
#INCLUDE "P16CXX.INC" ;defs for register location
__FUSES _WDT_ON&_HS_OSC ;watch dog on, and hs oscillator
;***** General constants
FXTAL EQU D'14745600' ;device clock freq
INTSEC EQU D'28800' ;desired interrupts/sec.
TRUE EQU 1H
FALSE EQU 0H
;Set up desired interrupts/sec for chip. A smaller number means more
;operations between interrupts, and more time alotted to the main program.
RTC_NUM EQU D'256' - ((FXTAL/(4*INTSEC)) - D'7')
;number of modules that use the interrupt mechanism
NUM_MOD EQU R2_ENABLE + R4_ENABLE + IR_ENABLE + IR_ENABLE + TW_ENABLE
;number of times/sec each interrupt module gets control (is run)
RUNSEC EQU INTSEC/NUM_MOD
;***** Memory Management
;Assign memory location to input variable 'name'
;Addresses will start at MEM_FIRST, and last one allowed is at MEM_LAST
;0CH to 2FH inclusive are available on '71.
;See .lst file for actual addresses. In that file,
;MEM_INDEX will be one address past the last one.
;Thus max for MEM_INDEX is MEM_LAST + 1
MEM_FIRST EQU 0CH
MEM_LAST EQU 2FH
MEM_INDEX SET MEM_FIRST
ALLOC MACRO NAME
NAME EQU MEM_INDEX
IF MEM_INDEX > MEM_LAST
CALL OUT_OF_MEMORY_ERROR
;Reduce the number of modules in use
ELSE
MEM_INDEX SET MEM_INDEX + 1
ENDIF
ENDM
;Assign memory location to input variable 'name'
;Total number of storage locations is 'spacing',
;which includes memory allocated in previous ALLOC call,
;and the one occupied by 'name'.
ALLOC_ARRAY MACRO NAME,SPACING
IF SPACING < 2
CALL ARRAY_TOO_SMALL
;Increase size of array to be greater than 2
ENDIF
MEM_INDEX SET (MEM_INDEX+SPACING)-2
NAME EQU MEM_INDEX
IF MEM_INDEX > MEM_LAST
CALL OUT_OF_MEMORY
;Reduce the number of modules in use
ELSE
MEM_INDEX SET MEM_INDEX + 1
ENDIF
ENDM
;Memory location assignment
;register storage for interrupt
ALLOC TEMP_W
ALLOC TEMP_STAT
ALLOC TASK_INDEX
;gen purpose for use in functions that interface to interrupt routines
ALLOC SCRATCH_1
ALLOC SCRATCH_2
IF R2_ENABLE == TRUE
;rs232 uart
ALLOC R2_OUT_TIMR ;output timer
ALLOC R2_OUT_BIT ;index of current output bit
ALLOC R2_IN_TIMER ;input timer
ALLOC R2_IN_BIT ;index of current input bit
ALLOC R2_IN_BYTE ;byte being received
ALLOC R2_IN_PTR ;ring buffer pointer in
ALLOC R2_OUT_PTR ;ring buffer pointer out
ALLOC R2_FIRST_BUF ;ring buffer location
ALLOC_ARRAY R2_LAST_BUF,D'07' ;ring buffer end
ENDIF
IF R4_ENABLE == TRUE
;rs422/485 uart
ALLOC R4_OUT_TIMR ;current bit being sent
ALLOC R4_OUT_BIT ;output data
ALLOC R4_IN_TIMER ;bit counter
ALLOC R4_IN_BIT ;data input bit
ALLOC R4_IN_BYTE ;byte being received
ALLOC R4_IN_PTR ;ring buffer pointer in
ALLOC R4_OUT_PTR ;ring buffer pointer out
ALLOC R4_FIRST_BUF ;ring buffer location
ALLOC_ARRAY R4_LAST_BUF,D'08' ;ring buffer end
ENDIF
IF LCD_ENABLE == TRUE
;timer
ALLOC TIMER_HI
ALLOC TIMER_LO
;binary to bcd conversion
ALLOC LSD
ALLOC MSD
ENDIF
IF IR_ENABLE == TRUE
;ir uart
ALLOC IR_DEV ;received ir device
ALLOC IR_DATA ;received ir data
ALLOC IR_PHASE ;current ir bit being received
ALLOC IR_TIMER ;rx countdown timer
ALLOC IR_T_DEV ;tx ir device
ALLOC IR_T_DATA ;tx ir data
ALLOC IR_O_COUNT ;number of times to send ir data
ALLOC IR_O_DEV ;ir device being sent
ALLOC IR_O_DATA ;ir data being sent
ALLOC IR_O_PHASE ;ir bit being sent
ALLOC IR_O_TIMER ;tx countdown timer
ENDIF
IF TW_ENABLE == TRUE
;x10 uart
;memory
ALLOC TW_FLAGS ;for the following booleans:
TW_PREV EQU 00H ;boolean, previous 60 hz status
TW_STATE EQU 01H ;boolean, current 60 hz status
TW_CARRIER EQU 02H ;boolean, data bit
TW_O_CARR EQU 03H ;boolean, tw_o_carrier;
TW_FIRST EQU 04H ;boolean, first packet of two
ALLOC TW_SAMPLE ;countdown and control timer
ALLOC TW_PHASE ;which bit current being sampled
ALLOC TW_HOUSE ;house code data
ALLOC TW_KEY ;key code data
ALLOC TW_O_SAMPLE ;countdown and control timer
ALLOC TW_O_PHASE ;bit being sent
ALLOC TW_O_HOUSE ;house code being sent
ALLOC TW_O_KEY ;key code being sent
ALLOC TW_T_HOUSE ;next house code to be sent
ALLOC TW_T_KEY ;next key code to be sent
ALLOC TW_MATCH ;ascii of x10 code sought
ALLOC TW_INDEX ;indexing counter
ENDIF ;TW_ENABLE
;***** Interrupt related functions
;This is called every time an interrupt occurs.
;Due to computed GOTO, this function must reside in memory range 0-FF.
;One module is called everytime there is an interrupt. Note how the call
;of each module is written. There must be exactly 4 instructions between
;each IF...ENDIF statement.
;Note that IR functions are called in separate interrupts. That is because
;each takes so much time to run.
INT_HANDLER MACRO
MOVFW TASK_INDEX ;if (task_index == num_mod)
SUBLW NUM_MOD
SKPNZ
CLRF TASK_INDEX ; task_index = 0;
CLRC ;// clear carry
RLF TASK_INDEX,F ;pc += (task_index++ * 4)
RLF TASK_INDEX,W
RRF TASK_INDEX,F
INCF TASK_INDEX,F
ADDWF PCL,F ;//computed goto, run one of the modules below
IF TW_ENABLE == TRUE
CALL TW_GET ;check x10 input
CALL TW_PUT ;check x10 output
GOTO INT_H_END
GOTO INT_H_END
ENDIF
IF R2_ENABLE == TRUE
CALL R2_SER_IN ;check serial input
CALL R2_SER_OUT ;check serial output
GOTO INT_H_END
GOTO INT_H_END
ENDIF
IF R4_ENABLE == TRUE
CALL R4_SER_IN ;check serial input
CALL R4_SER_OUT ;check serial output
GOTO INT_H_END
GOTO INT_H_END
ENDIF
IF IR_ENABLE == TRUE
CALL IR_GET ;check ir input
GOTO INT_H_END
GOTO INT_H_END
GOTO INT_H_END
CALL IR_PUT ;check ir output
GOTO INT_H_END
GOTO INT_H_END
GOTO INT_H_END
ENDIF
INT_H_END
IF INT_H_END > H'FE'
CALL PAGE_ERROR
;Due to computed gotos, this should be in program memory below 0xFF
;See Application Note AN556, example 5 for more info.
ENDIF
ENDM
;Interrupt service routine.
INT_VECT ORG H'04'
;Save W and STATUS registers
MOVWF TEMP_W ;save W
SWAPF STATUS,W ;get swapped status
MOVWF TEMP_STAT ;save swapped status
;Reschedule next interrupt
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -