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

📄 can_ref.asm

📁 该程序是mcp2510通信例子
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;; ----------- MAIN LOOP ----------------------------------
;; --------------------------------------------------------

jMainLoop clrwdt


;;====================== XMIT CODE ========================

          jmpClr    tbTxMsg,jMain10     ; not time to xmit next CAN msg yet
          bcf       tbTxMsg             ; reset xmit flag

     ;; Reload counter
          movlw     2              ; 65 mS units
          movwf     bXmitClk       ; Countdown to xmit next message

          jmpFeqL   bXmitID,0xFF,jMain10 ; Transmission turned off

     ;; Time to xmit next CAN message.  Select source of message and ID
     ;; to use for transmission

;; <<<<< Analog Input Board >>>>>

          jmpFeqL   bNextMsgType,0,Xmit3201   
          jmpFeqL   bNextMsgType,1,XmitRA0   
          goto      jMain8

;********** POT **********     

Xmit3201
          call      Read3201            ; read 3201 AD
          movfw     bSwXmitID           ; Use DIP Tx address for transmission
          movwf     bXmitID
          incf      bNextMsgType,F      ; Next time use next source and ID
          goto      jMain8  

XmitRA0                                 ;; Use Pot as input
          movlw     dA2DRA0             ; fosc/8 clk, RA0, A/D off
          call      ReadA2D             ; Read A/D port in W
          movfw     bSwXmitID           ; Use DIP Tx address for transmission
          addlw     0x01
          movwf     bXmitID
          clrf      bNextMsgType        ; clear next message
          goto      jMain8

jMain8
          
     ;; Wait for pending messages to be sent (ALL BUFFERS)
          bL2bV     0x08,b2510RegMask
          movlw     TXB0CTRL
          call      WaitANDeqZ

     ;; Send CAN message with 
     ;;    ID = bXmitID 
     ;;    Two data bytes: iA2DValue,iA2DValue+1

          SPI_WriteV TXB0SIDH,bXmitID    ; Message ID
          SPI_WriteL TXB0SIDL,0x00       ; Send message - lower bits 0
          SPI_WriteL TXB0DLC,0x02        ; 2 data bytes

     ;; Send least significant byte first
          SPI_WriteV TXB0D0,iA2DValue
          SPI_WriteV TXB0D1,iA2DValue+1
          SPI_Rts   RTS0                ; Transmit buffer 0

jMain10

;;====================== RECEIVE CODE ========================

          call      CheckCANMsg

          jmpClr    tbRxMsgPend,jMainLoop

     ;; new CAN message received

          call      ParseCAN
          bcf       tbRxMsgPend         ; new CAN message received
          goto      jMainLoop

;**********************************************************
;OutputPWM
;       OutputPWM - Uses PWM1 output.
;        
;**********************************************************
OutputPWM    
          movfw     bPWMValue   ; 8 bit PWM value   
          movwf     iA
          clrf      iA+1

     ;; W = 0 - 255.  Load into PWM register.     
     ;; load LOWER 2 bits into CCP1CON bits 5,4
     ;; load UPPER 6 bits (shifted right by 2 ) into CCPR1
     ;; this is high res 8 bit mode (upper 2 bits of 10 bit word are zero)
          movf     iA,W       ; low byte to W
          clrf     iA+1
          rrf      iA,F       ; low bit to carry          
          rrf      iA+1,F      ; move carry into upper bit 
          rrf      iA,F       ; low bit to carry          
          rrf      iA+1,F      ; move carry into upper bit
          rrf      iA+1,F      ; move to 6,5
          rrf      iA+1,W      ; move to 5,4 in W
          andlw    B'00110000'   ; mask other bits
          iorlw    B'00001100'   ; turn on PWM mode
          movwf    CCP1CON       ; set PWM1 and lower 2 bits
     ;; get upper 6 bits
          movf     iA,W
          andlw    B'00111111'   ; mask upper 2 bits
          movwf    CCPR1L           
                              
          return

;**********************************************************
;ReadA2D
;         This functions reads analog input and stores the result 
;         in iA2DValue as a 12 bit value.  Value in W is used to set
;         ADCON0 to select correct port.
;**********************************************************
ReadA2D

     ;; setup A/D to select port, etc
          movwf     ADCON0

     ;; turn on A/D 
          bsf      ADCON0,0        ;A/D on
     ;; allow 50us for settling
          movlw     25
          movwf     bCnt
ReadAD10 
          decfsz    bCnt,F
          goto      ReadAD10

     ;; begin conversion
          bsf       ADCON0,2           ; GO
ReadAD20  jmpSet    ADCON0,2,ReadAD20   ; wait for done bit

          movf      ADRES,W
          movwf     iA2DValue
          clrf      iA2DValue+1

     ;; Convert to 12 bit
          iShiftL   iA2DValue
          iShiftL   iA2DValue
          iShiftL   iA2DValue
          iShiftL   iA2DValue
          return

;******************************************************
;ParseCAN <<<<<INPUTS>>>>>
;         Parse message. Assumes message is two byte 12 bit data.
;         Uses bBaseRecID and bRecIDNext to accept message for PWM output.
;******************************************************
ParseCAN

;********** Analog In Board **********

          movlw     b'00001111'
          andwf     iRecID_H,W
          movwf     iA 
          jmpFeqL   iA,0x0,IDx0             ;check for ID x0
          goto      jParCANRet          

IDx0                                              ;; x0 input send PWM to lamp
     ;; 12 bits of data 
          bV2bV     pRecDataBase,iRecValue
          bV2bV     pRecDataBase+1,iRecValue+1

     ;; new PWM value pending

          bV2bV     iRecValue,iA
          bV2bV     iRecValue+1,iA+1              ; 12 bit received value

     ;; convert to 8 for PWM out
          iShiftR   iA
          iShiftR   iA
          iShiftR   iA
          iShiftR   iA

     ;; Convert to 8 bit
          bV2bV     iA,bPWMValue
          call      OutputPWM    
          goto      jParCANRet

jParCANRet
          return

;******************************************************
;Init2510
;*  Function:   Init_MCP2510()
;*      Place MCP2510 initialization here...
;*******************************************************
Init2510
     ;; Reset 2510
          call      Reset2510

     ;; set CLKOUT prescaler to div by 4
          bL2bV     0x03,b2510RegMask
          bL2bV     0x02,b2510RegData
          movlw     CANCTRL
          call      BitMod2510

;Set physical layer configuration 
;
;     Fosc = 16MHz
;     BRP        =   7  (divide by 8)
;     Sync Seg   = 1TQ
;     Prop Seg   = 1TQ
;     Phase Seg1 = 3TQ
;     Phase Seg2 = 3TQ
;
;    TQ = 2 * (1/Fosc) * (BRP+1) 
;     Bus speed = 1/(Total # of TQ) * TQ
;
          SPI_WriteL CNF1,0x07           ; set BRP to div by 8

;#define BTLMODE_CNF3    0x80
;#define SMPL_1X         0x00
;#define PHSEG1_3TQ      0x10
;#define PRSEG_1TQ       0x00
          SPI_WriteL CNF2,0x90

;#define PHSEG2_3TQ      0x02
          SPI_WriteL CNF3,0x02

;
     ;; Configure Receive buffer 0 Mask and Filters 
     ;; Receive buffer 0 will not be used
          SPI_WriteL RXM0SIDH,0xFF
          SPI_WriteL RXM0SIDL,0xFF

          SPI_WriteL RXF0SIDH,0xFF
          SPI_WriteL RXF0SIDL,0xFF

          SPI_WriteL RXF1SIDH,0xFF
          SPI_WriteL RXF1SIDL,0xFF

     ;; Configure Receive Buffer 1 Mask and Filters 
          SPI_WriteL RXM1SIDH,0xFF 
          SPI_WriteL RXM1SIDL,0xE0

     ;; Initialize Filter 2 to match x0 bBaseRecID from  DIP switch
          SPI_WriteV RXF2SIDH,bBaseRecID
          SPI_WriteL RXF2SIDL,0x00       ; Make sure EXIDE bit (bit 3) is set correctly in filter

     ;; Initialize Filter 3 to match x1 from DIP switch
          incf       bBaseRecID,F
          SPI_WriteV RXF3SIDH,bBaseRecID
          SPI_WriteL RXF3SIDL,0x00

     ;; Initialize Filter 4 to match x2 from DIP switch
          incf       bBaseRecID,F
          SPI_WriteV RXF4SIDH,bBaseRecID
          SPI_WriteL RXF4SIDL,0x00       

     ;; Initialize Filter 5 to match x3 from DIP switch
          incf       bBaseRecID,F
          SPI_WriteV RXF5SIDH,bBaseRecID
          SPI_WriteL RXF5SIDL,0x00       

          movlw     b'11110000'
          andwf     bBaseRecID,F

     ;; Disable all MCP2510 Interrupts
          bL2bV     0x00,b2510RegData
          movlw     CANINTE
          call      Wrt2510Reg

     ;; Sets normal mode
          call      SetNormalMode
          return

;**********************************************************
;ProcessSPI     
;
;**********************************************************
ProcessSPI
          skipSet   bSPICnt,2
     ;; buffer not full yet
          return

     ;; disable SPI interupt
          BANK1
          bcf       _SSPIE_P       ; SSP int enable (BANK 1)
          BANK0


     ;; enable SPI
          BANK1
          bsf       _SSPIE_P  ; SSP int enable (BANK 1)
          BANK0
          return


;*******************************************************************
;WaitMSec
;	Delay W number of Msec Routines (255 max)
;         Actually slightly larger than 1 mS
;*******************************************************************

WaitMSec
	movwf	bCnt		;store Msec -> bCnt

jWaitMSec0
    	clrwdt         		;clear wdt

; TMR1H: 256 uSec tics with maximum of 1/2 rollover = 32.768 msec maximum
          Set1HClock bGenClk,4          ; 256 uS

jWaitMSec1
          jmp1HNotYet bGenClk,jWaitMSec1

          decfsz    bCnt,F
          goto      jWaitMSec0
	return

;
;**********************************************************
;Init
;         Initialize 
;        
;**********************************************************
Init                          
          clrwdt                ; required before changing wdt to timer0

     ;; clear peripheral interrupts
	BANK1
          clrf      PIE1_P
       
     ;; OPTION_REG: PortB Pullups on.
     ;; no prescale for WDT -> should always > 7 mSec  ( 18 mS nominal)
     ;; Timer 0:  Use 64 prescale for 0.27127 * 64 = 17.361 uSec tics 

          movlw     B'01000101'        ; Timer0 prescale 64
          movwf     OPTION_REG_P

     ;; clear bank 0 
          movlw     0x20
          movwf     FSR
jInitClr1 clrf      INDF
          incf      FSR,F
          jmpClr    FSR,7,jInitClr1

     ;; clear bank 1
          movlw     0xA0
          movwf     FSR
jInitClr2 clrf      INDF
          incf      FSR,F
          jmpSet    FSR,7,jInitClr2

          call      InitIO              ;initalize IO of microcontroller

     ;; configure Timer1:
          BANK0
          movlw     B'00000001'     ; Prescale = 1, Timer enabled 
          movwf     T1CON

	BANK1
          bsf       _TMR1IE_P      ; timer1 rollover interrupt enable (page 1)
	BANK0

     ;; init output PWM1 ( uses timer2 )
	BANK0
            ;; Timer2 ( 8 bit timer ) set for 
	movlw    B'00000100'     ; prescale of 1, internal clk, enable timer2
	movwf    T2CON
              ; load PWM counter(PR2) with 0x3F ( 8 bit high res mode)
              ; this gives a 15.625KHz signal with 4MHz crystal
	BANK1
	movlw    0x3F
	movwf    PR2_P             
	BANK0


     ;; for testing
          clrf      TMR1L
          clrf      TMR1H

     ;; turn on interrupts
	BANK0
          movlw    B'11000000'     ; Enable interrupts ( Periphrals only )
          movwf    INTCON

          return


;; INITIALIZE I/O OF MICROCONTROLLER

InitIO
          BANK1
        	movlw    b'00000100'    	;turn on A/D conversion RA0, RA1, RA3  
       	movwf    ADCON1_P

    ;; Port A
    ;;      0  in     <*>A2D input POT<*>
    ;;      1  out(1) 2510 chip select 
    ;;      2  in     <*>open<*>
    ;;      3  in     <*>open<*>
    ;;      4  in     <*>open<*>
    ;;      5  out(1) RST 2510 

          BANK0
	movlw	B'00000010'	;; initialize Port A outputs 
       	movfw  	PORTA       	
          BANK1
        	movlw   	B'11111101'
        	movwf   	TRISA_P         	;; set Port A


    ;; Port B 
    ;;      0  in     Interrupt from 2510
    ;;      1  out(1) <*>CS' MCP3201<*>
    ;;      2  out(1) <*>CS' 25C04<*>
    ;;      3  in     <*>open<*>
    ;;      4  in     <*>open<*>
    ;;      5  in     RX0BF from 2510 
    ;;      6  in     ICD
    ;;      7  in     ICD

          BANK0
	movlw	B'00000110'	;; initialize Port B outputs 
       	movfw  	PORTB       	
          BANK1
      	movlw   	B'11111001'
          movwf     TRISB_P         	;; set Port B

    ;; Port C
    ;;      0  in     DIP #1
    ;;      1  in     DIP #2
    ;;      2  out(0) <*>PWM Out<*>
    ;;      3  out(0) SPI clock - master
    ;;      4  in     SPI data in
    ;;      5  out(0) SPI data out
    ;;      6  in     DIP #3
    ;;      7  in     DIP #4
    
          BANK0
          movlw     B'00000000'
          movwf     PORTC
          BANK1

          movlw     B'11010011'
          movwf     TRISC_P          ;; set Port C

          BANK0
          return

 ifdef ROBUST
;; robust design - force WDT reset
          FILL (goto WDTReset1),(0xFFF-$)
WDTReset1  goto      WDTReset1
 endif


         END

⌨️ 快捷键说明

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