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

📄 evm2510a.asm

📁 MCP2510使用范例程序及线路
💻 ASM
字号:
;************************************************
;* EVM2510A.ASM                                 *
;************************************************
;*                                              *
;* Written by:  Calvin Ho                       *
;*              Technical Sales Engineer.       *
;*              Microchip Technology Inc.       *
;* Date:        12 Nov 2000                     *
;* Revision:	1.0                             *
;************************************************
;
;
;
; This source code provides a demonstration of the MSSP peripheral
; on the PIC16F876 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 Byte2 to both PORTD & CCPR1L
; >>  Byte2 contain the ADC result send from Message 100
; >>  CCPR1L is PWM duty cycle register, change it will change the duty cycle of PWM output
; >>  
; >>  

	list p=16f877
	#include <p16f877.inc>
	#include <REG2510.inc>


; Variables used in this program;
	UDATA
 
TempH		RES	1		; TempH & TempL are used for Bin2BCD subroutine
TempL		RES	1		;

TempVar1	RES	1
TempVar2	RES	1

LoopCntr	RES	1

SPI_Temp	RES	1		; Used for SPI Temp in order to keep the content of W reg
Dlen_2510	RES	1
Addr_2510	RES	1
Buf_2510	RES	8

STATUS_2510	RES	1

CAN_PORTD	RES	1
CAN_PWM		RES	1

Temp_ADC	RES	1

;******************************************************************
;****	The location of Flash Registers is BANK3 
;****	Because the EEDATA & EEADR are located @ Bnk 3 
;******************************************************************
 

w_temp		EQU	0x72
status_temp	EQU	0x73
pclath_temp	EQU	0x74 
 			
PORT_CS2510	EQU	PORTC

#define		CS2510	PORTC,0		; RC2 is CS control signal of this 2510 EVM Board !!
#define		MESSAGE_NO1	.250	; 
#define		PWM_DUTY	.255

; 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 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 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

;*******************************************************
;****	END OF MACRO DECALRATION ^^^^^^^^^^^^^^^^^^^^^^^
;*******************************************************

START	CODE	H'000'
	nop
	goto	Prog_Main

SEC_ISR	CODE	H'004'
	goto	ISRs

;----------------------------------------------------------------------

PROG1  	CODE	

Prog_Main   
 
	bcf     OPTION_REG,NOT_RBPU  	; Enable PORTB pull-ups

	BANKSEL	PORTD
	movlw	0x00
	movwf	PORTD
	bsf	PORTB,5
	movlw	0xff
	movwf	PORTC

	BANKSEL	TRISD
	clrf	TRISD

	call 	InitADC
	call	InitSSP
	call	InitPWM
	
 	BANKSEL	LoopCntr
	Clrf	LoopCntr

Main:
	;*********************************************************************
	;**** 	RESET MCP2510 first ******************************************
	;*********************************************************************

	RESET_2510

	call	Delay_MCP2510		; Wait for 128 Cycle
	call	Delay_MCP2510
	call	Delay_MCP2510
	call	Delay_MCP2510

	call	CONFIG_2510

Write_Loop

	; ---- Convert ADC and save the value to Temp_ADC
 	BANKSEL ADCON0
	bsf	ADCON0,GO

Wait_ADC_OK

	BANKSEL	PIR1
	btfss	PIR1,ADIF
	goto	Wait_ADC_OK
	
	bcf	PIR1,ADIF			; Clear AD Complete Flag !1
	movf	ADRESH,W
	movwf	Temp_ADC


	WRITE_2510	TXB0SIDH,(MESSAGE_NO1 >> 3)
 	WRITE_2510	TXB0SIDL,((MESSAGE_NO1 << 5) & b'11100000')
	WRITE_2510	TXB0DLC,0x05				; DLC = 5 Bytes 

	BANKSEL	PORT_CS2510
	bcf	CS2510
	movlw	CMD_WRITE
	call	Write_SPI_Byte
	movlw	TXB0D0				; START FROM TXB0D0, CONTINUOUS WRITE  
	call	Write_SPI_Byte
	movf	LoopCntr,W
	call	Write_SPI_Byte
	movf	Temp_ADC,W		 
	call	Write_SPI_Byte
	movlw	0x88				; TEST PATTERN , ANY VALUE 
	call	Write_SPI_Byte
	movlw	0x34				; TEST PATTERN , ANY VALUE
	call	Write_SPI_Byte
	movlw	0x56				; TEST PATTERN , ANY VALUE
	call	Write_SPI_Byte
	BANKSEL	PORT_CS2510
	bsf	CS2510
	nop	

 	SEND_TXB0				; START TRANSMIT TRANSMIT BUFFER-0
	
	call	Delay_MCP2510

	READ_2510	CANINTF 		; Read from 0x2C , Data @ W register !!

	movwf	STATUS_2510
	btfss	STATUS_2510,0
	goto	No_2510_In

	; ******************************************************************
	; **** Now we get the information that RXB0 contain incoming data !!
	; ******************************************************************

	BANKSEL	PORT_CS2510
	bcf	CS2510
	movlw	CMD_READ
	call	Write_SPI_Byte
	movlw	RXB0D0				; SET ADDRESS !! 
	call	Write_SPI_Byte
	movlw	b'11111111'			; Get RXB0D0
	call	Write_SPI_Byte
	movwf	CAN_PORTD
	movlw	b'11111111'			; Get RXB0D1
	call	Write_SPI_Byte
	movwf	CAN_PWM
	BANKSEL	PORT_CS2510
	bsf	CS2510

	MODIFY_2510	CANINTF,b'00000001',b'00000000'
	
	BANKSEL	PORTD
	movf	CAN_PWM,W
	movwf	PORTD
	movwf	CCPR1L

