⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 station.asm

📁 CAN的心得和体会。简单实用
💻 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 + -