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

📄 can_ref.asm

📁 该程序是mcp2510通信例子
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;*******************************************************************
; Microchip CAN Reference Design
;
; Mike Richitelli
; Diversified Engineering
; 283 Indian River Road
; Orange, CT 06477
; (203)799-7875 fax(203)799-7892
; WWW.DIVERSIFIEDENGINEERING.NET 
;
;*******************************************************************
;*******************************************************************

          TITLE " CAN_Ref Design "

;*******************************************************************

dVersion       equ  1
dRelease       equ  5

;======================================================================
; Transmits CAN message every 131 mSec.  Message contains two data bytes
;         that represent a 12 bit value with least significant byte
;         sent first.
; Cycles between three outputs:
;         Pot:  Value goes from 0 to 0xFF0 as Pot is turned clockwise.
;               ID is selected from DIP switches #3 and #4 as follows:
;                   #3 #4  ID
;                   0  0   transmission disabled 
;                   0  1   0x100
;                   1  0   0x200
;                   1  1   0x300
;
;         Push button switch: Switch open => 0, Switch closed => 0xFFF   
;               ID is Pot ID + 0x010
;
;         CdS:  Value goes from 0 to 0xFF0 as Pot is turned clockwise.
;               ID is Pot ID + 0x020
;
; CAN messages received are assumed to be 12 bit data sent as two bytes, 
;         least significant byte first.
;
;         The base ID for receiving CAN messages is specified by DIP 
;         switches #1 and #2:
;                   #1 #2  ID
;                   0  0   0x000
;                   0  1   0x100
;                   1  0   0x200
;                   1  1   0x300
;
;         Lamp: If the message ID matches the ID selected by the DIP 
;               switches the 12 bit data is used to generate a PWM output 
;               where a 0 value gives a zero duty cycle and 0xFFF generates 
;               a 100% duty cycle.  The lamp output is proportional to
;               the duty cycle.
;               ID is Base ID
;
;         LED: On if value received is >= 0x800 and off if < 0x800.
;               ID is Base ID + 0x010
;
;======================================================================

;----- PIC16F876 Micro -----;

          LIST P=16F876
          LIST r=dec,x=on,t=off

#include "P16F876.INC"

  __CONFIG _BODEN_ON&_CP_OFF&_WRT_ENABLE_ON&_PWRTE_ON&_WDT_OFF&_HS_OSC&_DEBUG_OFF&_CPD_OFF&_LVP_OFF
  __IDLOCS (dVersion<<8)|dRelease  ; version: vvrr , vv- version, rr - release

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

#include "MACROS16.INC"
#include "MCP2510.INC"

;          errorlevel 0,-306,-302,-305

 
;******** constants

;Crystal freq 4.00 MHz, Fosc/4 = 1 uS
;
; Timer 1: Uses no prescale => Tic is 1 uSec
;       8 bit rollover 256 uSec
;       16 bit rollover 65.536 mSec

;   8 bit timers
;    TMR1L: 1 uSec tics with maximum of 1/2 rollover = 128 uSec maximum
;    TMR1H: 256 uSec tics with maximum of 1/2 rollover = 32.768 msec maximum



;======================================================================

;************************
; A/D selection ( value of ADCON0 )

#define dA2DRA0     B'01000000'         ; fosc/8 clk, RA0, A/D off
#define dA2DRA3     B'01011000'         ; fosc/8 clk, RA3, A/D off


;************************
; special function defines

#define _SSPEN      SSPCON,SSPEN        ; SPI enable

;************************

;; General control flags definitions

#define tbWork          bGenFlags1,0   ; working bit
#define tbReset         bGenFlags1,1   ; must reset 
#define tbNewSPI        bGenFlags1,2   ; new SPI data available
#define tbRxMsgPend     bGenFlags1,3   ; new CAN message received
#define tbTxMsg         bGenFlags1,4   ; xmit next CAN message
#define tbRC2NowHigh    bGenFlags1,5   ; Robot PWM signal high


;*****************  PIN DEFINITIONS **************************

#define tp2510_CS_   PORTA,1       ; CS_ for 2510 chip

;; I/O 
#define tpSwitch_    PORTB,1       ; Push button switch, Open => high
#define tpLED        PORTB,2       ; LED 

;; Analog In 
#define tpA2D_CS_    PORTB,1       ; CS_ for 3201 A2D chip
#define tpEE_CS_     PORTB,2       ; CS_ for 25040 E2

;*****************  LOCAL REGISTER STORAGE **************************
;
;
;============ BANK 0 =================

 cblock   0x20
     ;; interrupt variables
          bIntSaveSt       ; save Status
          bIntSaveFSR      ; save FSR
          bIntSavPCLATH    ; interrupt storage for PCLATH
          bIntWork         ; working
          iIntWork:2       ; working

     ;; general work space
	bGenFlags1       ; general control flags 1
	bGenFlags2       ; general control flags 2
          bWork            ; work byte
          bWork1           ; work byte 
	iWork:2          ; work integer
	bCnt             ; work byte counter

     ;; Arithmetic
          iA:2             ; 2 byte integer
          iB:2             ; 2 byte integer

     ;; Timer1
          iTimer1:2        ; counts Timer1 rollover   
          bGenClk          ; general clock    
          bXmitClk         ; Countdown to xmit next message

     ;; In/Out variables
          iA2DValue:2      ; 12 bit or 8 bit A2D value   
          bPWMValue        ; 8 bit PWM value   
          iRecValue:2      ; 12 bit received value

     ;; general control
          bSwXmitID        ; ID for transmission from DIP switch
          bBaseRecID       ; ID for reception from DIP switch
          bRecIDNext       ; Rec Base ID + 1
          bXmitID          ; ID for transmission of next msg
          bNextMsgType     ; Select next msg

     ;; Received CAN message
          iRecID_L         ; ID of received message (3 bits left justified)
          iRecID_H         ; ID of received message (8 bits left justified)
          bRecCount        ; number of bytes received
          pRecDataBase:8   ; received data

     ;; Low level SPI interface
          b2510RegAdr      ; Register address
          b2510RegData     ; Data sent/received
          b2510RegMask     ; Bit Mask

       ; following used in interrupt      
          bSPICnt          ; # bytes remaining to receive
          pSPIBuf          ; Pointer into buffer   
          pSPIBufBase:12   ; Base of SPI receive/xmit buffer

 endc


; storage for interrupt service routine
; W saved in one of these locations depending on the page selected 
; at the time the interrupt occured

bIntSaveW0 equ  0x7F       ; interrupt storage for W

;============ BANK 1 =================
bIntSaveW1 equ  0xFF       ; interrupt storage for W

;*******************************************************************
;********** LOCAL MACROS *******************************************
;*******************************************************************
; 
; Shift left 2 byte integer once.
iShiftL macro    iVar
        bcf      _C                ; clear carry bit    
        rlf      iVar,F
        rlf      iVar+1,F
        endm

; Shift right 2 byte integer once.
iShiftR macro    iVar
        bcf      _C               ; clear carry bit    
        rrf      iVar+1,F
        rrf      iVar,F
        endm

; Increment 2 byte integer
intInc  macro   iVar
        incf    iVar,F
        skipNZ
        incf    iVar+1,F
        endm

; 
;; --------------------------------------------------------
;; Set TRM1H 8 bit clock
;    TMR1H: 256 uSec tics with maximum of 1/2 rollover = 32.768 msec maximum
;; --------------------------------------------------------
Set1HClock macro bClk,Value
          movfw     TMR1H
          addlw     Value
          movwf     bClk
          endm

;; --------------------------------------------------------
;; Jump to jLabel if TMR1H (low byte) < bClk
;; --------------------------------------------------------
jmp1HNotYet macro bClk,jLabel

          movfw     TMR1H
          subwf     bClk,W
          andlw     0x80
          jmpZ      jLabel
          endm

;; --------------------------------------------------------
;; Jump to jLabel if TMR1H (low byte) < bClk
;; --------------------------------------------------------
jmp1HDone macro bClk,jLabel

          movfw     TMR1H
          subwf     bClk,W
          andlw     0x80
          jmpNZ     jLabel
          endm


;********************************************************************
;      Begin Program Code
;********************************************************************

          ORG      0x0            ;memory @ 0x0
          nop                     ;nop ICD!!
	goto     HardStart

	ORG     04h             ;Interrupt Vector @ 0x4
;**********************************************************
; Interrupt service routine - must be at location 4 if page 1 is used
; Context save & restore takes ~20 instr
;**********************************************************
     ;; Global int bit, GIE, has been reset.
     ;; W saved in bIntSaveW0 or bIntSaveW1 depending on the bank selected at
     ;; the time the interrupt occured.
          movwf     bIntSaveW0      ; save W in either of two locations 
                                    ; depending on bank currently selected

     ;; only way to preserve Status bits (since movf sets Z) is with a 
     ;; swapf command now
          swapf     STATUS,W        ; Status to W with nibbles swapped
          BANK0
          movwf     bIntSaveSt
          movfw     FSR
          movwf     bIntSaveFSR     ; save FSR
          movf      PCLATH,W 
          movwf     bIntSavPCLATH   ; interrupt storage for PCLATH
          clrf      PCLATH          ; set to page 0

     ;; Must determine source of interrupt

     ;; SPI interrupt
	btfsc    _SSPIF        ; SPI interrupt
	goto     IntSPI

          jmpSet   _TMR1IF,jIntTimer1  ; Timer1 overflow interrupt flag

     ;; unknown
                   
     ;; restore registers and return
IntReturn          
          BANK0
          movf      bIntSavPCLATH,W   ; interrupt storage for PCLATH
          movwf     PCLATH
          movf      bIntSaveFSR,W  ; restore FSR
          movwf     FSR
          swapf     bIntSaveSt,W ; get swapped Status (now unswapped)
          movwf     STATUS       ; W to Status  ( bank select restored )
          swapf     bIntSaveW0,F ; swap original W in place
          swapf     bIntSaveW0,W ; now load and unswap ( no status change)
          retfie                 ; return from interrupt


;***************** ID TABLE ****************************
; Look up ID associated with bits 0,1 in W
RxIDTable addwf    PCL,F           ;Jump to char pointed to in W reg
                                      ;( adds 5bits from PCLATH )
          retlw    0x00  ; 0
          retlw    0x20  ; 1
          retlw    0x10  ; 2
          retlw    0x30  ; 3
RxIDTable_End
#if ( (RxIDTable & 0xF00) != (RxIDTable_End & 0xF00) )
       MESSG   "Warning - Table crosses page boundry in computed jump"
#endif

; Look up ID associated with bits 0,1 in W
TxIDTable addwf    PCL,F           ;Jump to char pointed to in W reg
                                      ;( adds 5bits from PCLATH )
          retlw    0xFF  ; 0
          retlw    0x20  ; 1
          retlw    0x10  ; 2
          retlw    0x30  ; 3
TxIDTable_End
#if ( (TxIDTable & 0xF00) != (TxIDTable_End & 0xF00) )
       MESSG   "Warning - Table crosses page boundry in computed jump"
#endif

;***************** LIBRARY STORAGE & FUNCTIONS ****************************

#include "CanLib.asm"         ; basic 2510 interface routines
#include "a2d3201.asm"        ; MCP3201 AD routines

;***************** Local Interrupt Handlers ****************************

          
;**********************************************************
;jIntTimer1 
;         Timer1 rollover interrupt.
;
;**********************************************************
jIntTimer1  ; Timer1 overflow interrupt flag
          bcf       _TMR1IF        ; timer1 rollover interrupt flag
          intInc    iTimer1

          jmpFeqZ   bXmitClk,IntReturn
          
          decfsz    bXmitClk,F     ; Countdown to xmit next message
          goto      IntReturn

     ; Countdown to xmit next message

          bsf       tbTxMsg        ; xmit next CAN msg     
          goto      IntReturn

;**********************************************************
;IntSPI                                 
; 
; A single buffer, at pSPIBufBase, is used for both SPI receive and
; transmit.  When a byte is removed from the buffer to transmit it is
; replaced by the byte received.  
; 
; When here the buffer pointer, pSPIBuf, points to the last byte loaded 
; for transmission. This is the location that the received byte will be stored.
; 
; When here the count, bSPICnt, contains the number of bytes remaining
; to be received.  This is one less then the number remaining to be
; transmitted.  When bSPICnt reaches zero the transaction is complete.
; 
;         
;**********************************************************
IntSPI    
          bcf       _SSPIF              ; clear interrupt flag

     ;; Transfer received byte to the next location in the buffer
          bV2bV     pSPIBuf,FSR
          incf      pSPIBuf,F

          movfw     SSPBUF              ; get data & clear buffer flag
          movwf     INDF                ; put it into SPI buffer

          decfsz    bSPICnt,F
          goto      jIntSPI1            ; More bytes to send

     ;; Last transaction completed
          bsf       tp2510_CS_           ; CS_ for 2510 chip
          goto      IntReturn

jIntSPI1
     ;; Fetch next byte from buffer and load it for transmission
          incf      FSR,F
          movfw     INDF                ; get byte from buffer
          movwf     SSPBUF              ; send it
          goto      IntReturn


;**********************************************************
;**********************************************************
;**********************************************************

HardStart 
          call      Init

     ;; Make sure no chips are selected
          bsf       tp2510_CS_   ; CS_ for 2510 chip

     ;; Read DIP switch and create bBaseRecID and bSwXmitID

     ;; Rec ID bits are at pins 0,1 of PORTC and are logic high = 1
          movfw     PORTC
          andlw     0x03
          call      RxIDTable
          movwf     bBaseRecID

     ;; Xmit ID bits are at pins 6,7 of PORTC and are logic low = 1
          swapf     PORTC,W
          movwf     bSwXmitID
          rrf	bSwXmitID,F
          rrf	bSwXmitID,W
          andlw     0x03
          call      TxIDTable
          movwf     bSwXmitID


     ;; ----------------- One time calculations ----------------

     ;; Setup SPI port
          call      InitSPIPort

     ;; Wait 28 mS for 2510 to initialize ( there is no significance to 28 mS -
     ;; we just selected a large time since time is not critical)
          Set1HClock bGenClk,100   ; 277.77 uSec tics
jInit5
          jmp1HNotYet bGenClk,jInit5


     ;; Setup all 2510 registers
          call      Init2510

          bsf       tbTxMsg             ; xmit flag

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

⌨️ 快捷键说明

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