No_2510_In
	BANKSEL	LoopCntr
	incf	LoopCntr,F
	goto	Write_Loop


CONFIG_2510

	MODIFY_2510	CANCTRL,b'11100000',b'10000000'	; Set to Configure Mode

	MODIFY_2510	CANCTRL,b'00000111',b'00000101'	; Set Clock Out Freq

	WRITE_2510	CNF1,b'00000111'		; Set CNF1 , TQ = 2*8*1/16M = 1us

 	WRITE_2510	CNF2,b'00010000'		; Set CNF2 , PHASE1:3TQ,PRSEG:1TQ

 	WRITE_2510	CNF3,b'00000010'		; Set CNF3 , PHASE2:3TQ

 	WRITE_2510	CANINTE,b'00011111'

 	WRITE_2510	RXB0CTRL,b'01100000'		; RXB0CTRL , Turn Mask off

 	WRITE_2510	RXB1CTRL,b'01100000'		; RXB1CTRL , Turn Mask off
	
 	WRITE_2510	RXM0SIDH,0x00
 	WRITE_2510	RXM0SIDL,0x00
 	WRITE_2510	RXM0EID8,0x00
 	WRITE_2510	RXM0EID0,0x00

	MODIFY_2510	CANCTRL,b'11100000',b'00000000'	; Set to Normal Mode !!

	return	 
 
;****************************************************************************************
Write_SPI_Byte:
	BANKSEL	SSPBUF 
	movwf	SSPBUF
	BANKSEL	SSPSTAT			; Switch to SSPSTAT in order to test the BF Flag
Wait_SSPBF
 	btfss	SSPSTAT,BF	
	goto	Wait_SSPBF

	BANKSEL	SSPBUF			; Read from SSPBUF will update BF Flag Automately !!
	movf	SSPBUF,W
	return
 

;*************************************************************************************
;	Sub : Write_2510()
;	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 : Write_2510()
;	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_2510
	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		 
				

InitSSP
	BANKSEL	SSPSTAT			; SSPSTAT = 0x94 CKE=0 for mode 00 Operation 
	bsf	SSPSTAT,6
	bcf	SSPSTAT,7

	movlw	b'11010010'		; RC0=CS2510, RC4=SDI, RC5=SDO
	movwf	TRISC			; RC2 = PWM output 

	BANKSEL	PORT_CS2510		; The PORT of CS2510 pin's location !!!!
	bsf	CS2510
	
	BANKSEL	SSPCON			; SSPCON = 0x14
	movlw	b'00100010'		; CKP=0 , Master Mode with Fosc/64 clock
	movwf	SSPCON
        return

;----------------------------------------------------------------------

;***********************************************************************************
;****	InitPWM ()
;****	The procedure of initial PWM functionality
;****	1. Set PWM period by writing to PR2 (92h)
;****	2. Set PWM duty ycle by writing to CCPR1L and CCP1CON<5:4> (15h & 17h)
;****	3. Make CCP1 pin as output (RC2)
;****	4. Set Timer2 Prescale value and enable timer2 by writing T2CON (12h)
;****	5. Configure the CCP1 Module as PWM operation by writing CCP1CON <5:0> (17h)
;***********************************************************************************

InitPWM
	BANKSEL	PR2
	movlw	PWM_DUTY
	movwf	PR2		; Load to period register of Timer-2
	BANKSEL	CCPR1L
	clrf	CCPR1L
	movlw	B'00000000'	; Set CCP1RL<5:4> to 00 for 8 Bit PWM resolution 
	movwf	CCP1CON
	BANKSEL	TRISC
	bcf	TRISC,2		; RC2 is CCP1 output !!
	BANKSEL	T2CON
	movlw	b'00000101'
	movwf	T2CON
	movlw	b'00001111'
	movwf	CCP1CON		; Set as PWM Mode !! Bit<3:0> = 11XX 
	return


;***********************************************************************************
;****	InitADC ()
;****	Initial ADC as Left Justified and only AN0 used, Vref=Vdd , 
;***********************************************************************************

InitADC				; Initial AD Converter as Left Jus
	BANKSEL	TRISA
	bsf	TRISA,0		; RA0 is Analog Input !!
	movlw	B'01111110'	;
	movwf	ADCON1
	
	BANKSEL	ADCON0
	movlw	B'10000001'
	movwf	ADCON0
	return

ISRs:
	nop
	return


;***************************************************************************
; BOOT_SECTION :
; The code located here is used to download the code from RS-232 Interface
;***************************************************************************

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	

	 

	end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -