📄 evm2510a.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 + -