📄 can_ref.asm
字号:
;; ----------- MAIN LOOP ----------------------------------
;; --------------------------------------------------------
jMainLoop clrwdt
;;====================== XMIT CODE ========================
jmpClr tbTxMsg,jMain10 ; not time to xmit next CAN msg yet
bcf tbTxMsg ; reset xmit flag
;; Reload counter
movlw 2 ; 65 mS units
movwf bXmitClk ; Countdown to xmit next message
jmpFeqL bXmitID,0xFF,jMain10 ; Transmission turned off
;; Time to xmit next CAN message. Select source of message and ID
;; to use for transmission
;; <<<<< Analog Input Board >>>>>
jmpFeqL bNextMsgType,0,Xmit3201
jmpFeqL bNextMsgType,1,XmitRA0
goto jMain8
;********** POT **********
Xmit3201
call Read3201 ; read 3201 AD
movfw bSwXmitID ; Use DIP Tx address for transmission
movwf bXmitID
incf bNextMsgType,F ; Next time use next source and ID
goto jMain8
XmitRA0 ;; Use Pot as input
movlw dA2DRA0 ; fosc/8 clk, RA0, A/D off
call ReadA2D ; Read A/D port in W
movfw bSwXmitID ; Use DIP Tx address for transmission
addlw 0x01
movwf bXmitID
clrf bNextMsgType ; clear next message
goto jMain8
jMain8
;; Wait for pending messages to be sent (ALL BUFFERS)
bL2bV 0x08,b2510RegMask
movlw TXB0CTRL
call WaitANDeqZ
;; Send CAN message with
;; ID = bXmitID
;; Two data bytes: iA2DValue,iA2DValue+1
SPI_WriteV TXB0SIDH,bXmitID ; Message ID
SPI_WriteL TXB0SIDL,0x00 ; Send message - lower bits 0
SPI_WriteL TXB0DLC,0x02 ; 2 data bytes
;; Send least significant byte first
SPI_WriteV TXB0D0,iA2DValue
SPI_WriteV TXB0D1,iA2DValue+1
SPI_Rts RTS0 ; Transmit buffer 0
jMain10
;;====================== RECEIVE CODE ========================
call CheckCANMsg
jmpClr tbRxMsgPend,jMainLoop
;; new CAN message received
call ParseCAN
bcf tbRxMsgPend ; new CAN message received
goto jMainLoop
;**********************************************************
;OutputPWM
; OutputPWM - Uses PWM1 output.
;
;**********************************************************
OutputPWM
movfw bPWMValue ; 8 bit PWM value
movwf iA
clrf iA+1
;; W = 0 - 255. Load into PWM register.
;; load LOWER 2 bits into CCP1CON bits 5,4
;; load UPPER 6 bits (shifted right by 2 ) into CCPR1
;; this is high res 8 bit mode (upper 2 bits of 10 bit word are zero)
movf iA,W ; low byte to W
clrf iA+1
rrf iA,F ; low bit to carry
rrf iA+1,F ; move carry into upper bit
rrf iA,F ; low bit to carry
rrf iA+1,F ; move carry into upper bit
rrf iA+1,F ; move to 6,5
rrf iA+1,W ; move to 5,4 in W
andlw B'00110000' ; mask other bits
iorlw B'00001100' ; turn on PWM mode
movwf CCP1CON ; set PWM1 and lower 2 bits
;; get upper 6 bits
movf iA,W
andlw B'00111111' ; mask upper 2 bits
movwf CCPR1L
return
;**********************************************************
;ReadA2D
; This functions reads analog input and stores the result
; in iA2DValue as a 12 bit value. Value in W is used to set
; ADCON0 to select correct port.
;**********************************************************
ReadA2D
;; setup A/D to select port, etc
movwf ADCON0
;; turn on A/D
bsf ADCON0,0 ;A/D on
;; allow 50us for settling
movlw 25
movwf bCnt
ReadAD10
decfsz bCnt,F
goto ReadAD10
;; begin conversion
bsf ADCON0,2 ; GO
ReadAD20 jmpSet ADCON0,2,ReadAD20 ; wait for done bit
movf ADRES,W
movwf iA2DValue
clrf iA2DValue+1
;; Convert to 12 bit
iShiftL iA2DValue
iShiftL iA2DValue
iShiftL iA2DValue
iShiftL iA2DValue
return
;******************************************************
;ParseCAN <<<<<INPUTS>>>>>
; Parse message. Assumes message is two byte 12 bit data.
; Uses bBaseRecID and bRecIDNext to accept message for PWM output.
;******************************************************
ParseCAN
;********** Analog In Board **********
movlw b'00001111'
andwf iRecID_H,W
movwf iA
jmpFeqL iA,0x0,IDx0 ;check for ID x0
goto jParCANRet
IDx0 ;; x0 input send PWM to lamp
;; 12 bits of data
bV2bV pRecDataBase,iRecValue
bV2bV pRecDataBase+1,iRecValue+1
;; new PWM value pending
bV2bV iRecValue,iA
bV2bV iRecValue+1,iA+1 ; 12 bit received value
;; convert to 8 for PWM out
iShiftR iA
iShiftR iA
iShiftR iA
iShiftR iA
;; Convert to 8 bit
bV2bV iA,bPWMValue
call OutputPWM
goto jParCANRet
jParCANRet
return
;******************************************************
;Init2510
;* Function: Init_MCP2510()
;* Place MCP2510 initialization here...
;*******************************************************
Init2510
;; Reset 2510
call Reset2510
;; set CLKOUT prescaler to div by 4
bL2bV 0x03,b2510RegMask
bL2bV 0x02,b2510RegData
movlw CANCTRL
call BitMod2510
;Set physical layer configuration
;
; Fosc = 16MHz
; BRP = 7 (divide by 8)
; Sync Seg = 1TQ
; Prop Seg = 1TQ
; Phase Seg1 = 3TQ
; Phase Seg2 = 3TQ
;
; TQ = 2 * (1/Fosc) * (BRP+1)
; Bus speed = 1/(Total # of TQ) * TQ
;
SPI_WriteL CNF1,0x07 ; set BRP to div by 8
;#define BTLMODE_CNF3 0x80
;#define SMPL_1X 0x00
;#define PHSEG1_3TQ 0x10
;#define PRSEG_1TQ 0x00
SPI_WriteL CNF2,0x90
;#define PHSEG2_3TQ 0x02
SPI_WriteL CNF3,0x02
;
;; Configure Receive buffer 0 Mask and Filters
;; Receive buffer 0 will not be used
SPI_WriteL RXM0SIDH,0xFF
SPI_WriteL RXM0SIDL,0xFF
SPI_WriteL RXF0SIDH,0xFF
SPI_WriteL RXF0SIDL,0xFF
SPI_WriteL RXF1SIDH,0xFF
SPI_WriteL RXF1SIDL,0xFF
;; Configure Receive Buffer 1 Mask and Filters
SPI_WriteL RXM1SIDH,0xFF
SPI_WriteL RXM1SIDL,0xE0
;; Initialize Filter 2 to match x0 bBaseRecID from DIP switch
SPI_WriteV RXF2SIDH,bBaseRecID
SPI_WriteL RXF2SIDL,0x00 ; Make sure EXIDE bit (bit 3) is set correctly in filter
;; Initialize Filter 3 to match x1 from DIP switch
incf bBaseRecID,F
SPI_WriteV RXF3SIDH,bBaseRecID
SPI_WriteL RXF3SIDL,0x00
;; Initialize Filter 4 to match x2 from DIP switch
incf bBaseRecID,F
SPI_WriteV RXF4SIDH,bBaseRecID
SPI_WriteL RXF4SIDL,0x00
;; Initialize Filter 5 to match x3 from DIP switch
incf bBaseRecID,F
SPI_WriteV RXF5SIDH,bBaseRecID
SPI_WriteL RXF5SIDL,0x00
movlw b'11110000'
andwf bBaseRecID,F
;; Disable all MCP2510 Interrupts
bL2bV 0x00,b2510RegData
movlw CANINTE
call Wrt2510Reg
;; Sets normal mode
call SetNormalMode
return
;**********************************************************
;ProcessSPI
;
;**********************************************************
ProcessSPI
skipSet bSPICnt,2
;; buffer not full yet
return
;; disable SPI interupt
BANK1
bcf _SSPIE_P ; SSP int enable (BANK 1)
BANK0
;; enable SPI
BANK1
bsf _SSPIE_P ; SSP int enable (BANK 1)
BANK0
return
;*******************************************************************
;WaitMSec
; Delay W number of Msec Routines (255 max)
; Actually slightly larger than 1 mS
;*******************************************************************
WaitMSec
movwf bCnt ;store Msec -> bCnt
jWaitMSec0
clrwdt ;clear wdt
; TMR1H: 256 uSec tics with maximum of 1/2 rollover = 32.768 msec maximum
Set1HClock bGenClk,4 ; 256 uS
jWaitMSec1
jmp1HNotYet bGenClk,jWaitMSec1
decfsz bCnt,F
goto jWaitMSec0
return
;
;**********************************************************
;Init
; Initialize
;
;**********************************************************
Init
clrwdt ; required before changing wdt to timer0
;; clear peripheral interrupts
BANK1
clrf PIE1_P
;; OPTION_REG: PortB Pullups on.
;; no prescale for WDT -> should always > 7 mSec ( 18 mS nominal)
;; Timer 0: Use 64 prescale for 0.27127 * 64 = 17.361 uSec tics
movlw B'01000101' ; Timer0 prescale 64
movwf OPTION_REG_P
;; clear bank 0
movlw 0x20
movwf FSR
jInitClr1 clrf INDF
incf FSR,F
jmpClr FSR,7,jInitClr1
;; clear bank 1
movlw 0xA0
movwf FSR
jInitClr2 clrf INDF
incf FSR,F
jmpSet FSR,7,jInitClr2
call InitIO ;initalize IO of microcontroller
;; configure Timer1:
BANK0
movlw B'00000001' ; Prescale = 1, Timer enabled
movwf T1CON
BANK1
bsf _TMR1IE_P ; timer1 rollover interrupt enable (page 1)
BANK0
;; init output PWM1 ( uses timer2 )
BANK0
;; Timer2 ( 8 bit timer ) set for
movlw B'00000100' ; prescale of 1, internal clk, enable timer2
movwf T2CON
; load PWM counter(PR2) with 0x3F ( 8 bit high res mode)
; this gives a 15.625KHz signal with 4MHz crystal
BANK1
movlw 0x3F
movwf PR2_P
BANK0
;; for testing
clrf TMR1L
clrf TMR1H
;; turn on interrupts
BANK0
movlw B'11000000' ; Enable interrupts ( Periphrals only )
movwf INTCON
return
;; INITIALIZE I/O OF MICROCONTROLLER
InitIO
BANK1
movlw b'00000100' ;turn on A/D conversion RA0, RA1, RA3
movwf ADCON1_P
;; Port A
;; 0 in <*>A2D input POT<*>
;; 1 out(1) 2510 chip select
;; 2 in <*>open<*>
;; 3 in <*>open<*>
;; 4 in <*>open<*>
;; 5 out(1) RST 2510
BANK0
movlw B'00000010' ;; initialize Port A outputs
movfw PORTA
BANK1
movlw B'11111101'
movwf TRISA_P ;; set Port A
;; Port B
;; 0 in Interrupt from 2510
;; 1 out(1) <*>CS' MCP3201<*>
;; 2 out(1) <*>CS' 25C04<*>
;; 3 in <*>open<*>
;; 4 in <*>open<*>
;; 5 in RX0BF from 2510
;; 6 in ICD
;; 7 in ICD
BANK0
movlw B'00000110' ;; initialize Port B outputs
movfw PORTB
BANK1
movlw B'11111001'
movwf TRISB_P ;; set Port B
;; Port C
;; 0 in DIP #1
;; 1 in DIP #2
;; 2 out(0) <*>PWM Out<*>
;; 3 out(0) SPI clock - master
;; 4 in SPI data in
;; 5 out(0) SPI data out
;; 6 in DIP #3
;; 7 in DIP #4
BANK0
movlw B'00000000'
movwf PORTC
BANK1
movlw B'11010011'
movwf TRISC_P ;; set Port C
BANK0
return
ifdef ROBUST
;; robust design - force WDT reset
FILL (goto WDTReset1),(0xFFF-$)
WDTReset1 goto WDTReset1
endif
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -