📄 station.asm
字号:
;************************************************
;* STATION.ASM *
;************************************************
;* *
;* Written by: Rong *
;* Technical Sales Engineer. *
;* Rossmax Technology Inc. *
;* Date: 27 Sep 2004 *
;* Revision: 1.0 *
;************************************************
;
;
;
; This source code provides a demonstration of the MSSP peripheral
; on the PIC16F877 MCU & MCP2510 CAN Controller.
; It will show how to Configure and Write/Read the SPI data to/from MCP2510
; >> The operation Freq is 16Mhz for both 877 & MCP2510
; >> The Bit Rate will be set as 125K Bps with 8TQ/Bit
; >> The 877 receive data from MCP2510 & Send data to sample device
; >> The 877 receive data from the sample device and Send data to the master CAN controller.
list p=16f877
#include <p16f877.inc>
#include <REG2510.inc>
; Variables used in this program;
; UDATA
SERIAL_NUMBER_TYPE EQU 0x20 ; This Driver type
SERIAL_NUMBER_IDH EQU 0x21 ; This Driver ID high byte
SERIAL_NUMBER_IDL EQU 0x22 ; This Driver ID low byte
RecID EQU 0x23 ; Receive Master Driver ID
Dlen_2510 EQU 0x24 ; The length of Write Data
Addr_2510 EQU 0x25 ; The Start Address of MCP2510
Buf_2510 EQU 0X26 ; Write Data buffer
Buf_REC EQU 0x2e ; Read Data buffer
STATUS_byte EQU 0x36 ; STATUS of MCP2510
TempVar1 EQU 0X37 ; temp data
TempVar2 EQU 0X38 ; temp data
PORT_CS2510 EQU PORTC
#define CS2510 PORTC,0 ; RC0 is CS control signal of this 2510 EVM Board !!
#define MESSAGE .100 ; This Driver ID
#define MESSAGE_NO1 .1 ; Master Driver ID
; Locates startup code @ the reset vector
;*******************************************************
;**** MACRO RESET_2510
;**** RESET MCP2510
;*******************************************************
RESET_2510 MACRO
BANKSEL PORT_CS2510
bcf CS2510
movlw CMD_RESET
call Write_SPI_Byte
BANKSEL PORT_CS2510
bsf CS2510
ENDM
;*******************************************************
;**** MACRO STATUS_2510
;**** READ MCP2510'S STATUS
;*******************************************************
STATUS_2510 MACRO
BANKSEL PORT_CS2510
bcf CS2510
movlw CMD_STATUS
call Write_SPI_Byte
movlw 0xff
call Write_SPI_Byte
movwf STATUS_byte
call Write_SPI_Byte
subwf STATUS_byte,W
btfss STATUS,Z
clrf STATUS_byte
BANKSEL PORT_CS2510
bsf CS2510
ENDM
;*******************************************************
;**** MACRO WRITE_2510 W_ADD,W_DATA
;**** Write W_DATA into W_ADD
;*******************************************************
WRITE_2510 MACRO W_ADD,W_DATA
BANKSEL PORT_CS2510
bcf CS2510
movlw CMD_WRITE
call Write_SPI_Byte
movlw W_ADD
call Write_SPI_Byte
movlw W_DATA
call Write_SPI_Byte
BANKSEL PORT_CS2510
bsf CS2510
ENDM
;*******************************************************
;**** MACRO WRITE_2510 W_ADD,W_DATA
;**** Write W_DATA into W_ADD
;**** W_DATA is a Variable
;*******************************************************
WRITE_2510_DATA MACRO W_ADD,W_DATA
BANKSEL PORT_CS2510
bcf CS2510
movlw CMD_WRITE
call Write_SPI_Byte
movlw W_ADD
call Write_SPI_Byte
movf W_DATA,W
call Write_SPI_Byte
BANKSEL PORT_CS2510
bsf CS2510
ENDM
;*******************************************************
;**** MACRO READ_2510 R_ADD
;**** Read data @ address R_ADD
;*******************************************************
READ_2510 MACRO R_ADD
BANKSEL PORT_CS2510
bcf CS2510
movlw CMD_READ
call Write_SPI_Byte
movlw R_ADD
call Write_SPI_Byte
movlw 0xff
call Write_SPI_Byte
BANKSEL PORT_CS2510
bsf CS2510
ENDM
;*******************************************************
;**** MACRO MODIFY_2510 M_ADD,M_MASK,M_DATA
;**** Target address M_ADD
;**** Mask Pattern @ M_MASK
;**** Data Pattern @ M_DATA
;*******************************************************
MODIFY_2510 MACRO M_ADD,M_MASK,M_DATA
BANKSEL PORT_CS2510
bcf CS2510
movlw CMD_MODIFY
call Write_SPI_Byte
movlw M_ADD
call Write_SPI_Byte
movlw M_MASK
call Write_SPI_Byte
movlw M_DATA
call Write_SPI_Byte
BANKSEL PORT_CS2510
bsf CS2510
ENDM
;*******************************************************
;**** MACRO SEND_TXB0
;**** SEND COMMAND TO START TXBO TRANSMISSION
;*******************************************************
SEND_TXB0 MACRO
BANKSEL PORT_CS2510
bcf CS2510
movlw CMD_RTS0 ; TRansmit Buffer 0
call Write_SPI_Byte
BANKSEL PORT_CS2510
bsf CS2510
ENDM
;*******************************************************
;**** MACRO SEND_TXB1
;**** SEND COMMAND TO START TXB1 TRANSMISSION
;**** No use
;*******************************************************
SEND_TXB1 MACRO
BANKSEL PORT_CS2510
bcf CS2510
movlw CMD_RTS1 ; TRansmit Buffer 1
call Write_SPI_Byte
BANKSEL PORT_CS2510
bsf CS2510
ENDM
;*******************************************************
;**** MACRO SEND_TXB2
;**** SEND COMMAND TO START TXB2 TRANSMISSION
;**** No use
;*******************************************************
SEND_TXB2 MACRO
BANKSEL PORT_CS2510
bcf CS2510
movlw CMD_RTS2 ; TRansmit Buffer 2
call Write_SPI_Byte
BANKSEL PORT_CS2510
bsf CS2510
ENDM
;*******************************************************
;**** END OF MACRO DECALRATION ^^^^^^^^^^^^^^^^^^^^^^^
;*******************************************************
org H'000'
goto Prog_Main
org H'004'
goto ISRs
;----------------------------------------------------------------------
;PROG1 CODE
Prog_Main
BANKSEL PORTD ; Port Initialize
movlw 0x00
movwf PORTD
movlw 0xff
movwf PORTC
BANKSEL TRISD
clrf TRISD
movlw b'11010010' ; RC0=CS2510, RC4=SDI, RC5=SDO, RC3=SCK
movwf TRISC
BANKSEL PCON ;
movlw 0x07
movwf PCON
bcf STATUS,IRP ; Clear RAM page 0
movlw 0x20
movwf FSR
ClearRam
clrf INDF
incf FSR,F
btfss FSR,7
goto ClearRam
BANKSEL SERIAL_NUMBER_TYPE
movlw 0x20
movwf SERIAL_NUMBER_TYPE
movlw 0x20
movwf SERIAL_NUMBER_IDH
movlw 0x20
movwf SERIAL_NUMBER_IDL
call InitSSP
call CONFIG_2510
Main:
BANKSEL Dlen_2510 ; Send data, data length is 1 byte
movlw 0x01
movwf Dlen_2510
movlw Buf_2510
movwf FSR
incf INDF
call TxMsg
call Delay_MCP2510 ; delay
call Delay_MCP2510
call Delay_MCP2510
call Delay_MCP2510
call Delay_MCP2510
call Delay_MCP2510
call Delay_MCP2510
call Delay_MCP2510
call RxMsg ; receive
BANKSEL PORTD ; display
movf Buf_REC,W ;
movwf PORTD ;
goto Main
;***************************************************************************************
;Initialize MCP2510
;***************************************************************************************
CONFIG_2510
;**** RESET MCP2510 first ******************************************
RESET_2510
call Delay_MCP2510 ; Wait for 32 Cycle
MODIFY_2510 CANCTRL,b'11100000',b'10000000' ; Set to Configure Mode
MODIFY_2510 CANCTRL,b'00000111',b'00000100' ; Set Clock Out Freq
WRITE_2510 CNF1,b'00000111' ; Set CNF1 , TQ = 2*8*1/16M = 1us 125k/bps
WRITE_2510 CNF2,b'10010000' ; Set CNF2 , PHASE1:3TQ,PRSEG:1TQ
WRITE_2510 CNF3,b'00000010' ; Set CNF3 , PHASE2:3TQ
WRITE_2510 CANINTE,b'00000011'
WRITE_2510 TXB0CTRL,b'00000011' ; TXB0CTRL , Supreme PRI
WRITE_2510 TXB1CTRL,b'00000010' ; TXB1CTRL ,
WRITE_2510 TXB2CTRL,b'00000001' ; TXB2CTRL , The lowest PRI
WRITE_2510 RXB0CTRL,b'00000000' ; RXB0CTRL ,
WRITE_2510 RXB1CTRL,b'00000000' ; RXB1CTRL ,
WRITE_2510 RXF0SIDH,MESSAGE ; MESSAGE is filter address
WRITE_2510 RXF0SIDL,0x8
WRITE_2510 RXF1SIDH,0xff
WRITE_2510 RXF1SIDL,0x8
WRITE_2510 RXF2SIDH,0xff
WRITE_2510 RXF2SIDL,0x8
WRITE_2510 RXF3SIDH,0xff
WRITE_2510 RXF3SIDL,0x8
WRITE_2510 RXF4SIDH,0xff
WRITE_2510 RXF4SIDL,0x8
WRITE_2510 RXF5SIDH,0xff
WRITE_2510 RXF5SIDL,0x8
WRITE_2510 RXM0SIDH,0xff
WRITE_2510 RXM0SIDL,0x00
WRITE_2510 RXM0EID8,0x00
WRITE_2510 RXM0EID0,0x00
WRITE_2510 RXM1SIDH,0xff
WRITE_2510 RXM1SIDL,0x00
WRITE_2510 RXM1EID8,0x00
WRITE_2510 RXM1EID0,0x00
MODIFY_2510 CANCTRL,b'11100000',b'00000000' ; Set to Normal Mode !!
return
;****************************************************************************************
; send CAN data
; Parameter: SERIAL_NUMBER_TYPE, SERIAL_NUMBER_IDH, SERIAL_NUMBER_IDL
; Parameter: Dlen_2510(length), Buf_2510(data)
; return: No
;****************************************************************************************
TxMsg
STATUS_2510
BANKSEL STATUS_byte
btfsc STATUS_byte,2
goto TxMsg
WRITE_2510_DATA TXB0SIDH,SERIAL_NUMBER_TYPE
WRITE_2510 TXB0SIDL,(((MESSAGE_NO1 << 5) & b'11100000') | b'00001000')
WRITE_2510_DATA TXB0EID8,SERIAL_NUMBER_IDH
WRITE_2510_DATA TXB0EID0,SERIAL_NUMBER_IDL
WRITE_2510_DATA TXB0DLC,Dlen_2510 ; DLC
movlw TXB0D0
movwf Addr_2510
call WRITE_2510S
SEND_TXB0
return
;*************************************************************************************
; receive CAN data
; Parameter: NO
; return: RecID(Master Driver ID), W(data length), Buf_REC(data)
; If has not received to the data. return: W = 0
;****************************************************************************************
RxMsg
STATUS_2510
BANKSEL STATUS_byte
btfss STATUS_byte,0
retlw 0
READ_2510 RXB0SIDL
movwf RecID
rrf RecID
rrf RecID
rrf RecID
rrf RecID
rrf RecID
movf RecID,W
andlw 0x07
movwf RecID
READ_2510 RXB0DLC
andlw 0x0f
movwf Dlen_2510
movwf TempVar1
movlw RXB0D0
movwf Addr_2510
call READ_2510S
MODIFY_2510 CANINTF,b'00000001',b'00000000'
movf TempVar1,W
return
;*************************************************************************************
; Sub : Write_2510S()
; Purpose : Write the data with length Length_2510
; Dlen_2510: The length of Write Data
; Addr_2510: The Start Address of MCP2510
; FSR: The data pointer of Writing Data
; ********** The /CS pin is RB5
;*************************************************************************************
WRITE_2510S
movlw Buf_2510
movwf FSR
BANKSEL PORT_CS2510
bcf CS2510
movlw CMD_WRITE ; Write command of MCP2510
call Write_SPI_Byte
BANKSEL Addr_2510
movf Addr_2510,W
call Write_SPI_Byte ; Starting Address !!
WRITE_2510S_Loop
movf INDF,W ; Move data from @FSR to W
call Write_SPI_Byte ; Write to MCP2510
incf FSR,F ; Point to next address
BANKSEL Dlen_2510
decfsz Dlen_2510,F ; Check the condition of "end of data"
goto WRITE_2510S_Loop
BANKSEL PORT_CS2510
bsf CS2510
return
;*****************************************************************************************
; Sub : Read_2510S()
; Purpose : Read the data with length Length_2510
; Dlen_2510: The length of Read Data
; Addr_2510: The Start Address of MCP2510
; FSR: The data pointer of Reading Data
; ****** The /CS pin is RB5 , Clear it before Write and Set it when finish
;*****************************************************************************************
READ_2510S
movlw Buf_REC
movwf FSR
BANKSEL PORT_CS2510
bcf CS2510
movlw CMD_READ ; Write command of MCP2510
call Write_SPI_Byte
BANKSEL Addr_2510
movf Addr_2510,W
call Write_SPI_Byte ; Starting Address !!
READ_2510S_Loop
movlw 0x00
call Write_SPI_Byte
movwf INDF ; Write to @FSR
incf FSR
BANKSEL Dlen_2510
decfsz Dlen_2510,F ; Check the total data read
goto READ_2510S_Loop
BANKSEL PORT_CS2510
bsf CS2510
return
;*****************************************************************************************
; Sub : InitSSP()
; Initialize SPI Inerface
;*****************************************************************************************
InitSSP
BANKSEL SSPSTAT ; SSPSTAT = 0x94 CKE=0 for mode 00 Operation
bsf SSPSTAT,6
bcf SSPSTAT,7
BANKSEL PORT_CS2510 ; The PORT of CS2510 pin's location !!!!
bsf CS2510
BANKSEL SSPCON ; SSPCON = 0x20
movlw b'00100000' ; CKP=0 , Master Mode with Fosc/4 clock
movwf SSPCON
return
;****************************************************************************************
; PIC16F877 SPI read and write
;****************************************************************************************
Write_SPI_Byte:
BANKSEL SSPBUF
movwf SSPBUF
BANKSEL SSPSTAT ; Switch to SSPSTAT in order to test the BF Flag
Wait_BF
btfss SSPSTAT,BF
goto Wait_BF
BANKSEL SSPBUF ; Read from SSPBUF will update BF Flag Automately !!
movf SSPBUF,W
return
;***************************************************************************
; Delay_MCP2510 :
; Delay
;***************************************************************************
Delay_MCP2510
BANKSEL TempVar1
movlw 0x80
movwf TempVar1
clrf TempVar2
D_Loop1
nop
nop
decfsz TempVar2,F
goto D_Loop1
decfsz TempVar1,F
goto D_Loop1
return
;***************************************************************************
; Int
;***************************************************************************
ISRs:
nop
return
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -