0% found this document useful (0 votes)
393 views

Motor Controller Application

This document provides a summary of the code for a motor controller application using a PIC18F4331 microcontroller. It initializes various inputs and outputs including buttons, a quadrature encoder, and a motor driver. It also sets up interrupt service routines for the buttons and encoder, and implements a state machine to control the motor based on button presses.

Uploaded by

Luan Nguyen Viet
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
393 views

Motor Controller Application

This document provides a summary of the code for a motor controller application using a PIC18F4331 microcontroller. It initializes various inputs and outputs including buttons, a quadrature encoder, and a motor driver. It also sets up interrupt service routines for the buttons and encoder, and implements a state machine to control the motor based on button presses.

Uploaded by

Luan Nguyen Viet
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 117

; Motor Controller Application

; 10/16/06 Active LO I/O INTs, PWM on PHASE


; 10/06/06 ajs Derived from Index Table Application
;
; PIC18F4331 I/O
; --------------
; INPUT
; User Interface Digital Input Buttons. Debounce performed by button
hardware
; #1: RE3/MCLR => MCU Reset
; #2: RC4/INT1 =>
; #3: RC5/INT2 =>
; #4: RC3/INT0 =>
;
; Quadrature Encoder Interface Digital Inputs
; RA2 => Index
; RA3 => Channel A
; RA4 => Channel B
;
; OUTPUT
; RB0/PWM0 => A3959 Enable
; RB1/PWM1 => Inverse of PWM0, Activity LED
; RB2 => A3959 Phase
; RB3 => A3959 Extended Mode
;
;
; Operational Variables
; QEI_Flags: QEI Monitoring Flags
; QEI_Flags,0 = Monitoring of QEI Flags is Enabled
; QEI_Flags,1 = Interrupt on Position = Max Count
; QEI_Flags,2 = Max Count Changed
; QEI_Flags,3 = Repeat Run
; QEI_Flags,7 = Rotation Direction Changed

include <P18f4431.INC>

ORG 0x000000

goto RESET_1

ORG 0x000008 ; High Priority Interrupt Vector


goto HI_ISR
;; ORG 0x000018
;; goto LO_ISR

HI_ISR
movwf W_Temp ; W_TEMP is in virtual
bank
movff STATUS,STAT_Temp ; STATUS_TEMP located anywhere
movff BSR,BSR_Temp ; BSR_TMEP located anywhere

;; Check the Utility Timer


btfss INTCON,TMR0IF ; Skip if TMR0IF Flag is Set
goto HI_ISR_1
bcf T0CON,TMR0ON ; Turn off the timer
bcf INTCON,TMR0IF ; Clear the Timer 0 Flag

HI_ISR_1
btfsc INTCON,INT0IF
bsf ButtonPress,3 ; Set RC3 Button Flag
bcf INTCON,INT0IF

btfsc INTCON3,INT1IF ; Skip if INT1 Flag is Clear, else Turn On


RB5 LED
bsf ButtonPress,4 ; Set RC4 Button Flag
bcf INTCON3,INT1IF ; Clear INT1

btfsc INTCON3,INT2IF ; Skip if INT2 Flag is Clear, else Turn On


RB5 LED
bsf ButtonPress,5 ; Set RC5 Button Flag
bcf INTCON3,INT2IF ; Clear INT2

movff BSR_Temp,BSR ; Restore BSR


movff STAT_Temp, STATUS ; Restore STATUS
movwf W_Temp, W ; Restore WREG
retfie FAST

RESET_1
bcf INTCON,GIE ; Disable Global Interrupt
bsf OSCCON,6 ; Kick the INT OSC up to maximum
8MHz with x111xxxx
bsf OSCCON,5
bsf OSCCON,4
clrf ButtonPress ; Clear the Buttons flags
bsf PORTC,RC3 ; Setup PORTC I/O
bsf PORTC,RC4 ; I/O is Active LO
bsf PORTC,RC5
bsf TRISC,RC3 ; RC3/INT0
bsf TRISC,RC4 ; RC4/INT1
bsf TRISC,RC5 ; RC5/INT2

clrf PORTB ; Setup PORTB Output


bcf TRISB,RB0 ; RB0/PWM0 = Output
bcf TRISB,RB1 ; RB1/PWM1 = Output
bcf TRISB,RB2 ; RB2/Phase = Output
bcf TRISB,RB3 ; RB3/Mode = Output
bcf TRISB,RB4

TIMER_INIT
; Utility Timer Initialization
bcf INTCON,TMR0IE ; Disable Timer 0 Interrupt
bcf INTCON,TMR0IF
bcf T0CON,TMR0ON ; Turn off Timer 0
clrf TMR0H
clrf TMR0L
clrf T0CON
bcf T0CON,T016BIT ; Set 16 bit Counter Mode
bcf T0CON,T0CS ; Use Internal Clock
bsf T0CON,PSA ; Prescaler Off
;bcf T0CON,T0PS2
;bcf T0CON,T0PS1
;bcf T0CON,T0PS0
; T0PS2:T0PS0
; 111 =1:256 prescale value
; 110 =1:128 prescale value
; 101 =1:64 prescale value
; 100 =1:32 prescale value
; 011 =1:16 prescale value
; 010 =1:8 prescale value
; 001 =1:4 prescale value
; 000 =1:2 prescale value
bsf INTCON,TMR0IE ; Enable Timer0 Interrupt

QEI_INIT
clrf PORTA ; Setup PORTA I/O
; QEI Inputs
bcf ANSEL0,ANS2 ; RA2/Index = Digital
bsf TRISA,RA2 ; RA2 = Input
bcf ANSEL0,ANS3 ; RA3/QEA = Digital
bsf TRISA,RA3 ; RA3 = Input
bcf ANSEL0,ANS4 ; RA4/QEB = Digital
bsf TRISA,RA4 ; RA4 = Input

clrf QEI_Flags ; Clear QEI Monitoring Flags


clrf POSCNTL ; Clear Position Counter
clrf POSCNTH
movlw 0xFF ; Set Counter Maximum to 0xFFFF
movwf MAXCNTH
movlw 0x99 ; Set Counter Maximum to 0xFFFF
movwf MAXCNTL

clrf QEICON ; Reset QEI Configuration


bsf QEICON,VELM ; Turn Off Velocity Measurement Mode
bsf QEICON,QEIM1 ; Set for 2x and Max Count reset

bsf IPR3,IC3DRIP ; QEI Dir INT = High Priority


bsf IPR3,IC2QEIP ; QEI INT = High Priority
bcf PIR3,IC3DRIF ; Clear QEI Interrupt Flag bits
bcf PIR3,IC2QEIF
QEI_INIT_END

PWM_INIT
clrf Stop_Div

clrf PWMCON0 ; Disable PWM, clear configuration


bcf PTCON1,PTEN ; Disable PWM Timer
clrf PTCON0 ; Clear PWM Timer

movlw 0x0F ; Set the 12 bits PERIOD to Maximum


movwf PTPERH
movlw 0xFF
movwf PTPERL

bcf PWMCON0,PWMEN0 ; Turn Off Motor

; Put the A39 in Sleep Mode


clrf A39_ ; Clear Motor Driver Flag Register
bsf A39_,A_Sleep
bsf PORTB,RB2 ; HI ENABLE (off)
bsf PORTB,RB3 ; HI MODE
bsf PORTB,RB4 ; HI BREAK (off)

clrf Motor_Speed ; Reset Motor_Speed Variable


movlw 0x1F ; 8191=1FFF 50% Duty Cycle for PHASE PWM
movwf PDC0H
movlw 0xFF
movwf PDC0L

bcf PORTB,RB4 ; Clear Speed LEDs


bcf PORTB,RB5

movlw 0x20
movwf PTCON0
;bit 7-4 PTOPS3:PTOPS0: PWM Time Base Output Postscale Select bits
;0000 =1:1 Postscale
;0001 =1:2 Postscale
;1111 =1:16 Postscale
;bit 3-2 PTCKPS1:PTCKPS0: PWM Time Base Input Clock Prescale Select
bits
;00 =PWM time base input clock is Fosc/4 (1:1 prescale)
;01 =PWM time base input clock is Fosc/16 (1:4 prescale)
;10 =PWM time base input clock is Fosc/64 (1:16 prescale)
;11 =PWM time base input clock is Fosc/256 (1:64 prescale)

bcf PTCON0,PTMOD1 ; Continuous Up/Down Mode


bcf PTCON0,PTMOD0 ; Set to 1 for PTIF Interrupt Enable
bcf PIE3,PTIE ; Disable PTIF Interrupt
bcf PIR3,PTIF ; Clear PWM Flag
bsf PTCON1,PTEN
bcf PWMCON0,PMOD0 ; PWM0, PWM1 Independent Mode

PWM_INIT_END

RESET_1_INT_ON
; Setup RC3/INT0
bsf INTCON3,INT2IE ; Enable INT2 Interrupt
bcf INTCON,INT0IF ; Clear INT0
bsf INTCON,INT0IE ; Enable INT0 Interrupt
bcf INTCON2,INTEDG0 ; Set External I/O INTs to Trailing Edge
bcf INTCON2,INTEDG1
bcf INTCON2,INTEDG2
; Setup RC4/INT1 Interupt
bcf INTCON3,INT1IF ; Clear INT1
bsf INTCON3,INT1IP ; Set INT1 to High Priority
bsf INTCON3,INT1IE ; Enable INT1 Interrupt

; Setup RC5/INT2
bcf INTCON3,INT2IF ; Clear INT2
bsf INTCON3,INT2IP ; Set INT2 to High Priority
bsf INTCON3,INT2IE ; Enable INT2 Interrupt

bsf PIE3,IC2QEIE ; Enable QEI Interupts


bcf RCON,IPEN ; Disable Interrupt Priority
bsf INTCON,PEIE ; Enable Peripheral Interrupts
bsf INTCON,GIE ; Enable Global Interrupt

;;;; Main Program Loop ;;;;


PROG_LOOP

;;---- Button Press States ----;;

BUTTON_RC3_CHECK
btfss ButtonPress,3
goto BUTTON_RC4_CHECK

BUTTON_RC3_PRESSED
bcf INTCON,GIE ; Disable Global Interrupts
btfss KeyBounce,3 ; Check Bounce Setting
goto RC3_SET_TIMER ; Set Bounce Timer
goto RC3_CHECK_TIMER

RC3_SET_TIMER
; Set Bounce Timer
bsf KeyBounce,3
call BOUNCE_TIMER
goto RC3_DONE

RC3_CHECK_TIMER

btfsc T0CON,TMR0ON ; Check Timer


goto RC3_DONE ; Waiting, Jump to Done
; Time Expired
bcf ButtonPress,3 ; Clear Button Press Flag
bcf KeyBounce,3 ; Clear Bounce Setting
btfsc PORTC,RC3 ; Check RC Again (Active LO)
goto RC3_DONE ; Not Pressed

RC3_PRESSED
;; Do RC3 Stuff Here
btfss A39_,A_Sleep
goto A39_SLEEP_ON

A39_SLEEP_OFF ; -- RUN --
bcf A39_,A_Sleep
bcf PORTB,RB2 ; LO ENABLE (on)
bcf PORTB,RB3 ; LO MODE
bsf PORTB,RB4 ; HI BREAK (off)
bsf PWMCON0,PWMEN0 ; Turn On Motor
goto RC3_DONE

A39_SLEEP_ON
bsf A39_,A_Sleep
bcf PWMCON0,PWMEN0 ; Turn Off Motor
bsf PORTB,RB2 ; HI ENABLE (off)
bsf PORTB,RB3 ; HI MODE
bsf PORTB,RB4 ; HI BREAK (off)
;goto RC3_DONE

RC3_DONE
bsf INTCON,GIE ; Enable Global Interrupts

BUTTON_RC4_CHECK
btfss ButtonPress,4
goto BUTTON_RC5_CHECK

BUTTON_RC4_PRESSED
bcf INTCON,GIE ; Disable Global Interrupts
btfss KeyBounce,4 ; Check Bounce Setting
goto RC4_SET_TIMER ; Set Bounce Timer
goto RC4_CHECK_TIMER

RC4_SET_TIMER
; Set Bounce Timer
bsf KeyBounce,4
call BOUNCE_TIMER
goto RC4_DONE

RC4_CHECK_TIMER
btfsc T0CON,TMR0ON ; Check Timer
goto RC4_DONE ; Waiting, Jump to Done

; Time Expired
bcf ButtonPress,4 ; Clear Button Press Flag
bcf KeyBounce,4 ; Clear Bounce Setting
btfsc PORTC,RC4 ; Check RC Again (Active LO)
goto RC4_DONE ; Not Pressed

RC4_PRESSED
;; Do RC4 Stuff Here
; Increment Through Motor Speed Selection
; We are driving the motor with PWM on PHASE 50% Duty Cycle =
0x1FFF

movlw 0x00
cpfsgt Motor_Speed
goto MSPD_00
addlw 8
cpfsgt Motor_Speed
goto MSPD_01
addlw 1
cpfsgt Motor_Speed
goto MSPD_00
addlw 8
cpfsgt Motor_Speed
goto MSPD_02
goto MS_DONE

MSPD_00
; Pause
movlw 0x1F
movwf PDC0H
movlw 0xFF
movwf PDC0L
goto MS_DONE
MSPD_01
; Forward
movlw 0x04
addwf PDC0H,1
goto MS_DONE

MSPD_02
; Reverse
movlw 0x04
cpfslt PDC0H
goto MSPD_REV1
movlw 0x00
movwf PDC0H
movwf PDC0L
goto MS_DONE

MSPD_REV1
subwf PDC0H,1
goto MS_DONE

MS_DONE
incf Motor_Speed,1
movf Motor_Speed,0
movlw 0x12
cpfseq Motor_Speed ; Skip if Equal 4
goto RC4_DONE

MS_RESET
clrf Motor_Speed

RC4_DONE
bsf INTCON,GIE ; Enable Global Interrupts

BUTTON_RC5_CHECK
btfss ButtonPress,5
goto NEXT_STATE

BUTTON_RC5_PRESSED
bcf INTCON,GIE ; Disable Global Interrupts
btfss KeyBounce,5 ; Check Bounce Setting
goto RC5_SET_TIMER ; Set Bounce Timer
goto RC5_CHECK_TIMER

RC5_SET_TIMER
; Set Bounce Timer
bsf KeyBounce,5
call BOUNCE_TIMER
goto RC5_DONE

RC5_CHECK_TIMER
btfsc T0CON,TMR0ON ; Check Timer
goto RC5_DONE ; Waiting, Jump to Done

; Time Expired
bcf ButtonPress,5 ; Clear Button Press Flag
bcf KeyBounce,5 ; Clear Bounce Setting
btfsc PORTC,RC5 ; Check RC Again
goto RC5_CLEAR ; Not Pressed

RC5_PRESSED
;; Do RC Stuff Here
btg LATB,RB4

RC5_CLEAR
; bcf TRISC,RC5 ; Set RC to output
; bcf LATC,RC5 ; Clear RC
; bsf TRISC,RC5 ; Set RC back to input

RC5_DONE
bsf INTCON,GIE ; Enable Global Interrupts

NEXT_STATE

PROG_LOOP_DONE
goto PROG_LOOP

;;;; Subroutines ;;;;


BOUNCE_TIMER
movlw 0x7F ; Preload the timer to about 16ms
movwf TMR0H
movlw 0x00
movwf TMR0L
bsf T0CON,TMR0ON ; Turn Timer Off
return

; Reserve Memory for F Variables


; ------------------------------
W_Temp res 1 ; Interrupt Registers for Preservation
STAT_Temp res 1
BSR_Temp res 1

Time_Flags res 1 ; Utility Timer Flags


constant TF_WAIT=0 ; Wait for Timer

ButtonPress res 1 ; Button Press Flag for Bounce Testing


KeyBounce res 1 ; Key Bounce Timer Set Flags

Stop_Div res 1 ; Stop Counter Digit


Motor_Speed res 1 ; Motor Speed and Direction Digit

A39_ res 1 ; Motor Driver Flag Register


constant A_Sleep=0 ; Motor Sleep Flag

QEI_Flags res 1 ; QEI_Flags: QEI Monitoring Flags


constant QF_Enable=0 ; QEI_Flags,0 = Monitoring of QEI Flags is
Enabled
constant QF_PosMax=1 ; QEI_Flags,1 = Interrupt on Position = Max
Count
constant QF_MaxChg=2 ; QEI_Flags,2 = Max Count Changed
constant QF_Run=3 ; QEI_Flags,3 = Repeat Run
constant QF_Dir=7 ; QEI_Flags,7 = Rotation Direction Changed

end
Motor Controller Application
; 11/04/06 QEI
; 10/27/06 PWM on ENABLE
; 10/16/06 Active LO I/O INTs, PWM on PHASE
; 10/06/06 ajs Derived from Index Table Application
;
; PIC18F4431 I/O
; --------------
; INPUT
; User Interface Digital Input Buttons. Debounce performed by button
hardware
; #1: RE3/MCLR => MCU Reset
; #2: RC3/INT0 => A3953 Sleep ON/OFF (Motor ON/OFF)
; #3: RC4/INT1 => Motor Speed Select
; #4: RC5/INT2 =>
;
; Quadrature Encoder Interface Digital Inputs
; RA2 => Index
; RA3 => Channel A
; RA4 => Channel B
;
; OUTPUT
; RB0/PWM0 => Not Used
; RB1/PWM1 => A3959 Enable
; RB2 => A3959 Phase
; RB3 => A3959 Extended Mode
;
;
; Operational Variables
; QEI_Flags: QEI Monitoring Flags
; QEI_Flags,0 = Monitoring of QEI Flags is Enabled
; QEI_Flags,1 = Interrupt on Position = Max Count
; QEI_Flags,2 = Max Count Changed
; QEI_Flags,3 = Repeat Run
; QEI_Flags,7 = Rotation Direction Changed

include <P18f4431.INC>

ORG 0x000000

goto RESET_1

ORG 0x000008 ; High Priority Interrupt Vector


goto HI_ISR

;; ORG 0x000018
;; goto LO_ISR

HI_ISR
movwf W_Temp ; W_TEMP is in virtual
bank
movff STATUS,STAT_Temp ; STATUS_TEMP located anywhere
movff BSR,BSR_Temp ; BSR_TMEP located anywhere

; Clear Peripheral Interrupt Flag


bcf PIR3,PTIF

;; Check QEI
btfsc PIR3,IC3DRIF ; Direction Change Interrupt Fired
bsf QEI_Flags,QF_Dir ; Set Direction Changed Flag
bcf PIR3,IC3DRIF ; Clear Direction Change Interrupt Flag

btfsc PIR3,IC2QEIF ; QEI Position = Max Count Interrupt Fired


bsf QEI_Flags,QF_PosMax ; Set Position = Max Count Flag
bcf PIR3,IC2QEIF ; Clear QEI Interrupt Flag

;; Check the Utility Timer


btfss INTCON,TMR0IF ; Skip if TMR0IF Flag is Set
goto HI_ISR_1
bcf T0CON,TMR0ON ; Turn off the timer
bcf INTCON,TMR0IF ; Clear the Timer 0 Flag

HI_ISR_1
btfsc INTCON,INT0IF
bsf ButtonPress,3 ; Set RC3 Button Flag
bcf INTCON,INT0IF

btfsc INTCON3,INT1IF ; Skip if INT1 Flag is Clear, else Turn On


RB5 LED
bsf ButtonPress,4 ; Set RC4 Button Flag
bcf INTCON3,INT1IF ; Clear INT1

btfsc INTCON3,INT2IF ; Skip if INT2 Flag is Clear, else Turn On


RB5 LED
bsf ButtonPress,5 ; Set RC5 Button Flag
bcf INTCON3,INT2IF ; Clear INT2

movff BSR_Temp,BSR ; Restore BSR


movff STAT_Temp, STATUS ; Restore STATUS
movwf W_Temp, W ; Restore WREG
retfie FAST
RESET_1
bcf INTCON,GIE ; Disable Global Interrupt
bsf OSCCON,6 ; Kick the INT OSC up to maximum
8MHz with x111xxxx
bsf OSCCON,5
bsf OSCCON,4

clrf ButtonPress ; Clear the Buttons flags


bsf PORTC,RC3 ; Setup PORTC I/O
bsf PORTC,RC4 ; I/O is Active LO
bsf PORTC,RC5

bsf TRISC,RC2 ; Optical Interrupter Input HI is clear, LO is


Blocked

bsf TRISC,RC3 ; RC3/INT0


bsf TRISC,RC4 ; RC4/INT1
bsf TRISC,RC5 ; RC5/INT2

clrf PORTB ; Setup PORTB Output


bcf TRISB,RB0 ; RB0/PWM0 = Output
bcf TRISB,RB1 ; RB1/PWM1 = Output
bcf TRISB,RB2 ; RB2/Phase = Output
bcf TRISB,RB3 ; RB3/Mode = Output
bcf TRISB,RB4

TIMER_INIT
; Utility Timer Initialization
bcf INTCON,TMR0IE ; Disable Timer 0 Interrupt
bcf INTCON,TMR0IF
bcf T0CON,TMR0ON ; Turn off Timer 0
clrf TMR0H
clrf TMR0L
clrf T0CON
bcf T0CON,T016BIT ; Set 16 bit Counter Mode
bcf T0CON,T0CS ; Use Internal Clock
bsf T0CON,PSA ; Prescaler Off
;bcf T0CON,T0PS2
;bcf T0CON,T0PS1
;bcf T0CON,T0PS0
; T0PS2:T0PS0
; 111 =1:256 prescale value
; 110 =1:128 prescale value
; 101 =1:64 prescale value
; 100 =1:32 prescale value
; 011 =1:16 prescale value
; 010 =1:8 prescale value
; 001 =1:4 prescale value
; 000 =1:2 prescale value
bsf INTCON,TMR0IE ; Enable Timer0 Interrupt

QEI_INIT
clrf PORTA ; Setup PORTA I/O
; QEI Inputs
bcf ANSEL0,ANS2 ; RA2/Index = Digital
bsf TRISA,RA2 ; RA2 = Input
bcf ANSEL0,ANS3 ; RA3/QEA = Digital
bsf TRISA,RA3 ; RA3 = Input
bcf ANSEL0,ANS4 ; RA4/QEB = Digital
bsf TRISA,RA4 ; RA4 = Input

clrf QEI_Flags ; Clear QEI Monitoring Flags


bsf QEI_Flags,QF_Home ; Go to Home first thing
clrf POSCNTL ; Clear Position Counter
clrf POSCNTH
movlw 0xFF ; Set Counter Maximum to 0xFFFF
movwf MAXCNTH
movlw 0x99 ; Set Counter Maximum to 0xFFFF
movwf MAXCNTL

clrf QEICON ; Reset QEI Configuration


bsf QEICON,VELM ; Turn Off Velocity Measurement Mode
bsf QEICON,QEIM1 ; Set for 2x and Max Count reset

bsf IPR3,IC3DRIP ; QEI Dir INT = High Priority


bsf IPR3,IC2QEIP ; QEI INT = High Priority
bcf PIR3,IC3DRIF ; Clear QEI Interrupt Flag bits
bcf PIR3,IC2QEIF
QEI_INIT_END

PWM_INIT
clrf Stop_Divs

clrf PWMCON0 ; Disable PWM, clear configuration


bcf PTCON1,PTEN ; Disable PWM Timer
clrf PTCON0
;We need a 40MHz clock to play with this stuff!
; bit 7-4 PTOPS3:PTOPS0: PWM Time Base Output Postscale Select bits
; 0000 =1:1 Postscale
; 0001 =1:2 Postscale
; 1111 =1:16 Postscale

; bit 3-2 PTCKPS1:PTCKPS0: PWM Time Base Input Clock Prescale


Select bits
; 00 =PWM time base input clock is Fosc/4 (1:1 prescale)
; 01 =PWM time base input clock is Fosc/16 (1:4 prescale)
; 10 =PWM time base input clock is Fosc/64 (1:16 prescale)
; 11 =PWM time base input clock is Fosc/256 (1:64 prescale)

bcf PTCON0,PTMOD1 ; Continuous Up/Down Mode


bcf PTCON0,PTMOD0 ; Set to 1 for PTIF Interrupt Enable

movlw 0x0F ; Set the 12 bits PERIOD to Maximum


movwf PTPERH
movlw 0xFF
movwf PTPERL

bcf PWMCON0,PWMEN0 ; Turn Off Motor

; Put the A39 in Sleep Mode


clrf A39_ ; Clear Motor Driver Flag Register
bsf A39_,A_Sleep
bsf PORTB,RB1 ; HI ENABLE (off)
bsf PORTB,RB3 ; HI MODE
bsf PORTB,RB4 ; HI BREAK (off)

bcf TRISD,RD0
bcf PORTD,RD0

movlw 0x02
movwf Motor_Speed

movlw 0x3F
movwf PDC0H
movlw 0xFF
movwf PDC0L

bcf PIE3,PTIE ; Disable PTIF Interrupt


bcf PIR3,PTIF ; Clear PWM Flag
bsf PTCON1,PTEN
bcf PWMCON0,PMOD0 ; PWM0, PWM1 Independent Mode

PWM_INIT_END
call RESET_INTERRUPTS
goto PROG_LOOP

RESET_INTERRUPTS
; Setup RC3/INT0
bsf INTCON3,INT2IE ; Enable INT2 Interrupt
bcf INTCON,INT0IF ; Clear INT0
bsf INTCON,INT0IE ; Enable INT0 Interrupt

bcf INTCON2,INTEDG0 ; Set External I/O INTs to Trailing Edge


bcf INTCON2,INTEDG1
bcf INTCON2,INTEDG2
; Setup RC4/INT1 Interupt
bcf INTCON3,INT1IF ; Clear INT1
bsf INTCON3,INT1IP ; Set INT1 to High Priority
bsf INTCON3,INT1IE ; Enable INT1 Interrupt

; Setup RC5/INT2
bcf INTCON3,INT2IF ; Clear INT2
bsf INTCON3,INT2IP ; Set INT2 to High Priority
bsf INTCON3,INT2IE ; Enable INT2 Interrupt

bsf PIE3,IC2QEIE ; Enable QEI Interupts


bcf RCON,IPEN ; Disable Interrupt Priority
bsf INTCON,PEIE ; Enable Peripheral Interrupts
bsf INTCON,GIE ; Enable Global Interrupt
return

;;;; Misc Subroutines ;;;

GOTO_HOME
call NUDGE
bcf PIE3,IC2QEIE ; Disable QEI Interupts
bcf RCON,IPEN ; Disable Interrupt Priority
bcf INTCON,PEIE ; Disable Peripheral Interrupts
bcf INTCON,GIE ; Disable Global Interrupt
bcf QEI_Flags,QF_Home ; Clear Homing Flag
bsf QEI_Flags,QF_Nudge ; Set Nudging ON in case we are already Home

movlw 0x02
movwf Motor_Speed
call SPEED_1

bcf A39_,A_Sleep
call RESET_INTERRUPTS
call NUDGE
HOME_RUN
movlw 0x00
btfsc PORTC,RC2
goto HOME_RUN

RESET_QEI
call MOTOR_STOP
clrf POSCNTH
clrf POSCNTL ; Clear Position Counter
movf MAXCNTH,0
movwf CAP3BUFH
movf MAXCNTL,0
movwf CAP3BUFL
clrf POSCNTH
clrf POSCNTL ; Clear Position Counter
clrf CAP2BUFH
clrf CAP2BUFL
call RESET_INTERRUPTS
return

NUDGE
movlw 0x00
movwf TMR0H
movlw 0x00
movwf TMR0L
bsf QEI_Flags,QF_Nudge
bsf T0CON,TMR0ON ; Turn Timer ON
call MOTOR_RUN
NUDGE_RUN
movlw 0x00
btfsc T0CON,TMR0ON
goto NUDGE_RUN
return

SPEED_1
movlw 0x20
movwf PDC0H
;movlw 0x0f
;subwf PDC0H,1
return

SPEED_2
movlw 0x10
movwf PDC0H
;movlw 0x0f
;subwf PDC0H,1
return

SPEED_3
movlw 0x00
movwf PDC0H
movlw 0x00
movwf PDC0L
;movlw 0x0f
;subwf PDC0H,1
return

MOTOR_STOP
;bsf A39_,A_Sleep
bcf PWMCON0,PWMEN0 ; Turn Off Motor
bsf PORTB,RB1 ; HI ENABLE (off)
bsf PORTB,RB3 ; HI MODE
bcf PORTB,RB4 ; BREAK (off)
bcf PORTD,RD0
return

MOTOR_RUN
btfsc A39_,A_Sleep
goto MOTOR_DONE
bcf PORTB,RB1 ; LO ENABLE (on)
bcf PORTB,RB3 ; LO MODE
bsf PORTB,RB4 ; BREAK (ON)
bsf PWMCON0,PWMEN0 ; Turn On Motor
bsf PORTD,RD0
bsf QEI_Flags,QF_Run ; Set the QEI Run Flag
MOTOR_DONE
return

;;;; Main Program Loop ;;;;


PROG_LOOP

;;---- Button Press States ----;;

BUTTON_RC3_CHECK
btfss ButtonPress,3
goto BUTTON_RC4_CHECK

BUTTON_RC3_PRESSED
bcf INTCON,GIE ; Disable Global Interrupts
btfss KeyBounce,3 ; Check Bounce Setting
goto RC3_SET_TIMER ; Set Bounce Timer
goto RC3_CHECK_TIMER

RC3_SET_TIMER
; Set Bounce Timer
bsf KeyBounce,3
call BOUNCE_TIMER
goto RC3_DONE

RC3_CHECK_TIMER

btfsc T0CON,TMR0ON ; Check Timer


goto RC3_DONE ; Waiting, Jump to Done

; Time Expired
bcf ButtonPress,3 ; Clear Button Press Flag
bcf KeyBounce,3 ; Clear Bounce Setting
btfsc PORTC,RC3 ; Check RC Again (Active LO)
goto RC3_DONE ; Not Pressed

RC3_PRESSED
;; Do RC3 Stuff Here
btfsc PWMCON0,PWMEN0
goto A39_SLEEP_ON
A39_SLEEP_OFF ; -- RUN --
bcf A39_,A_Sleep
bsf INTCON,GIE ; Enable Global Interrupts
call NUDGE
call MOTOR_RUN
;bcf PORTB,RB1 ; LO ENABLE (on)
;bcf PORTB,RB3 ; LO MODE
;bsf PORTB,RB4 ; BREAK (ON)
;bsf PWMCON0,PWMEN0 ; Turn On Motor
;bsf PORTD,RD0
goto RC3_DONE

A39_SLEEP_ON
bsf A39_,A_Sleep
call MOTOR_STOP
;bcf PWMCON0,PWMEN0 ; Turn Off Motor
;bsf PORTB,RB1 ; HI ENABLE (off)
;bsf PORTB,RB3 ; HI MODE
;bcf PORTB,RB4 ; BREAK (off)
;bcf PORTD,RD0
;goto RC3_DONE

RC3_DONE
bsf INTCON,GIE ; Enable Global Interrupts

BUTTON_RC4_CHECK
btfss ButtonPress,4
goto BUTTON_RC5_CHECK

BUTTON_RC4_PRESSED
bcf INTCON,GIE ; Disable Global Interrupts
btfss KeyBounce,4 ; Check Bounce Setting
goto RC4_SET_TIMER ; Set Bounce Timer
goto RC4_CHECK_TIMER

RC4_SET_TIMER
; Set Bounce Timer
bsf KeyBounce,4
call BOUNCE_TIMER
goto RC4_DONE
RC4_CHECK_TIMER
btfsc T0CON,TMR0ON ; Check Timer
goto RC4_DONE ; Waiting, Jump to Done

; Time Expired
bcf ButtonPress,4 ; Clear Button Press Flag
bcf KeyBounce,4 ; Clear Bounce Setting
btfsc PORTC,RC4 ; Check RC Again (Active LO)
goto RC4_DONE ; Not Pressed

RC4_PRESSED
;; Do RC4 Stuff Here
; Increment Through Motor Speed Selection
; We are driving the motor with PWM on ENABLE

movlw 0x00
cpfsgt Motor_Speed
goto MSPD_PAUSE
addlw 1
cpfsgt Motor_Speed
goto MSPD_FORWARD_1
addlw 1
cpfsgt Motor_Speed
goto MSPD_FORWARD_2
addlw 1
cpfsgt Motor_Speed
goto MSPD_FORWARD_3

addlw 1
cpfsgt Motor_Speed
goto MSPD_PAUSE

addlw 1
cpfsgt Motor_Speed
goto MSPD_REVERSE_1
addlw 1
cpfsgt Motor_Speed
goto MSPD_REVERSE_2
addlw 1
cpfsgt Motor_Speed
goto MSPD_REVERSE_3
goto MS_DONE
MSPD_PAUSE
movlw 0x3F
movwf PDC0H
movlw 0xFF
movwf PDC0L
goto MS_DONE

MSPD_FORWARD_1
bcf LATB,RB2
call SPEED_1
goto MS_DONE

MSPD_FORWARD_2
bcf LATB,RB2
call SPEED_2
goto MS_DONE

MSPD_FORWARD_3
bcf LATB,RB2
call SPEED_3
goto MS_DONE

MSPD_REVERSE_1
bsf LATB,RB2
call SPEED_1
goto MS_DONE

MSPD_REVERSE_2
bsf LATB,RB2
call SPEED_2
goto MS_DONE

MSPD_REVERSE_3
bsf LATB,RB2
call SPEED_3
goto MS_DONE

MS_DONE
incf Motor_Speed,1
movf Motor_Speed,0
movlw 0x08
cpfseq Motor_Speed ; Skip if Equal 4
goto RC4_DONE

MS_RESET
clrf Motor_Speed

RC4_DONE
bsf INTCON,GIE ; Enable Global Interrupts

BUTTON_RC5_CHECK
btfss ButtonPress,5
goto NEXT_STATE

BUTTON_RC5_PRESSED
bcf INTCON,GIE ; Disable Global Interrupts
btfss KeyBounce,5 ; Check Bounce Setting
goto RC5_SET_TIMER ; Set Bounce Timer
goto RC5_CHECK_TIMER

RC5_SET_TIMER
; Set Bounce Timer
bsf KeyBounce,5
call BOUNCE_TIMER
goto RC5_DONE

RC5_CHECK_TIMER
btfsc T0CON,TMR0ON ; Check Timer
goto RC5_DONE ; Waiting, Jump to Done

; Time Expired
bcf ButtonPress,5 ; Clear Button Press Flag
bcf KeyBounce,5 ; Clear Bounce Setting
btfsc PORTC,RC5 ; Check RC Again
goto RC5_DONE ; Not Pressed

RC5_PRESSED
;; Select Stop Divisions
; Reset Position Counters
clrf POSCNTL ; Clear Position Counter
clrf POSCNTH

clrf QEI_Flags ; Clear QEI Monitoring Flags


bsf QEI_Flags,QF_Enable ; Set QEI Monitoring ON as default
bsf QEI_Flags,QF_MaxChg ; Set QEI Max Count Changed Flag

bcf PIR3,IC3DRIF ; Clear QEI Interrupt Flag bits


bcf PIR3,IC2QEIF

;;; Increment Divisions Setting Variable


movlw 0x00
cpfsgt Stop_Divs
goto DIV_180
addlw 1
cpfsgt Stop_Divs
goto DIV_90
addlw 1
cpfsgt Stop_Divs
goto DIV_60
addlw 1
cpfsgt Stop_Divs
goto DIV_45
addlw 1
cpfsgt Stop_Divs
goto DIV_30
addlw 1
cpfsgt Stop_Divs
goto DIV_10
addlw 1
cpfsgt Stop_Divs
goto DIV_01
addlw 1
cpfsgt Stop_Divs
goto DIV_RESET
goto DIV_DONE

DIV_180
movlw 0xFF ; 65433.6 = 0xFF99
movwf MAXCNTH ; Set Counter Maximum
movlw 0x99
movwf MAXCNTL
goto DIV_DONE

DIV_90
movlw 0x7F ; 32716.8 = 0x7FCC
movwf MAXCNTH
movlw 0xCC
movwf MAXCNTL
goto DIV_DONE

DIV_60
movlw 0x55
movwf MAXCNTH
movlw 0x32
movwf MAXCNTL
goto DIV_DONE

DIV_45
movlw 0x3F ; 16358.4 = 0x3FE6
movwf MAXCNTH
movlw 0xE6
movwf MAXCNTL
goto DIV_DONE

DIV_30
movlw 0x2A ; 10905.6 = 0x2A99
movwf MAXCNTH
movlw 0x99
movwf MAXCNTL
goto DIV_DONE

DIV_10
movlw 0x0A
movwf MAXCNTH
movlw 0xA6
movwf MAXCNTL
goto DIV_DONE

DIV_01
movlw 0x00 ; 181.76 = 0x00B5
movwf MAXCNTH
movlw 0xAA
movwf MAXCNTL
goto DIV_DONE

DIV_DONE
incf Stop_Divs,1
movf Stop_Divs,0
movlw 0x08
cpfseq Stop_Divs
goto RC5_DONE

DIV_RESET ; None of the Above, Set Manual Mode


bcf QEI_Flags,QF_Enable ; Turn Off QEI Monitoring
clrf Stop_Divs
bsf QEI_Flags,QF_Home ; Go Home

RC5_DONE
bsf QEI_Flags,QF_MaxChg ; Clear QEI Max Changed
bsf INTCON,GIE ; Enable Global Interrupts

NEXT_STATE

CHECK_HOME
btfss QEI_Flags,QF_Home
goto CHECK_QEI_0
call GOTO_HOME

CHECK_QEI_0 ; *** QEI Direction Change ***


btfss QEI_Flags,QF_Enable
goto CHECK_QEI_1

STATE_QEI_0
bcf INTCON,GIE ; Disable Global Interrupt
bcf QEI_Flags,QF_Dir ; Clear Direction Change Flag
; btfss QEI_Flags,QF_Enable ; Check for QEI Monitoring
; goto QEI_0_DONE ; Not monitoring QEI. exit
;;;; QEI_Monitoring in effect: Do Direction Change Stuff Here
;;;; ...
;QEI_0_DONE
bsf INTCON,GIE ; Enable Global Interrupt

CHECK_QEI_1 ; *** QEI Position = Max Count ***


btfss QEI_Flags,QF_PosMax
goto RUN_OVER_CHECK

STATE_QEI_1
bcf INTCON,GIE ; Disable Global Interrupt
btfss QEI_Flags,QF_Enable ; Check for QEI Monitoring Enabled
goto QEI_1_DONE ; Not Monitoring QEI, Exit to keep running

btfsc QEI_Flags,QF_MaxChg ; Check for NOT Max Count Changed


goto QEI_1_DONE ; Max Count was changed. Exit to keep running

btfsc QEI_Flags,QF_Run ; Check for NOT Run Flag = STOP


goto QEI_RUN ; Run

QEI_1_STOP_RUN
call MOTOR_STOP
movf MAXCNTH,0
movwf CAP3BUFH
movf MAXCNTL,0
movwf CAP3BUFL
clrf POSCNTH
clrf POSCNTL ; Clear Position Counter
bsf QEI_Flags,QF_MaxChg ; Clear QEI Max Changed

QEI_RUN
bcf QEI_Flags,QF_Run ; Clear Run Flag

QEI_1_DONE
bcf QEI_Flags,QF_MaxChg ; Clear QEI Max Changed
bcf QEI_Flags,QF_PosMax ; Clear QEI Position = Max Count Flag

RUN_OVER_CHECK
btfsc PORTC,RC2
goto PROG_LOOP_DONE

;; Optical Interrupter Interrupted


bcf INTCON,GIE ; Disable Global Interrupt
SET_HOME_POS
call MOTOR_STOP
movf MAXCNTH,0
movwf QEI_MAXH
movf MAXCNTL,0
movwf QEI_MAXL
movf QEI_MAXH,0
movwf MAXCNTH
movwf CAP3BUFH
movf QEI_MAXL,0
movwf MAXCNTL
movwf CAP3BUFL
clrf POSCNTH
clrf POSCNTL ; Clear Position Counter
bcf QEI_Flags,QF_MaxChg ; Clear QEI Max Changed

RUN_OVER_DONE
bsf INTCON,GIE ; Enable Global Interrupt

PROG_LOOP_DONE
bsf INTCON,GIE ; Enable Global Interrupt
goto PROG_LOOP

;;;; Subroutines ;;;;


BOUNCE_TIMER
movlw 0x7F ; Preload the timer to about 16ms
movwf TMR0H
movlw 0x00
movwf TMR0L
bsf T0CON,TMR0ON ; Turn Timer Off
return

; Reserve Memory for F Variables


; ------------------------------
W_Temp res 1 ; Interrupt Registers for Preservation
STAT_Temp res 1
BSR_Temp res 1

Time_Flags res 1 ; Utility Timer Flags


constant TF_WAIT=0 ; Wait for Timer

ButtonPress res 1 ; Button Press Flag for Bounce Testing


KeyBounce res 1 ; Key Bounce Timer Set Flags

Stop_Divs res 1 ; Stop Division Setting


Motor_Speed res 1 ; Motor Speed and Direction Digit

A39_ res 1 ; Motor Driver Flag Register


constant A_Sleep=0 ; Motor Sleep Flag
QEI_MAXH res 1
QEI_MAXL res 1

QEI_Flags res 1 ; QEI_Flags: QEI Monitoring Flags


constant QF_Enable=0 ; QEI_Flags,0 = Monitoring of QEI Flags is
Enabled
constant QF_PosMax=1 ; QEI_Flags,1 = Interrupt on Position = Max
Count
constant QF_MaxChg=2 ; QEI_Flags,2 = Max Count Changed
constant QF_Run=3 ; QEI_Flags,3 = Repeat Run
constant QF_Home=4 ; QEI_Flags,4 = Home
constant QF_Nudge=5 ; QEI_Flags,5 = Nudge
constant QF_Dir=7 ; QEI_Flags,7 = Rotation Direction Changed

end
; Index Table Motor Controller Application
; 09/23/06 ajs Initial Application Template
;
; PIC18F4431 I/O
; --------------
; INPUT
; User Interface Digital Input Buttons. Debounce performed by button
hardware
; #1: RE3/MCLR => MCU Reset
; #2: RC4/INT1 => Stop Divisions Count
; #3: RC5/INT2 => Motor Speed and Direction
; #4: RC3/INT0 => Run
;
; Quadrature Encoder Interface Digital Inputs
; RA2 => Index
; RA3 => Channel A
; RA4 => Channel B
;
; OUTPUT
; RB0/PWM0 => A3959 Enable
; RB1/PWM1 => Inverse of PWM0, Activity LED
; RB2 => A3959 Phase
; RB3 => A3959 Extended Mode
;
; RD
;
; Operational Variables
; QEI_Flags: QEI Monitoring Flags
; QEI_Flags,0 = Monitoring of QEI Flags is Enabled
; QEI_Flags,1 = Interrupt on Position = Max Count
; QEI_Flags,2 = Max Count Changed
; QEI_Flags,3 = Repeat Run
; QEI_Flags,7 = Rotation Direction Changed

include <P18f4431.INC>

ORG 0x000000 ; MCLR Reset Entry Point Vector


goto RESET_1 ; Jump to Initialization

ORG 0x000008 ; High Priority Interrupt Vector


goto HI_ISR

ORG 0x000018 ; Low Priority Interrupt


goto LO_ISR

HI_ISR ; High Priority Interrupt


Service Routine
movwf W_Temp ; W_TEMP is in virtual
bank
movff STATUS,STAT_Temp ; STATUS_TEMP located anywhere
movff BSR,BSR_Temp ; BSR_TMEP located anywhere

btfsc INTCON3,INT1IF ; Skip if INT1 Flag is Clear, else Turn On


RB5 LED
bsf Buttons,4 ; Set Button Flag 4
bcf INTCON3,INT1IF ; Clear INT1

btfsc INTCON3,INT2IF ; Skip if INT2 Flag is Clear, else Turn On


RB5 LED
bsf Buttons,5
bcf INTCON3,INT2IF ; Clear INT2

btfsc INTCON,INT0IF
bsf Buttons,3 ; Set Button Flag 3
bcf INTCON,INT0IF

movff BSR_Temp,BSR ; Restore BSR


movff STAT_Temp, STATUS ; Restore STATUS
movwf W_Temp, W ; Restore WREG
retfie FAST

LO_ISR ; Low Priority Interrupts


movwf W_Temp ; W_TEMP is in virtual
bank
movff STATUS,STAT_Temp ; STATUS_TEMP located anywhere
movff BSR,BSR_Temp ; BSR_TMEP located anywhere

bcf PIR3,PTIF

btfsc PIR3,IC3DRIF ; Direction Change Interrupt Fired


bsf QEI_Flags,QF_Dir ; Set Direction Changed Flag
bcf PIR3,IC3DRIF ; Clear Direction Change Interrupt Flag

btfsc PIR3,IC2QEIF ; QEI Position = Max Count Interrupt Fired


bsf QEI_Flags,QF_PosMax ; Set Position = Max Count Flag
bcf PIR3,IC2QEIF ; Clear QEI Interrupt Flag

movff BSR_Temp,BSR ; Restore BSR


movff STAT_Temp, STATUS ; Restore STATUS
movwf W_Temp, W ; Restore WREG
retfie FAST

RESET_1 ; Reset
Initialization
bcf INTCON,GIE ; Disable Global Interrupt
bsf OSCCON,6 ; Kick the INT OSC up to maximum
8MHz with x111xxxx
bsf OSCCON,5
bsf OSCCON,4

clrf Buttons ; Clear the Buttons flags

clrf PORTA ; Setup PORTA I/O


; QEI Inputs
bcf ANSEL0,ANS2 ; RA2/Index = Digital
bsf TRISA,RA2 ; RA2 = Input
bcf ANSEL0,ANS3 ; RA3/QEA = Digital
bsf TRISA,RA3 ; RA3 = Input
bcf ANSEL0,ANS4 ; RA4/QEB = Digital
bsf TRISA,RA4 ; RA4 = Input
clrf PORTB ; Setup PORTB Output
bcf TRISB,RB0 ; RB0/PWM0 = Output
bcf TRISB,RB1 ; RB1/PWM1 = Output
bcf TRISB,RB2 ; RB2/Phase = Output
bcf TRISB,RB3 ; RB3/Mode = Output

bcf TRISB,RB4 ; RB4/Speed Select bit 0


bcf TRISB,RB5 ; RB5/Speed Select bit 1

clrf PORTD ; Setup PORTD I/O


bcf TRISD,RD4 ; Digit LED Segments Output
bcf TRISD,RD5
bcf TRISD,RD6
bcf TRISD,RD7
clrf LATD

bcf PORTC,RC3 ; Setup PORTC I/O


bcf PORTC,RC4
bcf PORTC,RC5
bsf TRISC,RC3 ; RC3/INT0 = Step Counter
bsf TRISC,RC4 ; RC4/INT1 = Motor Speed and Direction
bsf TRISC,RC5 ; RC5/INT2 = Run

QEI_INIT
clrf QEI_Flags ; Clear QEI Monitoring Flags
clrf POSCNTL ; Clear Position Counter
clrf POSCNTH
movlw 0xFF ; Set Counter Maximum to 0xFFFF
movwf MAXCNTH
movlw 0x99 ; Set Counter Maximum to 0xFFFF
movwf MAXCNTL

clrf QEICON ; Reset QEI Configuration


bsf QEICON,VELM ; Turn Off Velocity Measurement Mode
bsf QEICON,QEIM1 ; Set for 2x and Max Count reset

bcf IPR3,IC3DRIP ; QEI Dir INT = Low Priority


bcf IPR3,IC2QEIP ; QEI INT = Low Priority
bcf PIR3,IC3DRIF ; Clear QEI Interrupt Flag bits
bcf PIR3,IC2QEIF
PWM_INIT
clrf Motor_Digit
clrf Stop_Digit

clrf PWMCON0 ; Disable PWM, clear configuration


bcf PTCON1,PTEN ; Disable PWM Timer
clrf PTCON0 ; Clear PWM Timer

movlw 0x0F ; Set the 12 bits PERIOD to Maximum


movwf PTPERH
movlw 0xFF
movwf PTPERL

movlw 0x00 ; Set the PWM 12 bits Duty Cycle to 0


movwf PDC0H

bcf PORTB,RB4 ; Clear Speed LEDs


bcf PORTB,RB5

bcf PTCON0,PTMOD1 ; Continuous Up/Down Mode


bcf PTCON0,PTMOD0 ; Set to 1 for PTIF Interrupt Enable
bcf PIE3,PTIE ; Disable PTIF Interrupt
bcf PIR3,PTIF ; Clear PWM Flag
bsf PTCON1,PTEN
bcf PWMCON0,PMOD0 ; PWM0, PWM1 Independent Mode

; Setup RC4/INT1 Interupt


bcf INTCON3,INT1IF ; Clear INT1
bsf INTCON3,INT1IP ; Set INT1 to High Priority
bsf INTCON3,INT1IE ; Enable INT1 Interrupt

; Setup RC5/INT2
bcf INTCON3,INT2IF ; Clear INT2
bsf INTCON3,INT2IP ; Set INT2 to High Priority
bsf INTCON3,INT2IE ; Enable INT2 Interrupt

; Setup RC3/INT0
bsf INTCON3,INT2IE ; Enable INT2 Interrupt
bcf INTCON,INT0IF ; Clear INT0
bsf INTCON,INT0IE ; Enable INT0 Interrupt

bsf PIE3,IC2QEIE ; Enable QEI Interupts


bsf RCON,IPEN ; Enable Interrupt Priority
bsf INTCON,PEIE ; Enable Peripheral Interrupts
bsf INTCON,GIE ; Enable Global Interrupt

PROG_LOOP ; CHECK_BTN_1 Reset Initialization

CHECK_RC4_INT1 ; *** Set the Divisions to Stop At ***

btfss Buttons,4 ; Check for RC4/INT1 Button Flag


goto CHECK_RC5_INT2 ; flag not set, goto next run check

STATE_RC4_INT1 ; RC4/INT1 Button Flag set,


process
bcf INTCON,GIE ; Disable Global Interrupt
bcf TRISC,RC4 ; Set RC4 to output
bcf PORTC,RC4 ; Clear RC4
bsf TRISC,RC4 ; Set RC4 back to input

; Reset Position Counters


clrf POSCNTL ; Clear Position Counter
clrf POSCNTH

clrf QEI_Flags ; Clear QEI Monitoring Flags


bsf QEI_Flags,QF_Enable ; Set QEI Monitoring ON as default
bsf QEI_Flags,QF_MaxChg ; Set QEI Max Count Changed Flag

bcf PIR3,IC3DRIF ; Clear QEI Interrupt Flag bits


bcf PIR3,IC2QEIF

;;; Increment Divisions Setting Variable


movlw 0x10
addwf LATD

D_360
movf LATD,0 ; Get the current Div Stop Setting
xorlw 0x10 ; XOR with 0x10 = 360 deg
tstfsz WREG ; Test
goto D_180 ; Not Zero so try 180 deg
movlw 0xFF ; 65433.6 = 0xFF99
movwf MAXCNTH ; Set Counter Maximum
movlw 0x99
movwf MAXCNTL
goto QEI_ENABLE
D_180
movf LATD,0
xorlw 0x20 ; XOR with 0x20 = 180 deg
tstfsz WREG
goto D_90
movlw 0x7F ; 32716.8 = 0x7FCC
movwf MAXCNTH
movlw 0xCC
movwf MAXCNTL
goto QEI_ENABLE

D_90
movf LATD,0
xorlw 0x30 ; XOR with 0x30 = 90 deg
tstfsz WREG
goto D_60
movlw 0x3F ; 16358.4 = 0x3FE6
movwf MAXCNTH
movlw 0xE6
movwf MAXCNTL
goto QEI_ENABLE

D_60
movf LATD,0
xorlw 0x40 ; XOR with 0x40 = 60 deg
tstfsz WREG
goto D_45
movlw 0x2A ; 10905.6 = 0x2A99
movwf MAXCNTH
movlw 0x99
movwf MAXCNTL
goto QEI_ENABLE

D_45
movf LATD,0
xorlw 0x50 ; XOR with 0x50 = 45 deg
tstfsz WREG
goto D_10
movlw 0x1F ; 8179.2 = 0x1FF3
movwf MAXCNTH
movlw 0xF3
movwf MAXCNTL
goto QEI_ENABLE
D_10
movf LATD,0
xorlw 0x60 ; XOR with 0x60 = 10 deg
tstfsz WREG
goto D_01
movlw 0x07 ; 1817.6 = 0x0719
movwf MAXCNTH
movlw 0x19
movwf MAXCNTL
goto QEI_ENABLE

D_01
movf LATD,0
xorlw 0x70 ; XOR with 0x70 = 1 deg
tstfsz WREG
goto D_RESET
movlw 0x00 ; 181.76 = 0x00B5
movwf MAXCNTH
movlw 0xB5
movwf MAXCNTL
goto QEI_ENABLE

D_RESET ; None of the Above, Set Manual Mode


bcf QEI_Flags,QF_Enable ; Turn Off QEI Monitoring
movlw 0x0F ; Reset to Divisions to 0
andwf LATD,1

QEI_ENABLE
bcf Buttons,4 ; Reset Buttons 4 Flag
bsf INTCON,GIE ; Enable Global Interrupt

CHECK_RC5_INT2 ; *** Set the PWM Speed ***


btfss Buttons,5 ; Check for RC5/INT2
goto CHECK_RC3_INT0 ; flag not set, goto next run check

STATE_RC5_INT2 ; RC5/INT2 triggered


bcf INTCON,GIE ; Disable Global Interrupt
bcf TRISC,RC5 ; Set RC5 to output
bcf PORTC,RC5 ; Clear RC5
bsf TRISC,RC5 ; Set RC5 back to input
;;; Increment Motor Speed
movf LATB,0 ; Get the current Motor Speed setting
xorlw 0x30 ; XOR with 0x30 = Maximum
tstfsz WREG ; Test, skip if Zero
goto MS_INCREASE ; If Not Max, then Increase

MS_OFF ; If Max, set to slowest


bcf LATB,RB4
bcf LATB,RB5
movlw 0x00
movwf PDC0H ; Set Duty Cycle
movlw 0x00
movwf PDC0L
goto MS_DONE

MS_INCREASE
movlw 0x10 ; Else Increase Speed
addwf LATB

MS_SLOW
movf LATB,0 ; Get the current Motor Speed setting
xorlw 0x10 ; XOR with 0x10 = Slow
tstfsz WREG ; Test
goto MS_FASTER ; Not Zero so try Faster
movlw 0x0F ; 1535 = 0x5FF
movwf PDC0H ; Set Duty Cycle
movlw 0xFF
movwf PDC0L
goto MS_DONE

MS_FASTER
movf LATB,0
xorlw 0x20 ; XOR with 0x20 = Faster
tstfsz WREG
goto MS_MAX
movlw 0x1F ; 2815 0xAFF
movwf PDC0H
movlw 0xFF
movwf PDC0L
goto MS_DONE

MS_MAX
movf LATB,0
xorlw 0x30 ; XOR with 0x30 = Maximum Speed
tstfsz WREG
goto MS_DONE
movlw 0x2F ; 4095 = 0xFFF
movwf PDC0H
movlw 0xFF
movwf PDC0L
goto MS_DONE

MS_DONE
bcf Buttons,5 ; Reset Buttons 5 Flag
bsf INTCON,GIE ; Enable Global Interrupt

CHECK_RC3_INT0 ; *** RUN / STOP ***


btfss Buttons,3 ; Check for RC3/INT0
goto CHECK_QEI_1 ; flag not set, goto next run state

STATE_RC3_INT0 ; RC3/INT0 triggered


bcf INTCON,GIE ; Disable Global Interrupt
bcf TRISC,RC3 ; Set RC3 to output
bcf PORTC,RC3 ; Clear RC3
bsf TRISC,RC3 ; Set RC3 back to input

btfss QEI_Flags,QF_Enable
goto MANUAL_MODE
; QEI Enabled Mode
bsf PWMCON0,PWMEN0 ; Turn On Motor
goto RUNSTOP_DONE

MANUAL_MODE
btg PWMCON0,PWMEN0 ; Toggle RUN/STOP

RUNSTOP_DONE
btfsc PWMCON0,PWMEN0
bsf QEI_Flags,QF_Run ; If Running, Set the QEI Run Flag

bcf Buttons,3 ; Reset Buttons 3 Flag


bsf INTCON,GIE ; Enable Global Interrupt

CHECK_QEI_0 ; *** QEI Direction Change ***


btfss QEI_Flags,QF_Enable
goto CHECK_QEI_1

STATE_QEI_0
bcf INTCON,GIE ; Disable Global Interrupt
bcf QEI_Flags,QF_Dir ; Clear Direction Change Flag

; btfss QEI_Flags,QF_Enable ; Check for QEI Monitoring


; goto QEI_0_DONE ; Not monitoring QEI. exit

;;;; QEI_Monitoring in effect: Do Direction Change Stuff Here


;;;; ...

;QEI_0_DONE
bsf INTCON,GIE ; Enable Global Interrupt

CHECK_QEI_1 ; *** QEI Position = Max Count ***


btfss QEI_Flags,QF_PosMax
goto FINAL_CHECK

STATE_QEI_1
bcf INTCON,GIE ; Disable Global Interrupt

btfss QEI_Flags,QF_Enable ; Check for QEI Monitoring Enabled


goto QEI_1_DONE ; Not Monitoring QEI, Exit to keep running

btfsc QEI_Flags,QF_MaxChg ; Check for NOT Max Count Changed


goto QEI_1_DONE ; Max Count was changed. Exit to keep running

btfsc QEI_Flags,QF_Run ; Check for NOT Run Flag = STOP


goto QEI_RUN ; Run

QEI_1_STOP_RUN
bcf PWMCON0,PWMEN0 ; Stop PWM

QEI_RUN
bcf QEI_Flags,QF_Run ; Clear Run Flag

QEI_1_DONE
bcf QEI_Flags,QF_MaxChg ; Clear QEI Max Changed
bcf QEI_Flags,QF_PosMax ; Clear QEI Position = Max Count Flag
bsf INTCON,GIE ; Enable Global Interrupt
FINAL_CHECK
goto PROG_LOOP

; Reserve Memory for F Variables


; ------------------------------
W_Temp res 1 ; Interrupt Registers for Preservation
STAT_Temp res 1
BSR_Temp res 1

Buttons res 1 ; Button Flags 1=ON, 0=OFF


Stop_Digit res 1 ; Stop Counter Digit
Motor_Digit res 1 ; Motor Speed and Direction Digit

QEI_Flags res 1 ; QEI_Flags: QEI Monitoring Flags


constant QF_Enable=0 ; QEI_Flags,0 = Monitoring of QEI Flags is
Enabled
constant QF_PosMax=1 ; QEI_Flags,1 = Interrupt on Position = Max
Count
constant QF_MaxChg=2 ; QEI_Flags,2 = Max Count Changed
constant QF_Run=3 ; QEI_Flags,3 = Repeat Run
constant QF_Dir=7 ; QEI_Flags,7 = Rotation Direction Changed

end
Motor Controller Unit Test 7
; 08/31/06 ajs A3959: For Demo Index Table: PHASE[RC5/INT2 button ->
RD5] ON = CW
; 08/26/06 ajs DS275: Transmit Test
;
; PIC18F4431 I/O
; Input Output
; RC3/INT0 -> RB0/PWM0 => A3959 Enable
; RC4/INT1 -> RD4 => A3959 Mode
; RC5/INT2 -> RD5 => A3959 Phase
;
; Unit Test Scope
; Verify Operation of Motor on A3959 at 100% ON/OFF with Vbb = 12V
; Verify Transmission of Data on DS275 at 2400 baud
;

include <P18f4431.INC>
ORG 0x0000 ; MCLR Reset Entry Point Vector
goto RESET_1 ; Jump to Initialization

ORG 0x0008 ; High Priority Interrupt Vector


goto HI_ISR

HI_ISR ; High Priority Interrupt


Service Routine
movwf W_Temp ; W_TEMP is in virtual
bank
movff STATUS,STAT_Temp ; STATUS_TEMP located anywhere
movff BSR,BSR_Temp ; BSR_TMEP located anywhere

btfsc INTCON3,INT1IF ; Skip if INT1 Flag is Clear, else Turn On


RB5 LED
bsf Buttons,4 ; Set Button Flag 4
bcf INTCON3,INT1IF ; Clear INT1

btfsc INTCON3,INT2IF ; Skip if INT2 Flag is Clear, else Turn On


RB5 LED
bsf Buttons,5
bcf INTCON3,INT2IF ; Clear INT2

btfsc INTCON,INT0IF
bsf Buttons,3 ; Set Button Flag 3
bcf INTCON,INT0IF

movff BSR_Temp,BSR ; Restore BSR


movff STAT_Temp, STATUS ; Restore STATUS
movwf W_Temp, W ; Restore WREG
retfie FAST

RESET_1 ; Reset
Initialization
bcf INTCON,GIE ; Disable Global Interrupt
bsf OSCCON,6 ; Kick the INT OSC up to maximum
8MHz with x111xxxx
bsf OSCCON,5
bsf OSCCON,4

clrf Buttons ; Clear the Buttons flags


clrf PORTB ; Setup PORTB I/O
bcf TRISB,RB0 ; RB0 = Output
;bcf TRISB,RB5 ; RB5 = Output
;bcf TRISB,RB4 ; RB4 = Output

clrf PORTD ; Setup PORTD I/O


movlw 0x00
movwf TRISD ; Set PORTD to All Output
bsf PORTD,RD5 ; PHASE ON = CW

bcf PORTC,RC3 ; Setup PORTC I/O


bcf PORTC,RC4
bcf PORTC,RC5
bsf TRISC,RC3 ; RC4/INT1 = Input
bsf TRISC,RC4
bsf TRISC,RC5

bcf PORTE,RE1
bcf TRISE,RE1

Setup_Async_Mode
#define TXSTA_INIT 0x20
#define RCSTA_INIT 0x90
movlw 0x33 ; 0x81 for 20MHz OSC
movwf SPBRG ; baud rate generator is reset & initialized
movlw TXSTA_INIT
movwf TXSTA ; 8-bit transmission, async mode
movlw RCSTA_INIT
movwf RCSTA ; 8-bit reception, enable serial port,

bcf PIR1,TXIF
movlw 0x0D
movwf TXREG
TXi1
bsf PORTE,RE1
btfss PIR1,TXIF
goto TXi1
movlw 0x0D
movwf TXREG
TXi2
bsf PORTE,RE1
btfss PIR1,TXIF
goto TXi2
movlw 0x0D
movwf TXREG
TXi3
bsf PORTE,RE1
btfss PIR1,TXIF
goto TXi3
movlw 0x2A
movwf TXREG
TXi4
bsf PORTE,RE1
btfss PIR1,TXIF
goto TXi4
movlw 0x0D
movwf TXREG
TXi5
bsf PORTE,RE1
btfss PIR1,TXIF
goto TXi5
bcf PORTE,RE1
; Setup RC4/INT1 Interupt
bcf INTCON3,INT1IF ; Clear INT1
bsf INTCON3,INT1IP ; Set INT1 to High Priority
bsf INTCON3,INT1IE ; Enable INT1 Interrupt
bcf INTCON3,INT2IF ; Clear INT2
bsf INTCON3,INT2IP ; Set INT2 to High Priority
bsf INTCON3,INT2IE ; Enable INT0 Interrupt

bsf INTCON3,INT2IE ; Enable INT2 Interrupt


bcf INTCON,INT0IF ; Clear INT0
bsf INTCON,INT0IE ; Enable INT0 Interrupt
;bsf INTCON,PEIE
bsf INTCON,GIE ; Enable Global Interrupt

CHECK_1
btfss Buttons,4 ; Check for RC4/INT1 Button Flag
goto CHECK_2 ; flag not set, goto next run state

STATE_1 ; RC4/INT1 Button Flag set, process


bcf INTCON,GIE ; Disable Global Interrupt
call TX_BUTTON
bcf TRISC,RC4 ; Set RC4 to output
bcf PORTC,RC4 ; Clear RC4
bsf TRISC,RC4 ; Set RC4 back to input
btg PORTD,RD4 ; Toggle RD4
bcf Buttons,4 ; Reset Buttons 4 Flag
bsf INTCON,GIE ; Enable Global Interrupt

CHECK_2
btfss Buttons,5 ; Check for RC5/INT2
goto CHECK_3 ; flag not set, goto next run state

STATE_2 ; RC5/INT2 triggered


bcf INTCON,GIE ; Disable Global Interrupt
call TX_BUTTON
bcf TRISC,RC5 ; Set RC5 to output
bcf PORTC,RC5 ; Clear RC5
bsf TRISC,RC5 ; Set RC5 back to input
btg PORTD,RD5 ; Toggle RD5
bcf Buttons,5 ; Reset Buttons 5 Flag
bsf INTCON,GIE ; Enable Global Interrupt

CHECK_3
btfss Buttons,3 ; Check for RC3/INT0
goto CHECK_4 ; flag not set, goto next run state

STATE_3 ; RC3/INT1 triggered


bcf INTCON,GIE ; Disable Global Interrupt
call TX_BUTTON
bcf TRISC,RC3 ; Set RC3 to output
bcf PORTC,RC3 ; Clear RC3
bsf TRISC,RC3 ; Set RC3 back to input
btg PORTB,RB0 ; Toggle RB0
bcf Buttons,3 ; Reset Buttons 3 Flag
bsf INTCON,GIE ; Enable Global Interrupt

CHECK_4
goto CHECK_1

TX_BUTTON
TX_J1
bsf PORTE,RE1
btfss PIR1,TXIF
goto TX_J1
movlw 0x21 ; "!"
movwf TXREG

TX_J2
bsf PORTE,RE1
btfss PIR1,TXIF
goto TX_J2
movlw 0x55 ; "U"
movwf TXREG

TXB4
bsf PORTE,RE1
btfss PIR1,TXIF
goto TXB4

btfss Buttons,4 ; Check for RC4/INT1 Button Flag


goto TXB5
movlw 0x31
movwf TXREG
goto TX_J3

TXB5
btfss Buttons,5 ; Check for RC5/INT2 Button Flag
goto TXB3
movlw 0x32
movwf TXREG
goto TX_J3

TXB3
btfss Buttons,3 ; Check for RC3/INT0 Button Flag
goto TX_J3
movlw 0x33
movwf TXREG

TX_J3
bsf PORTE,RE1
btfss PIR1,TXIF
goto TX_J3
movlw 0x0D
movwf TXREG
TX_J4
bsf PORTE,RE1
btfss PIR1,TXIF
goto TX_J4
bcf PORTE,RE1
return

;Get_Serial_Data_Poll
; movlb 1 ; PIR is in bank 1
;PollRcv
; btfss PIR,0 ; check the RBIF bit
; goto PollRcv ; loop until char received, assume WDT is off
; movlb 0 ; RCREG is in bank 0
; movpf RCREG,SerInData
; return ; Received 8-bits are in SerInData

W_Temp res 1
STAT_Temp res 1
BSR_Temp res 1
Buttons res 1 ; Button Flags 1=ON, 0=OFF
Button_Press res 1

end
; Motor Controller Unit Test 8
; 09/04/06 ajs PWM Test
; 09/02/06 ajs PIC18F4431 QEI Test
; 08/31/06 ajs A3959: For Demo Index Table: PHASE[RC5/INT2 button ->
RD5] ON = CW
; 08/26/06 ajs DS275: Transmit Test
;
; PIC18F4431 I/O
; Input Output
; RC3/INT0 -> RB0/PWM0 => A3959 Enable
; RC4/INT1 -> RD4 => A3959 Mode
; RC5/INT2 -> RD5 => A3959 Phase
;
; Unit Test Scope
; Verify Operation of Motor on A3959 at 100% ON/OFF with Vbb = 12V
; Verify Transmission of Data on DS275 at 2400 baud
;

include <P18f4431.INC>

ORG 0x0000 ; MCLR Reset Entry Point Vector


goto RESET_1 ; Jump to Initialization
ORG 0x0008 ; High Priority Interrupt Vector
goto HI_ISR

HI_ISR ; High Priority Interrupt


Service Routine
movwf W_Temp ; W_TEMP is in virtual
bank
movff STATUS,STAT_Temp ; STATUS_TEMP located anywhere
movff BSR,BSR_Temp ; BSR_TMEP located anywhere

btfsc INTCON3,INT1IF ; Skip if INT1 Flag is Clear, else Turn On


RB5 LED
bsf Buttons,4 ; Set Button Flag 4
bcf INTCON3,INT1IF ; Clear INT1

btfsc INTCON3,INT2IF ; Skip if INT2 Flag is Clear, else Turn On


RB5 LED
bsf Buttons,5
bcf INTCON3,INT2IF ; Clear INT2

btfsc INTCON,INT0IF
bsf Buttons,3 ; Set Button Flag 3
bcf INTCON,INT0IF

movff BSR_Temp,BSR ; Restore BSR


movff STAT_Temp, STATUS ; Restore STATUS
movwf W_Temp, W ; Restore WREG
retfie FAST

RESET_1 ; Reset
Initialization
bcf INTCON,GIE ; Disable Global Interrupt
bsf OSCCON,6 ; Kick the INT OSC up to maximum
8MHz with x111xxxx
bsf OSCCON,5
bsf OSCCON,4

clrf Buttons ; Clear the Buttons flags

clrf PORTA
clrf PORTB ; Setup PORTB I/O
bcf TRISB,RB0 ; RB0 = Output
;bcf TRISB,RB5 ; RB5 = Output
;bcf TRISB,RB4 ; RB4 = Output

clrf PORTD ; Setup PORTD I/O


movlw 0x00
movwf TRISD ; Set PORTD to All Output

bcf PORTC,RC3 ; Setup PORTC I/O


bcf PORTC,RC4
bcf PORTC,RC5
bsf TRISC,RC3 ; RC4/INT1 = Input
bsf TRISC,RC4
bsf TRISC,RC5

bcf PORTE,RE1
bcf TRISE,RE1

Setup_Async_Mode
#define TXSTA_INIT 0x20
#define RCSTA_INIT 0x90
movlw 0x33 ; 0x81 for 20MHz OSC
movwf SPBRG ; baud rate generator is reset & initialized
movlw TXSTA_INIT
movwf TXSTA ; 8-bit transmission, async mode
movlw RCSTA_INIT
movwf RCSTA ; 8-bit reception, enable serial port,

bcf PIR1,TXIF
movlw 0x0D
movwf TXREG
TXi1
bsf PORTE,RE1
btfss PIR1,TXIF
goto TXi1
movlw 0x0D
movwf TXREG
TXi2
bsf PORTE,RE1
btfss PIR1,TXIF
goto TXi2
movlw 0x0D
movwf TXREG
TXi3
bsf PORTE,RE1
btfss PIR1,TXIF
goto TXi3
movlw 0x2A
movwf TXREG
TXi4
bsf PORTE,RE1
btfss PIR1,TXIF
goto TXi4
movlw 0x0D
movwf TXREG
TXi5
bsf PORTE,RE1
btfss PIR1,TXIF
goto TXi5
bcf PORTE,RE1

QEI_INIT
bcf ANSEL0,ANS4
bcf ANSEL0,ANS3
bcf ANSEL0,ANS2
bsf TRISA,RA4
bsf TRISA,RA3
bsf TRISA,RA2
movlw 0xFF
movwf MAXCNTH
movwf MAXCNTL
movwf CAP2BUFH
movwf CAP2BUFL
movwf CAP3BUFH
movwf CAP3BUFL
clrf POSCNTL
clrf POSCNTH
clrf QEICON

bsf QEICON,VELM
bsf QEICON,QEIM1

PWM_INIT
clrf PWMCON0 ; Disable PWM, clear configuration
bcf PTCON1,PTEN ; Disable PWM Timer
clrf PTCON0 ; Clear PWM Timer

movlw 0x0F ; Set the PERIOD


movwf PTPERH
movlw 0xFF
movwf PTPERL

; bsf TRISA,RA0 ; Setup Analog Input on RA0/AN0 for Duty Cycle


Control
; bsf ADCON0,ADON

; bsf ADCON0,ADON ; Turn on the A-to-D


Convertion Module
;PWM1
; bsf ADCON0,GO_DONE ; Start a conversion
;PWM2
; btfsc ADCON0,GO_DONE ; Wait for conversion to complete
; goto PWM2
; movf ADRESH,w ; Move result to W

;movlw 0x3E
movwf PDC0H
movlw 0xFF
movwf PDC0L

bsf PTCON0,PTMOD1
bsf PTCON0,PTMOD0
bsf PTCON1,PTEN
bsf PWMCON0,PMOD0

; Setup RC4/INT1 Interupt


bcf INTCON3,INT1IF ; Clear INT1
bsf INTCON3,INT1IP ; Set INT1 to High Priority
bsf INTCON3,INT1IE ; Enable INT1 Interrupt
bcf INTCON3,INT2IF ; Clear INT2
bsf INTCON3,INT2IP ; Set INT2 to High Priority
bsf INTCON3,INT2IE ; Enable INT0 Interrupt

bsf INTCON3,INT2IE ; Enable INT2 Interrupt


bcf INTCON,INT0IF ; Clear INT0
bsf INTCON,INT0IE ; Enable INT0 Interrupt
;bsf INTCON,PEIE
bsf INTCON,GIE ; Enable Global Interrupt

CHECK_1
btfss Buttons,4 ; Check for RC4/INT1 Button Flag
goto CHECK_2 ; flag not set, goto next run state

STATE_1 ; RC4/INT1 Button Flag set, process


bcf INTCON,GIE ; Disable Global Interrupt
call TX_BUTTON
bcf TRISC,RC4 ; Set RC4 to output
bcf PORTC,RC4 ; Clear RC4
bsf TRISC,RC4 ; Set RC4 back to input
btg PORTD,RD4 ; Toggle RD4
bcf Buttons,4 ; Reset Buttons 4 Flag
bsf INTCON,GIE ; Enable Global Interrupt

CHECK_2
btfss Buttons,5 ; Check for RC5/INT2
goto CHECK_3 ; flag not set, goto next run state

STATE_2 ; RC5/INT2 triggered


bcf INTCON,GIE ; Disable Global Interrupt
call TX_BUTTON
bcf TRISC,RC5 ; Set RC5 to output
bcf PORTC,RC5 ; Clear RC5
bsf TRISC,RC5 ; Set RC5 back to input
btg PORTD,RD5 ; Toggle RD5
bcf Buttons,5 ; Reset Buttons 5 Flag
bsf INTCON,GIE ; Enable Global Interrupt

CHECK_3
btfss Buttons,3 ; Check for RC3/INT0
goto CHECK_4 ; flag not set, goto next run state

STATE_3 ; RC3/INT0 triggered


bcf INTCON,GIE ; Disable Global Interrupt
call TX_BUTTON
bcf TRISC,RC3 ; Set RC3 to output
bcf PORTC,RC3 ; Clear RC3
bsf TRISC,RC3 ; Set RC3 back to input
;btg PORTB,RB0 ; Toggle RB0
btg PWMCON0,PWMEN1
bcf Buttons,3 ; Reset Buttons 3 Flag
bsf INTCON,GIE ; Enable Global Interrupt

CHECK_4
btfss PORTA,RA3
goto CLEAR_LED

SET_LED
bsf PORTD,RD0
goto CHECK_5

CLEAR_LED
bcf PORTD,RD0
goto CHECK_5

; bsf ADCON0,ADON ; Turn on the A-to-D


Convertion Module
;PWM_UP1
; bsf ADCON0,GO_DONE ; Start a conversion
;PWM_UP2
; btfsc ADCON0,GO_DONE ; Wait for conversion to complete
; goto PWM_UP2
; movf ADRESH,w ; Move result to W
; movwf PDC0H

CHECK_5
goto CHECK_1

PWM_STOP
bcf PTCON1,PTEN ; Disable PWM Timer
return

PWM_RUN
movlw 0x20
movwf PWMCON0
bsf PTCON1,PTEN
return

TX_BUTTON
TX_J1
bsf PORTE,RE1
btfss PIR1,TXIF
goto TX_J1
movlw 0x21 ; "!"
movwf TXREG

TX_J2
bsf PORTE,RE1
btfss PIR1,TXIF
goto TX_J2
movlw 0x55 ; "U"
movwf TXREG

TXB4
bsf PORTE,RE1
btfss PIR1,TXIF
goto TXB4

btfss Buttons,4 ; Check for RC4/INT1 Button Flag


goto TXB5
movlw 0x31
movwf TXREG
goto TX_J3

TXB5
btfss Buttons,5 ; Check for RC5/INT2 Button Flag
goto TXB3
movlw 0x32
movwf TXREG
goto TX_J3

TXB3
btfss Buttons,3 ; Check for RC3/INT0 Button Flag
goto TX_J3
movlw 0x33
movwf TXREG

TX_J3
bsf PORTE,RE1
btfss PIR1,TXIF
goto TX_J3
movlw 0x0D
movwf TXREG
TX_J4
bsf PORTE,RE1
btfss PIR1,TXIF
goto TX_J4
bcf PORTE,RE1
return

;Get_Serial_Data_Poll
; movlb 1 ; PIR is in bank 1
;PollRcv
; btfss PIR,0 ; check the RBIF bit
; goto PollRcv ; loop until char received, assume WDT is off
; movlb 0 ; RCREG is in bank 0
; movpf RCREG,SerInData
; return ; Received 8-bits are in SerInData

W_Temp res 1
STAT_Temp res 1
BSR_Temp res 1
Buttons res 1 ; Button Flags 1=ON, 0=OFF
Button_Press res 1

end
; Index Table Motor Controller Application
; 09/23/06 ajs Initial Application Template
;
; PIC18F4431 I/O
; --------------
; INPUT
; User Interface Digital Input Buttons. Debounce performed by button
hardware
; #1: RE3/MCLR => MCU Reset
; #2: RC4/INT1 => Stop Divisions Count
; #3: RC5/INT2 => Motor Speed and Direction
; #4: RC3/INT0 => Run
;
; Quadrature Encoder Interface Digital Inputs
; RA2 => Index
; RA3 => Channel A
; RA4 => Channel B
;
; OUTPUT
; RB0/PWM0 => A3959 Enable
; RB1/PWM1 => Inverse of PWM0, Activity LED
; RB2 => A3959 Phase
; RB3 => A3959 Extended Mode
;
; RD
;
; Operational Variables
; QEI_Flags: QEI Monitoring Flags
; QEI_Flags,0 = Monitoring of QEI Flags is Enabled
; QEI_Flags,1 = Interrupt on Position = Max Count
; QEI_Flags,2 = Max Count Changed
; QEI_Flags,3 = Repeat Run
; QEI_Flags,7 = Rotation Direction Changed

include <P18f4431.INC>

ORG 0x000000 ; MCLR Reset Entry Point Vector


goto RESET_1 ; Jump to Initialization

ORG 0x000008 ; High Priority Interrupt Vector


goto HI_ISR

ORG 0x000018 ; Low Priority Interrupt


goto LO_ISR

HI_ISR ; High Priority Interrupt


Service Routine
movwf W_Temp ; W_TEMP is in virtual
bank
movff STATUS,STAT_Temp ; STATUS_TEMP located anywhere
movff BSR,BSR_Temp ; BSR_TMEP located anywhere

btfsc INTCON3,INT1IF ; Skip if INT1 Flag is Clear, else Turn On


RB5 LED
bsf Buttons,4 ; Set Button Flag 4
bcf INTCON3,INT1IF ; Clear INT1

btfsc INTCON3,INT2IF ; Skip if INT2 Flag is Clear, else Turn On


RB5 LED
bsf Buttons,5
bcf INTCON3,INT2IF ; Clear INT2
btfsc INTCON,INT0IF
bsf Buttons,3 ; Set Button Flag 3
bcf INTCON,INT0IF

movff BSR_Temp,BSR ; Restore BSR


movff STAT_Temp, STATUS ; Restore STATUS
movwf W_Temp, W ; Restore WREG
retfie FAST

LO_ISR ; Low Priority Interrupts


movwf W_Temp ; W_TEMP is in virtual
bank
movff STATUS,STAT_Temp ; STATUS_TEMP located anywhere
movff BSR,BSR_Temp ; BSR_TMEP located anywhere

bcf PIR3,PTIF

btfsc PIR3,IC3DRIF ; Direction Change Interrupt Fired


bsf QEI_Flags,QF_Dir ; Set Direction Changed Flag
bcf PIR3,IC3DRIF ; Clear Direction Change Interrupt Flag

btfsc PIR3,IC2QEIF ; QEI Position = Max Count Interrupt Fired


bsf QEI_Flags,QF_PosMax ; Set Position = Max Count Flag
bcf PIR3,IC2QEIF ; Clear QEI Interrupt Flag

movff BSR_Temp,BSR ; Restore BSR


movff STAT_Temp, STATUS ; Restore STATUS
movwf W_Temp, W ; Restore WREG
retfie FAST

RESET_1 ; Reset
Initialization
bcf INTCON,GIE ; Disable Global Interrupt
bsf OSCCON,6 ; Kick the INT OSC up to maximum
8MHz with x111xxxx
bsf OSCCON,5
bsf OSCCON,4

clrf Buttons ; Clear the Buttons flags

clrf PORTA ; Setup PORTA I/O


; QEI Inputs
bcf ANSEL0,ANS2 ; RA2/Index = Digital
bsf TRISA,RA2 ; RA2 = Input
bcf ANSEL0,ANS3 ; RA3/QEA = Digital
bsf TRISA,RA3 ; RA3 = Input
bcf ANSEL0,ANS4 ; RA4/QEB = Digital
bsf TRISA,RA4 ; RA4 = Input

clrf PORTB ; Setup PORTB Output


bcf TRISB,RB0 ; RB0/PWM0 = Output
bcf TRISB,RB1 ; RB1/PWM1 = Output
bcf TRISB,RB2 ; RB2/Phase = Output
bcf TRISB,RB3 ; RB3/Mode = Output

bcf TRISB,RB4 ; RB4/Speed Select bit 0


bcf TRISB,RB5 ; RB5/Speed Select bit 1

clrf PORTD ; Setup PORTD I/O


bcf TRISD,RD4 ; Digit LED Segments Output
bcf TRISD,RD5
bcf TRISD,RD6
bcf TRISD,RD7
clrf LATD

bcf PORTC,RC3 ; Setup PORTC I/O


bcf PORTC,RC4
bcf PORTC,RC5
bsf TRISC,RC3 ; RC3/INT0 = Step Counter
bsf TRISC,RC4 ; RC4/INT1 = Motor Speed and Direction
bsf TRISC,RC5 ; RC5/INT2 = Run

QEI_INIT
clrf QEI_Flags ; Clear QEI Monitoring Flags
clrf POSCNTL ; Clear Position Counter
clrf POSCNTH
movlw 0xFF ; Set Counter Maximum to 0xFFFF
movwf MAXCNTH
movlw 0x99 ; Set Counter Maximum to 0xFFFF
movwf MAXCNTL

clrf QEICON ; Reset QEI Configuration


bsf QEICON,VELM ; Turn Off Velocity Measurement Mode
bsf QEICON,QEIM1 ; Set for 2x and Max Count reset

bcf IPR3,IC3DRIP ; QEI Dir INT = Low Priority


bcf IPR3,IC2QEIP ; QEI INT = Low Priority
bcf PIR3,IC3DRIF ; Clear QEI Interrupt Flag bits
bcf PIR3,IC2QEIF

PWM_INIT
clrf Motor_Digit
clrf Stop_Digit

clrf PWMCON0 ; Disable PWM, clear configuration


bcf PTCON1,PTEN ; Disable PWM Timer
clrf PTCON0 ; Clear PWM Timer

movlw 0x0F ; Set the 12 bits PERIOD to Maximum


movwf PTPERH
movlw 0xFF
movwf PTPERL

movlw 0x00 ; Set the PWM 12 bits Duty Cycle to 0


movwf PDC0H

bcf PORTB,RB4 ; Clear Speed LEDs


bcf PORTB,RB5

bcf PTCON0,PTMOD1 ; Continuous Up/Down Mode


bcf PTCON0,PTMOD0 ; Set to 1 for PTIF Interrupt Enable
bcf PIE3,PTIE ; Disable PTIF Interrupt
bcf PIR3,PTIF ; Clear PWM Flag
bsf PTCON1,PTEN
bcf PWMCON0,PMOD0 ; PWM0, PWM1 Independent Mode

; Setup RC4/INT1 Interupt


bcf INTCON3,INT1IF ; Clear INT1
bsf INTCON3,INT1IP ; Set INT1 to High Priority
bsf INTCON3,INT1IE ; Enable INT1 Interrupt

; Setup RC5/INT2
bcf INTCON3,INT2IF ; Clear INT2
bsf INTCON3,INT2IP ; Set INT2 to High Priority
bsf INTCON3,INT2IE ; Enable INT2 Interrupt
; Setup RC3/INT0
bsf INTCON3,INT2IE ; Enable INT2 Interrupt
bcf INTCON,INT0IF ; Clear INT0
bsf INTCON,INT0IE ; Enable INT0 Interrupt

bsf PIE3,IC2QEIE ; Enable QEI Interupts


bsf RCON,IPEN ; Enable Interrupt Priority
bsf INTCON,PEIE ; Enable Peripheral Interrupts
bsf INTCON,GIE ; Enable Global Interrupt

PROG_LOOP ; CHECK_BTN_1 Reset Initialization

CHECK_RC4_INT1 ; *** Set the Divisions to Stop At ***

btfss Buttons,4 ; Check for RC4/INT1 Button Flag


goto CHECK_RC5_INT2 ; flag not set, goto next run check

STATE_RC4_INT1 ; RC4/INT1 Button Flag set,


process
bcf INTCON,GIE ; Disable Global Interrupt
bcf TRISC,RC4 ; Set RC4 to output
bcf PORTC,RC4 ; Clear RC4
bsf TRISC,RC4 ; Set RC4 back to input

; Reset Position Counters


clrf POSCNTL ; Clear Position Counter
clrf POSCNTH

clrf QEI_Flags ; Clear QEI Monitoring Flags


bsf QEI_Flags,QF_Enable ; Set QEI Monitoring ON as default
bsf QEI_Flags,QF_MaxChg ; Set QEI Max Count Changed Flag

bcf PIR3,IC3DRIF ; Clear QEI Interrupt Flag bits


bcf PIR3,IC2QEIF

;;; Increment Divisions Setting Variable


movlw 0x10
addwf LATD

D_360
movf LATD,0 ; Get the current Div Stop Setting
xorlw 0x10 ; XOR with 0x10 = 360 deg
tstfsz WREG ; Test
goto D_180 ; Not Zero so try 180 deg
movlw 0xFF ; 65433.6 = 0xFF99
movwf MAXCNTH ; Set Counter Maximum
movlw 0x99
movwf MAXCNTL
goto QEI_ENABLE

D_180
movf LATD,0
xorlw 0x20 ; XOR with 0x20 = 180 deg
tstfsz WREG
goto D_90
movlw 0x7F ; 32716.8 = 0x7FCC
movwf MAXCNTH
movlw 0xCC
movwf MAXCNTL
goto QEI_ENABLE

D_90
movf LATD,0
xorlw 0x30 ; XOR with 0x30 = 90 deg
tstfsz WREG
goto D_60
movlw 0x3F ; 16358.4 = 0x3FE6
movwf MAXCNTH
movlw 0xE6
movwf MAXCNTL
goto QEI_ENABLE

D_60
movf LATD,0
xorlw 0x40 ; XOR with 0x40 = 60 deg
tstfsz WREG
goto D_45
movlw 0x2A ; 10905.6 = 0x2A99
movwf MAXCNTH
movlw 0x99
movwf MAXCNTL
goto QEI_ENABLE

D_45
movf LATD,0
xorlw 0x50 ; XOR with 0x50 = 45 deg
tstfsz WREG
goto D_10
movlw 0x1F ; 8179.2 = 0x1FF3
movwf MAXCNTH
movlw 0xF3
movwf MAXCNTL
goto QEI_ENABLE

D_10
movf LATD,0
xorlw 0x60 ; XOR with 0x60 = 10 deg
tstfsz WREG
goto D_01
movlw 0x07 ; 1817.6 = 0x0719
movwf MAXCNTH
movlw 0x19
movwf MAXCNTL
goto QEI_ENABLE

D_01
movf LATD,0
xorlw 0x70 ; XOR with 0x70 = 1 deg
tstfsz WREG
goto D_RESET
movlw 0x00 ; 181.76 = 0x00B5
movwf MAXCNTH
movlw 0xB5
movwf MAXCNTL
goto QEI_ENABLE

D_RESET ; None of the Above, Set Manual Mode


bcf QEI_Flags,QF_Enable ; Turn Off QEI Monitoring
movlw 0x0F ; Reset to Divisions to 0
andwf LATD,1

QEI_ENABLE
bcf Buttons,4 ; Reset Buttons 4 Flag
bsf INTCON,GIE ; Enable Global Interrupt

CHECK_RC5_INT2 ; *** Set the PWM Speed ***


btfss Buttons,5 ; Check for RC5/INT2
goto CHECK_RC3_INT0 ; flag not set, goto next run check

STATE_RC5_INT2 ; RC5/INT2 triggered


bcf INTCON,GIE ; Disable Global Interrupt
bcf TRISC,RC5 ; Set RC5 to output
bcf PORTC,RC5 ; Clear RC5
bsf TRISC,RC5 ; Set RC5 back to input

;;; Increment Motor Speed


movf LATB,0 ; Get the current Motor Speed setting
xorlw 0x30 ; XOR with 0x30 = Maximum
tstfsz WREG ; Test, skip if Zero
goto MS_INCREASE ; If Not Max, then Increase

MS_OFF ; If Max, set to slowest


bcf LATB,RB4
bcf LATB,RB5
movlw 0x00
movwf PDC0H ; Set Duty Cycle
movlw 0x00
movwf PDC0L
goto MS_DONE

MS_INCREASE
movlw 0x10 ; Else Increase Speed
addwf LATB

MS_SLOW
movf LATB,0 ; Get the current Motor Speed setting
xorlw 0x10 ; XOR with 0x10 = Slow
tstfsz WREG ; Test
goto MS_FASTER ; Not Zero so try Faster
movlw 0x0F ; 1535 = 0x5FF
movwf PDC0H ; Set Duty Cycle
movlw 0xFF
movwf PDC0L
goto MS_DONE

MS_FASTER
movf LATB,0
xorlw 0x20 ; XOR with 0x20 = Faster
tstfsz WREG
goto MS_MAX
movlw 0x1F ; 2815 0xAFF
movwf PDC0H
movlw 0xFF
movwf PDC0L
goto MS_DONE

MS_MAX
movf LATB,0
xorlw 0x30 ; XOR with 0x30 = Maximum Speed
tstfsz WREG
goto MS_DONE
movlw 0x2F ; 4095 = 0xFFF
movwf PDC0H
movlw 0xFF
movwf PDC0L
goto MS_DONE

MS_DONE
bcf Buttons,5 ; Reset Buttons 5 Flag
bsf INTCON,GIE ; Enable Global Interrupt

CHECK_RC3_INT0 ; *** RUN / STOP ***


btfss Buttons,3 ; Check for RC3/INT0
goto CHECK_QEI_1 ; flag not set, goto next run state

STATE_RC3_INT0 ; RC3/INT0 triggered


bcf INTCON,GIE ; Disable Global Interrupt
bcf TRISC,RC3 ; Set RC3 to output
bcf PORTC,RC3 ; Clear RC3
bsf TRISC,RC3 ; Set RC3 back to input

btfss QEI_Flags,QF_Enable
goto MANUAL_MODE
; QEI Enabled Mode
bsf PWMCON0,PWMEN0 ; Turn On Motor
goto RUNSTOP_DONE

MANUAL_MODE
btg PWMCON0,PWMEN0 ; Toggle RUN/STOP

RUNSTOP_DONE
btfsc PWMCON0,PWMEN0
bsf QEI_Flags,QF_Run ; If Running, Set the QEI Run Flag

bcf Buttons,3 ; Reset Buttons 3 Flag


bsf INTCON,GIE ; Enable Global Interrupt

CHECK_QEI_0 ; *** QEI Direction Change ***


btfss QEI_Flags,QF_Enable
goto CHECK_QEI_1

STATE_QEI_0
bcf INTCON,GIE ; Disable Global Interrupt
bcf QEI_Flags,QF_Dir ; Clear Direction Change Flag

; btfss QEI_Flags,QF_Enable ; Check for QEI Monitoring


; goto QEI_0_DONE ; Not monitoring QEI. exit

;;;; QEI_Monitoring in effect: Do Direction Change Stuff Here


;;;; ...

;QEI_0_DONE
bsf INTCON,GIE ; Enable Global Interrupt

CHECK_QEI_1 ; *** QEI Position = Max Count ***


btfss QEI_Flags,QF_PosMax
goto FINAL_CHECK

STATE_QEI_1
bcf INTCON,GIE ; Disable Global Interrupt

btfss QEI_Flags,QF_Enable ; Check for QEI Monitoring Enabled


goto QEI_1_DONE ; Not Monitoring QEI, Exit to keep running

btfsc QEI_Flags,QF_MaxChg ; Check for NOT Max Count Changed


goto QEI_1_DONE ; Max Count was changed. Exit to keep running

btfsc QEI_Flags,QF_Run ; Check for NOT Run Flag = STOP


goto QEI_RUN ; Run

QEI_1_STOP_RUN
bcf PWMCON0,PWMEN0 ; Stop PWM
QEI_RUN
bcf QEI_Flags,QF_Run ; Clear Run Flag

QEI_1_DONE
bcf QEI_Flags,QF_MaxChg ; Clear QEI Max Changed
bcf QEI_Flags,QF_PosMax ; Clear QEI Position = Max Count Flag
bsf INTCON,GIE ; Enable Global Interrupt

FINAL_CHECK
goto PROG_LOOP

; Reserve Memory for F Variables


; ------------------------------
W_Temp res 1 ; Interrupt Registers for Preservation
STAT_Temp res 1
BSR_Temp res 1

Buttons res 1 ; Button Flags 1=ON, 0=OFF


Stop_Digit res 1 ; Stop Counter Digit
Motor_Digit res 1 ; Motor Speed and Direction Digit

QEI_Flags res 1 ; QEI_Flags: QEI Monitoring Flags


constant QF_Enable=0 ; QEI_Flags,0 = Monitoring of QEI Flags is
Enabled
constant QF_PosMax=1 ; QEI_Flags,1 = Interrupt on Position = Max
Count
constant QF_MaxChg=2 ; QEI_Flags,2 = Max Count Changed
constant QF_Run=3 ; QEI_Flags,3 = Repeat Run
constant QF_Dir=7 ; QEI_Flags,7 = Rotation Direction Changed

end
******************************************************************
***/
/* Header for IO ports module library functions */
/
******************************************************************
***/

#ifndef __PORTS_H
#define __PORTS_H
/* List of SFRs for IO ports */
/* This list contains the SFRs with default (POR) values to be used for
configuring IOports */
/* The user can modify this based on the requirement */
#define CNEN1_VALUE 0x0000
#define CNPU1_VALUE 0x0000

#define CNEN2_VALUE 0x0000


#define CNPU2_VALUE 0x0000

#define IEC0_VALUE 0x0000


#define IEC1_VALUE 0x0000
#define IEC2_VALUE 0x0000

#define IFS0_VALUE 0x0000


#define IFS1_VALUE 0x0000
#define IFS2_VALUE 0x0000

#define IPC0_VALUE 0x4444


#define IPC1_VALUE 0x4444
#define IPC2_VALUE 0x4444
#define IPC3_VALUE 0x4444
#define IPC4_VALUE 0x4444
#define IPC5_VALUE 0x4444
#define IPC6_VALUE 0x4444
#define IPC7_VALUE 0x4444
#define IPC8_VALUE 0x4444
#define IPC9_VALUE 0x4444
#define IPC10_VALUE 0x4444
#define IPC11_VALUE 0x4444

#if defined(__dsPIC33FJ64GP206__) || defined(__dsPIC33FJ64GP306__) ||


defined(__dsPIC33FJ64GP310__) || defined(__dsPIC33FJ64GP706__) || \
defined(__dsPIC33FJ64GP708__) ||
defined(__dsPIC33FJ64GP710__) || defined(__dsPIC33FJ128GP206__) ||
defined(__dsPIC33FJ128GP306__) || \
defined(__dsPIC33FJ128GP310__) ||
defined(__dsPIC33FJ128GP706__) || defined(__dsPIC33FJ128GP708__) ||
defined(__dsPIC33FJ128GP710__) || \
defined(__dsPIC33FJ256GP506__) ||
defined(__dsPIC33FJ256GP510__) || defined(__dsPIC33FJ256GP710__) ||
defined(__dsPIC33FJ64MC506__) || \
defined(__dsPIC33FJ64MC508__) ||
defined(__dsPIC33FJ64MC510__) || defined(__dsPIC33FJ64MC706__) ||
defined(__dsPIC33FJ64MC710__) || \
defined(__dsPIC33FJ128MC506__) ||
defined(__dsPIC33FJ128MC510__) || defined(__dsPIC33FJ128MC706__) ||
defined(__dsPIC33FJ128MC708__) || \
defined(__dsPIC33FJ128MC710__) ||
defined(__dsPIC33FJ256MC510__) || defined(__dsPIC33FJ256MC710__) ||
defined(__PIC24HJ64GP206__) || \
defined(__PIC24HJ64GP210__) || defined(__PIC24HJ64GP506__) ||
defined(__PIC24HJ64GP510__) || defined(__PIC24HJ128GP206__) || \
defined(__PIC24HJ128GP210__) || defined(__PIC24HJ128GP506__)
|| defined(__PIC24HJ128GP510__) || defined(__PIC24HJ128GP306__) || \
defined(__PIC24HJ128GP310__) || defined(__PIC24HJ256GP206__)
|| defined(__PIC24HJ256GP210__) || \
defined(__PIC24HJ256GP610__)

#define IEC3_VALUE 0x0000


#define IEC4_VALUE 0x0000

#define IFS3_VALUE 0x0000


#define IFS4_VALUE 0x0000

#define IPC12_VALUE 0x4444


#define IPC13_VALUE 0x4444
#define IPC14_VALUE 0x4444
#define IPC15_VALUE 0x4444
#define IPC16_VALUE 0x4444
#define IPC17_VALUE 0x4444

#endif

/* Config Bit Defines to be used for CN interrupt configuration */


#define CHANGE_INT_ON 0xFFFFFFFF /* interrupts on */
#define CHANGE_INT_OFF 0xF7FFFFFF /* interrupts off */

/* Setting the priority of CN interrupt */


#define CHANGE_INT_PRI_0 0xF8FFFFFF
#define CHANGE_INT_PRI_1 0xF9FFFFFF
#define CHANGE_INT_PRI_2 0xFAFFFFFF
#define CHANGE_INT_PRI_3 0xFBFFFFFF
#define CHANGE_INT_PRI_4 0xFCFFFFFF
#define CHANGE_INT_PRI_5 0xFDFFFFFF
#define CHANGE_INT_PRI_6 0xFEFFFFFF
#define CHANGE_INT_PRI_7 0xFFFFFFFF

/* Setting the priority of External interrupt */


#define EXT_INT_PRI_0 0xFFF8
#define EXT_INT_PRI_1 0xFFF9
#define EXT_INT_PRI_2 0xFFFA
#define EXT_INT_PRI_3 0xFFFB
#define EXT_INT_PRI_4 0xFFFC
#define EXT_INT_PRI_5 0xFFFD
#define EXT_INT_PRI_6 0xFFFE
#define EXT_INT_PRI_7 0xFFFF

/* enable / disable External interrupt */


#define EXT_INT_ENABLE 0xFFFF
#define EXT_INT_DISABLE 0xFFF7

/* External interrupts edge selection defines */


#define RISING_EDGE_INT 0xFFEF /*Interrupt is set by a
rising edge */
#define FALLING_EDGE_INT 0xFFFF /*Interrupt is set by a
falling edge */

/* Macros to Enable CN interrupts */


#define EnableCN0 asm ("BSET CNEN1,#0")
#define EnableCN1 asm ("BSET CNEN1,#1")
#define EnableCN2 asm ("BSET CNEN1,#2")
#define EnableCN3 asm ("BSET CNEN1,#3")
#define EnableCN4 asm ("BSET CNEN1,#4")
#define EnableCN5 asm ("BSET CNEN1,#5")
#define EnableCN6 asm ("BSET CNEN1,#6")
#define EnableCN7 asm ("BSET CNEN1,#7")

#if defined(__dsPIC30F5011__) || defined(__dsPIC30F6011__) ||


defined(__dsPIC30F6012__) || \
defined(__dsPIC30F6010__) || defined(__dsPIC30F5013__) ||
defined(__dsPIC30F6013__) || \
defined(__dsPIC30F6014__) || defined(__dsPIC30F5015__) ||
defined(__dsPIC30F6010A__) || \
defined(__dsPIC30F6011A__) || defined(__dsPIC30F6012A__) ||
defined(__dsPIC30F6013A__) || \
defined(__dsPIC30F6014A__) || defined(__dsPIC30F5016__) ||
defined(__dsPIC30F6015__) || \
defined (__dsPIC33FJ64GP206__) ||
defined(__dsPIC33FJ128GP206__) || defined(__dsPIC33FJ64GP306__) ||
defined(__dsPIC33FJ128GP306__) || \
defined(__dsPIC33FJ256GP506__) || defined(__dsPIC33FJ64GP706__) ||
defined(__dsPIC33FJ128GP706__) || defined(__dsPIC33FJ128MC708__) || \
defined(__dsPIC33FJ64MC508__) || defined(__dsPIC33FJ128MC506__) ||
defined(__dsPIC33FJ64MC506__) || defined(__dsPIC33FJ128MC706__) || \
defined(__dsPIC33FJ64MC506__) || defined(__PIC24HJ64GP506__) ||
defined(__PIC24HJ128GP506__) || defined(__PIC24HJ128GP306__) || \
defined(__PIC24HJ64GP206__) || defined(__PIC24HJ128GP206__) ||
defined(__PIC24HJ256GP206__) || \
defined(__dsPIC33FJ64GP708__) ||
defined(__dsPIC33FJ128GP708__) || defined(__dsPIC33FJ64GP310__) ||
defined(__dsPIC33FJ128GP310__) || \
defined(__dsPIC33FJ256GP510__) || defined(__dsPIC33FJ64GP710__) ||
defined(__dsPIC33FJ128GP710__) || defined(__dsPIC33FJ256MC710__) || \
defined(__dsPIC33FJ64MC510__) || defined(__dsPIC33FJ128MC510__) ||
defined(__dsPIC33FJ256MC510__) || defined(__dsPIC33FJ64MC710__) || \
defined(__dsPIC33FJ128MC710__) || defined(__dsPIC33FJ256MC710__) ||
defined(__PIC24HJ64GP210__) || defined(__PIC24HJ128GP210__) || \
defined(__PIC24HJ128GP310__) || defined(__PIC24HJ64GP506__) ||
defined(__PIC24HJ256GP210__) || defined(__PIC24HJ128GP510__) || \
defined(__PIC24HJ256GP610__)

#define EnableCN8 asm ("BSET CNEN1,#8")


#define EnableCN9 asm ("BSET CNEN1,#9")
#define EnableCN10 asm ("BSET CNEN1,#10")
#define EnableCN11 asm ("BSET CNEN1,#11")
#define EnableCN12 asm ("BSET CNEN1,#12")
#define EnableCN13 asm ("BSET CNEN1,#13")
#define EnableCN14 asm ("BSET CNEN1,#14")
#define EnableCN15 asm ("BSET CNEN1,#15")
#define EnableCN16 asm ("BSET CNEN2,#0")
#define EnableCN17 asm ("BSET CNEN2,#1")
#define EnableCN18 asm ("BSET CNEN2,#2")
#endif

#if defined(__dsPIC30F6010__) || defined(__dsPIC30F5013__) ||


defined(__dsPIC30F6013__) || \
defined(__dsPIC30F6014__) || defined(__dsPIC30F6010A__) ||
defined(__dsPIC30F6013A__) || \
defined(__dsPIC30F6014A__) || defined(__dsPIC30F5016__) || \
defined(__dsPIC33FJ64GP708__) ||
defined(__dsPIC33FJ128GP708__) || defined(__dsPIC33FJ64GP310__) ||
defined(__dsPIC33FJ128GP310__) || \
defined(__dsPIC33FJ256GP510__) || defined(__dsPIC33FJ64GP710__) ||
defined(__dsPIC33FJ128GP710__) || defined(__dsPIC33FJ256MC710__) || \
defined(__dsPIC33FJ64MC510__) || defined(__dsPIC33FJ128MC510__) ||
defined(__dsPIC33FJ256MC510__) || defined(__dsPIC33FJ64MC710__) || \
defined(__dsPIC33FJ128MC710__) || defined(__dsPIC33FJ256MC710__) ||
defined(__PIC24HJ64GP210__) || defined(__PIC24HJ128GP210__) || \
defined(__PIC24HJ128GP310__) || defined(__PIC24HJ64GP506__) ||
defined(__PIC24HJ256GP210__) || defined(__PIC24HJ128GP510__) || \
defined(__PIC24HJ256GP610__)

#define EnableCN19 asm ("BSET CNEN2,#3")


#define EnableCN20 asm ("BSET CNEN2,#4")
#define EnableCN21 asm ("BSET CNEN2,#5")
#endif

#if defined(__dsPIC30F5013__) || defined(__dsPIC30F6013__) ||


defined(__dsPIC30F6014__) || \
defined(__dsPIC30F6013A__) || defined(__dsPIC30F6014A__) ||
defined(__dsPIC33FJ64GP708__) || defined(__dsPIC33FJ128GP708__) ||
defined(__dsPIC33FJ64GP310__) || defined(__dsPIC33FJ128GP310__) || \
defined(__dsPIC33FJ256GP510__) || defined(__dsPIC33FJ64GP710__) ||
defined(__dsPIC33FJ128GP710__) || defined(__dsPIC33FJ256MC710__) || \
defined(__dsPIC33FJ64MC510__) || defined(__dsPIC33FJ128MC510__) ||
defined(__dsPIC33FJ256MC510__) || defined(__dsPIC33FJ64MC710__) || \
defined(__dsPIC33FJ128MC710__) || defined(__dsPIC33FJ256MC710__) ||
defined(__PIC24HJ64GP210__) || defined(__PIC24HJ128GP210__) || \
defined(__PIC24HJ128GP310__) || defined(__PIC24HJ64GP506__) ||
defined(__PIC24HJ256GP210__) || defined(__PIC24HJ128GP510__) || \
defined(__PIC24HJ256GP610__)

#define EnableCN22 asm ("BSET CNEN2,#6")


#define EnableCN23 asm ("BSET CNEN2,#7")
#endif

/* Macros to Disable CN interrupts */


#define DisableCN0 asm ("BCLR CNEN1,#0")
#define DisableCN1 asm ("BCLR CNEN1,#1")
#define DisableCN2 asm ("BCLR CNEN1,#2")
#define DisableCN3 asm ("BCLR CNEN1,#3")
#define DisableCN4 asm ("BCLR CNEN1,#4")
#define DisableCN5 asm ("BCLR CNEN1,#5")
#define DisableCN6 asm ("BCLR CNEN1,#6")
#define DisableCN7 asm ("BCLR CNEN1,#7")

#if defined(__dsPIC30F5011__) || defined(__dsPIC30F6011__) ||


defined(__dsPIC30F6012__) || \
defined(__dsPIC30F6010__) || defined(__dsPIC30F5013__) ||
defined(__dsPIC30F6013__) || \
defined(__dsPIC30F6014__) || defined(__dsPIC30F5015__) ||
defined(__dsPIC30F6010A__) || \
defined(__dsPIC30F6011A__) || defined(__dsPIC30F6012A__) ||
defined(__dsPIC30F6013A__) || \
defined(__dsPIC30F6014A__) || defined(__dsPIC30F5016__) ||
defined(__dsPIC30F6015__) || \
defined (__dsPIC33FJ64GP206__) ||
defined(__dsPIC33FJ128GP206__) || defined(__dsPIC33FJ64GP306__) ||
defined(__dsPIC33FJ128GP306__) || \
defined(__dsPIC33FJ256GP506__) || defined(__dsPIC33FJ64GP706__) ||
defined(__dsPIC33FJ128GP706__) || defined(__dsPIC33FJ128MC708__) || \
defined(__dsPIC33FJ64MC508__) || defined(__dsPIC33FJ128MC506__) ||
defined(__dsPIC33FJ64MC506__) || defined(__dsPIC33FJ128MC706__) || \
defined(__dsPIC33FJ64MC506__) || defined(__PIC24HJ64GP506__) ||
defined(__PIC24HJ128GP506__) || defined(__PIC24HJ128GP306__) || \
defined(__PIC24HJ64GP206__) || defined(__PIC24HJ128GP206__) ||
defined(__PIC24HJ256GP206__) || \
defined(__dsPIC33FJ64GP708__) || defined(__dsPIC33FJ128GP708__) ||
defined(__dsPIC33FJ64GP310__) || defined(__dsPIC33FJ128GP310__) || \
defined(__dsPIC33FJ256GP510__) || defined(__dsPIC33FJ64GP710__) ||
defined(__dsPIC33FJ128GP710__) || defined(__dsPIC33FJ256MC710__) || \
defined(__dsPIC33FJ64MC510__) || defined(__dsPIC33FJ128MC510__) ||
defined(__dsPIC33FJ256MC510__) || defined(__dsPIC33FJ64MC710__) || \
defined(__dsPIC33FJ128MC710__) || defined(__dsPIC33FJ256MC710__) ||
defined(__PIC24HJ64GP210__) || defined(__PIC24HJ128GP210__) || \
defined(__PIC24HJ128GP310__) || defined(__PIC24HJ64GP506__) ||
defined(__PIC24HJ256GP210__) || defined(__PIC24HJ128GP510__) || \
defined(__PIC24HJ256GP610__)

#define DisableCN8 asm ("BCLR CNEN1,#8")


#define DisableCN9 asm ("BCLR CNEN1,#9")
#define DisableCN10 asm ("BCLR CNEN1,#10")
#define DisableCN11 asm ("BCLR CNEN1,#11")
#define DisableCN12 asm ("BCLR CNEN1,#12")
#define DisableCN13 asm ("BCLR CNEN1,#13")
#define DisableCN14 asm ("BCLR CNEN1,#14")
#define DisableCN15 asm ("BCLR CNEN1,#15")
#define DisableCN16 asm ("BCLR CNEN2,#0")
#define DisableCN17 asm ("BCLR CNEN2,#1")
#define DisableCN18 asm ("BCLR CNEN2,#2")
#endif

#if defined(__dsPIC30F6010__) || defined(__dsPIC30F5013__) ||


defined(__dsPIC30F6013__) || \
defined(__dsPIC30F6014__) || defined(__dsPIC30F6010A__) ||
defined(__dsPIC30F6013A__) || \
defined(__dsPIC30F6014A__) || defined(__dsPIC30F5016__) || \
defined(__dsPIC33FJ64GP708__) ||
defined(__dsPIC33FJ128GP708__) || defined(__dsPIC33FJ64GP310__) ||
defined(__dsPIC33FJ128GP310__) || \
defined(__dsPIC33FJ256GP510__) || defined(__dsPIC33FJ64GP710__) ||
defined(__dsPIC33FJ128GP710__) || defined(__dsPIC33FJ256MC710__) || \
defined(__dsPIC33FJ64MC510__) || defined(__dsPIC33FJ128MC510__) ||
defined(__dsPIC33FJ256MC510__) || defined(__dsPIC33FJ64MC710__) || \
defined(__dsPIC33FJ128MC710__) || defined(__dsPIC33FJ256MC710__) ||
defined(__PIC24HJ64GP210__) || defined(__PIC24HJ128GP210__) || \
defined(__PIC24HJ128GP310__) || defined(__PIC24HJ64GP506__) ||
defined(__PIC24HJ256GP210__) || defined(__PIC24HJ128GP510__) || \
defined(__PIC24HJ256GP610__)

#define DisableCN19 asm ("BCLR CNEN2,#3")


#define DisableCN20 asm ("BCLR CNEN2,#4")
#define DisableCN21 asm ("BCLR CNEN2,#5")
#endif

#if defined(__dsPIC30F5013__) || defined(__dsPIC30F6013__) ||


defined(__dsPIC30F6014__) || \
defined(__dsPIC30F6013A__) || defined(__dsPIC30F6014A__) ||
defined(__dsPIC33FJ64GP708__) || defined(__dsPIC33FJ128GP708__) ||
defined(__dsPIC33FJ64GP310__) || defined(__dsPIC33FJ128GP310__) || \
defined(__dsPIC33FJ256GP510__) || defined(__dsPIC33FJ64GP710__) ||
defined(__dsPIC33FJ128GP710__) || defined(__dsPIC33FJ256MC710__) || \
defined(__dsPIC33FJ64MC510__) || defined(__dsPIC33FJ128MC510__) ||
defined(__dsPIC33FJ256MC510__) || defined(__dsPIC33FJ64MC710__) || \
defined(__dsPIC33FJ128MC710__) || defined(__dsPIC33FJ256MC710__) ||
defined(__PIC24HJ64GP210__) || defined(__PIC24HJ128GP210__) || \
defined(__PIC24HJ128GP310__) || defined(__PIC24HJ64GP506__) ||
defined(__PIC24HJ256GP210__) || defined(__PIC24HJ128GP510__) || \
defined(__PIC24HJ256GP610__)

#define DisableCN22 asm ("BCLR CNEN2,#6")


#define DisableCN23 asm ("BCLR CNEN2,#7")
#endif

//////////////////////////////////////////////////////////////////////////////////////////////
/* Macros to Enable External interrupts */

#if defined(__dsPIC33FJ64GP206__) || defined(__dsPIC33FJ64GP306__) ||


defined(__dsPIC33FJ64GP310__) || defined(__dsPIC33FJ64GP706__) || \
defined(__dsPIC33FJ64GP708__) ||
defined(__dsPIC33FJ64GP710__) || defined(__dsPIC33FJ128GP206__) ||
defined(__dsPIC33FJ128GP306__) || \
defined(__dsPIC33FJ128GP310__) ||
defined(__dsPIC33FJ128GP706__) || defined(__dsPIC33FJ128GP708__) ||
defined(__dsPIC33FJ128GP710__) || \
defined(__dsPIC33FJ256GP506__) ||
defined(__dsPIC33FJ256GP510__) || defined(__dsPIC33FJ256GP710__) ||
defined(__dsPIC33FJ64MC506__) || \
defined(__dsPIC33FJ64MC508__) ||
defined(__dsPIC33FJ64MC510__) || defined(__dsPIC33FJ64MC706__) ||
defined(__dsPIC33FJ64MC710__) || \
defined(__dsPIC33FJ128MC506__) ||
defined(__dsPIC33FJ128MC510__) || defined(__dsPIC33FJ128MC706__) ||
defined(__dsPIC33FJ128MC708__) || \
defined(__dsPIC33FJ128MC710__) ||
defined(__dsPIC33FJ256MC510__) || defined(__dsPIC33FJ256MC710__) ||
defined(__PIC24HJ64GP206__) || \
defined(__PIC24HJ64GP210__) || defined(__PIC24HJ64GP506__) ||
defined(__PIC24HJ64GP510__) || defined(__PIC24HJ128GP206__) || \
defined(__PIC24HJ128GP210__) || defined(__PIC24HJ128GP506__)
|| defined(__PIC24HJ128GP510__) || defined(__PIC24HJ128GP306__) || \
defined(__PIC24HJ128GP310__) || defined(__PIC24HJ256GP206__)
|| defined(__PIC24HJ256GP210__) || \
defined(__PIC24HJ256GP610__)
/* Enable 33F and 24H interrupts */

#define EnableINT0 asm ("BSET IEC0, #0")


#define EnableINT1 asm ("BSET IEC1, #4")
#define EnableINT2 asm ("BSET IEC1, #13")
#define EnableINT3 asm ("BSET IEC3, #5")
#define EnableINT4 asm ("BSET IEC3, #6")

/* disable 33F and 24H interrupts */

#define DisableINT0 asm ("BCLR IEC0, #0")


#define DisableINT1 asm ("BCLR IEC1, #4")
#define DisableINT2 asm ("BCLR IEC1, #13")
#define DisableINT3 asm ("BCLR IEC3, #5")
#define DisableINT4 asm ("BCLR IEC3, #6")

#define SetPriorityInt0(priority) (IPC0bits.INT0IP = priority)


#define SetPriorityInt1(priority) (IPC5bits.INT1IP = priority)
#define SetPriorityInt2(priority) (IPC7bits.INT2IP = priority)
#define SetPriorityInt3(priority) (IPC13bits.INT3IP = priority)
#define SetPriorityInt4(priority) (IPC13bits.INT4IP = priority)

#else

/* Enable 30F interrupts */

#define EnableINT0 asm ("BSET IEC0, #0")


#define EnableINT1 asm ("BSET IEC1, #0")
#define EnableINT2 asm ("BSET IEC1, #7")
#define EnableINT3 asm ("BSET IEC2, #4")
#define EnableINT4 asm ("BSET IEC2, #5")

/* Enable 30F interrupts */

#define DisableINT0 asm ("BCLR IEC0, #0")


#define DisableINT1 asm ("BCLR IEC1, #0")
#define DisableINT2 asm ("BCLR IEC1, #7")
#define DisableINT3 asm ("BCLR IEC2, #4")
#define DisableINT4 asm ("BCLR IEC2, #5")

/* Macros to set priority for External interrupts */

#define SetPriorityInt0(priority) (IPC0bits.INT0IP = priority)


#define SetPriorityInt1(priority) (IPC4bits.INT1IP = priority)
#define SetPriorityInt2(priority) (IPC5bits.INT2IP = priority)
#define SetPriorityInt3(priority) (IPC9bits.INT3IP = priority)
#define SetPriorityInt4(priority) (IPC9bits.INT4IP = priority)

#endif

/* Function Prototypes */

/* ConfigCNPullups
* Enable/ disable pull up registers
*/
void ConfigCNPullups(long int) __attribute__ ((section (".libperi")));

/* ConfigIntCN
* Enable/Disable CN interrupt and set priority
*/
void ConfigIntCN(long int) __attribute__ ((section (".libperi")));

/* configINT0
* Enable/disable INT0 interrupts,set priority and falling edge/rising edge
*/
void configINT0(unsigned int) __attribute__ ((section (".libperi")));

/* CloseINT0
* Disable INT0 interrupts, registers
*/
void CloseINT0() __attribute__ ((section (".libperi")));

/* configINT1
* Enable/disable INT1 interrupt,set priority and falling edge/rising edge
*/
void configINT1(unsigned int) __attribute__ ((section (".libperi")));

/* CloseINT1
* Disable INT1 interrupts, registers
*/
void CloseINT1() __attribute__ ((section (".libperi")));

/* configINT2
* Enable/disable INT2 interrupt,set priority and falling edge/rising edge
*/
void configINT2(unsigned int) __attribute__ ((section (".libperi")));
/* CloseINT2
* Disable INT2 interrupts, registers
*/
void CloseINT2() __attribute__ ((section (".libperi")));

#if defined(__dsPIC30F6010__) || defined(__dsPIC30F5011__) ||


defined(__dsPIC30F6011__)|| \
defined(__dsPIC30F6012__) || defined(__dsPIC30F5013__) ||
defined(__dsPIC30F6013__)|| \
defined(__dsPIC30F6014__) || defined(__dsPIC30F6010A__) ||
defined(__dsPIC30F6011A__) || \
defined(__dsPIC30F6012A__) || defined(__dsPIC30F6013A__) ||
defined(__dsPIC30F6014A__) || \
defined(__dsPIC30F5016__) || defined(__dsPIC30F6015__) ||
defined(__dsPIC33FJ64GP206__) || defined(__dsPIC33FJ64GP306__) ||
defined(__dsPIC33FJ64GP310__) || defined(__dsPIC33FJ64GP706__) || \
defined(__dsPIC33FJ64GP708__) ||
defined(__dsPIC33FJ64GP710__) || defined(__dsPIC33FJ128GP206__) ||
defined(__dsPIC33FJ128GP306__) || \
defined(__dsPIC33FJ128GP310__) ||
defined(__dsPIC33FJ128GP706__) || defined(__dsPIC33FJ128GP708__) ||
defined(__dsPIC33FJ128GP710__) || \
defined(__dsPIC33FJ256GP506__) ||
defined(__dsPIC33FJ256GP510__) || defined(__dsPIC33FJ256GP710__) ||
defined(__dsPIC33FJ64MC506__) || \
defined(__dsPIC33FJ64MC508__) ||
defined(__dsPIC33FJ64MC510__) || defined(__dsPIC33FJ64MC706__) ||
defined(__dsPIC33FJ64MC710__) || \
defined(__dsPIC33FJ128MC506__) ||
defined(__dsPIC33FJ128MC510__) || defined(__dsPIC33FJ128MC706__) ||
defined(__dsPIC33FJ128MC708__) || \
defined(__dsPIC33FJ128MC710__) ||
defined(__dsPIC33FJ256MC510__) || defined(__dsPIC33FJ256MC710__) ||
defined(__PIC24HJ64GP206__) || \
defined(__PIC24HJ64GP210__) || defined(__PIC24HJ64GP506__) ||
defined(__PIC24HJ64GP510__) || defined(__PIC24HJ128GP206__) || \
defined(__PIC24HJ128GP210__) || defined(__PIC24HJ128GP506__)
|| defined(__PIC24HJ128GP510__) || defined(__PIC24HJ128GP306__) || \
defined(__PIC24HJ128GP310__) || defined(__PIC24HJ256GP206__)
|| defined(__PIC24HJ256GP210__) || \
defined(__PIC24HJ256GP610__)
/* configINT3
* Enable/disable INT3 interrupt,set priority and falling edge/rising edge
*/
void configINT3(unsigned int) __attribute__ ((section (".libperi")));

/* CloseINT3
* Disable INT3 interrupts, registers
*/
void CloseINT3() __attribute__ ((section (".libperi")));

/* configINT4
* Enable/disable INT4 interrupt,set priority and falling edge/rising edge
*/
void configINT4(unsigned int) __attribute__ ((section (".libperi")));

/* CloseINT4
* Disable INT4 interrupts, registers
*/
void CloseINT4() __attribute__ ((section (".libperi")));

#endif

#endif
// include files
#include <p30fxxxx.h>
#include <can.h>
#define dataarray 0x0900

// config bits
_FOSC(ECIO);
_FWDT(WDT_OFF);

// defines

// function prototypes
void CAN_Init(void);
void PIC_Init(void);
int SendCANMsg (void);

// global vars
// CAN variables
/* Length of data to be transmitted/read */
unsigned char datalen;
unsigned char Txdata[] = {'M','I','C','R','O','C','H','I','P','\0'};
unsigned int TXConfig, RXConfig;
unsigned long MaskID,MessageID;
char FilterNo, tx_rx_no;
unsigned char * datareceived = (unsigned char *) dataarray; /* Holds
the data received */

// global vars modified by ISR (volatile)

int main(void)
{
unsigned int eeAddr, eeData, i, j;

Nop();
PIC_Init();
Nop();
CAN_Init();

while(1)
{
// send msg on buttonpress
if(PORTDbits.RD8 == 0)
{
// small debounce
for(i=0; i<0xFFFF; i++);

if(PORTDbits.RD8 == 0)
{
j = 0;
j = SendCANMsg();
}
}
}

return 0;
}
//
// function definitions

void PIC_Init(void)
{
// all digital I/O
ADPCFG = 0xFFFF;

TRISD = 0xFFFF;

TRISFbits.TRISF0 = 1;
TRISFbits.TRISF1 = 0;

TRISBbits.TRISB0 = 0;
TRISBbits.TRISB1 = 0;

Nop();

}
//

void CAN_Init(void)
{

/* Set request for configuration mode */


CAN1SetOperationMode(CAN_IDLE_CON &
CAN_MASTERCLOCK_0
&

CAN_REQ_OPERMODE_CONFIG &
CAN_CAPTURE_DIS);

// verify config mode has been entered


while(C1CTRLbits.OPMODE <=3);

/* Load configuration register */


CAN1Initialize( CAN_SYNC_JUMP_WIDTH2 &
CAN_BAUD_PRE_SCALE(5),
CAN_WAKEUP_BY_FILTER_DIS
&
CAN_PHASE_SEG2_TQ(3) &
CAN_PHASE_SEG1_TQ(3) &

CAN_PROPAGATIONTIME_SEG_TQ(3) &
CAN_SEG2_FREE_PROG &
CAN_SAMPLE3TIMES);

/* Load Acceptance filter register */


FilterNo = 0;

CAN1SetFilter( FilterNo,
CAN_FILTER_SID(0x0821) &
CAN_RX_EID_DIS,
CAN_FILTER_EID(0x00000000));

/* Load mask filter register */


CAN1SetMask( FilterNo,
CAN_MASK_SID(0xFFFF) &
CAN_MATCH_FILTER_TYPE,
CAN_MASK_EID(0x00000000));

/* Set transmitter and receiver mode */


tx_rx_no = 0;

CAN1SetTXMode( tx_rx_no, CAN_TX_STOP_REQ &


CAN_TX_PRIORITY_HIGH );

CAN1SetRXMode( tx_rx_no, CAN_RXFUL_CLEAR &


CAN_BUF0_DBLBUFFER_EN);

/* Set request for Normal mode */


CAN1SetOperationMode(CAN_IDLE_CON &
CAN_CAPTURE_DIS & CAN_MASTERCLOCK_1 &
CAN_REQ_OPERMODE_NOR);

// verify normal mode has been entered


while(C1CTRLbits.OPMODE != 0);

/* Set request for Loopback mode */


// CAN1SetOperationMode(CAN_IDLE_CON &
CAN_CAPTURE_DIS & CAN_MASTERCLOCK_1 &
CAN_REQ_OPERMODE_LOOPBK);

// verify loopback mode has been entered


// while(C1CTRLbits.OPMODE != 2);

PORTBbits.RB1 = 1;

return;

}
//

int SendCANMsg (void)


{

/* Load message ID, Data into transmit buffer and set transmit
request bit */
datalen = 8;
CAN1SendMessage((CAN_TX_SID(0x0821)) & CAN_TX_EID_DIS
& CAN_SUB_NOR_TX_REQ,
(CAN_TX_EID(0x00000000)) &
CAN_NOR_TX_REQ,
Txdata,datalen, tx_rx_no);

Nop();

/* Wait till message is transmitted completely */


while(!CAN1IsTXReady(0));

PORTBbits.RB0 = 1;

/* Wait till receive buffer contain valid message */


while(!CAN1IsRXReady(0));

/* Read received data from receive buffer and store it into user
defined dataarray */
CAN1ReceiveMessage(datareceived, datalen, tx_rx_no);
Nop();

return(1);

}
//

//*****************************************************************
//* CAN_Crosswire.c *
//*****************************************************************
//* *
//* Written by: Priyabrata Sinha *
//* Applications Engr. *
//* Microchip Technology Inc. *
//* Date: 6 April 2004 *
//* Revision: 1.00 *
//*****************************************************************
// modified to test on 30F4011 *
//*****************************************************************

#include "p30F4011.h"

#define FCY (4*7372800L) /*w/ PLLx4 */


//#define BITRATE 115200L
//#define BITRATE 230400L
//#define BITRATE 307201L
#define BITRATE 460800L
//#define BITRATE 921600L
// #define BITRATE 1000000

//---------------------------------------------------------------------

// Buffers for CAN data


unsigned int OutData0[4] = {0x0000, 0x0000, 0x0000, 0x0000};
unsigned int OutData1[4] = {0x0000, 0x0000, 0x0000, 0x0000};
unsigned int OutData2 = 0x0000;
unsigned int OutData3[4] = {0x0000, 0x0000, 0x0000, 0x0000};
unsigned int OutData4[4] = {0x0000, 0x0000, 0x0000, 0x0000};
unsigned int OutData5 = 0x0000;

unsigned int InData0[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};


unsigned int InData1[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
unsigned int InData2 = 0xFFFF;
unsigned int InData3[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
unsigned int InData4[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
unsigned int InData5 = 0xFFFF;

unsigned int testval;


//---------------------------------------------------------------------

int main(void)
{

TRISD = 0x0000;
LATD = 0xFFFF; // Initially LEDs are off

testval = ((FCY*4/32)/BITRATE)-1;
C1CTRLbits.CANCKS = 1;
//C1CTRLbits.CANCKS = 0; /* Fcan = Fcy*4 */
C1CFG1 = ((FCY/32)/BITRATE)-1;
// C1CFG1 = ((FCY*4/32)/BITRATE)-1;
C1CFG2 = 0x018A; // ph seg 1 = ph seg 2 =2 and prop =
3

// C1CFG2 = 0x06F0; // SEG1PH=7Tq, SEG2PH=7Tq, PRSEG=1Tq


// Sample 3 times
// Each bit time is 16Tq

C1INTF = 0;
IFS1bits.C1IF = 0;
C1INTE = 0x00FF; // Enable all interrupt sources
IEC1bits.C1IE = 1;

#if 0
C2CTRLbits.CANCKS = 1;
C2CFG1 = ((FCY/32)/BITRATE)-1;
// C2CFG2 = 0x06F0; // SEG1PH=7Tq, SEG2PH=7Tq, PRSEG=1Tq
// Sample 3 times
// Each bit time is 16Tq

C2INTF = 0;
IFS2bits.C2IF = 0;
C2INTE = 0x00FF; // Enable all interrupt sources
IEC2bits.C2IE = 1;
#endif

INTCON1bits.NSTDIS = 1;

//---------------------------------------------------------------------

// Configure Receive Buffers, Filters and Masks


C1RX0CON = C1RX1CON = 0x0000;

C1RXM0SID = C1RXM1SID = 0x1FFD;


C1RXM0EIDH = C1RXM1EIDH = 0x0FFF;
C1RXM0EIDL = C1RXM1EIDL = 0xFC00;

#if 0
C1RX0CON = C1RX1CON = C2RX0CON = C2RX1CON = 0x0000;

C1RXM0SID = C1RXM1SID = C2RXM0SID = C2RXM1SID = 0x1FFD;


C1RXM0EIDH = C1RXM1EIDH = C2RXM0EIDH = C2RXM1EIDH =
0x0FFF;
C1RXM0EIDL = C1RXM1EIDL = C2RXM0EIDL = C2RXM1EIDL =
0xFC00;
#endif

C1RXF0SID = 0x0AA8;
C1RXF2SID = 0x1555;
C1RXF2EIDH = 0x0004;
C1RXF2EIDL = 0x8C00;

#if 0
C2RXF0SID = 0x0AA8;
C2RXF2SID = 0x1555;
C2RXF2EIDH = 0x0004;
C2RXF2EIDL = 0x8C00;
#endif

C1TX0CON = 0x0003; // High priority


C1TX0SID = 0x50A8; // SID = 01010101010 (0x2AA)
C1TX0EID = 0x0000; // EID = 0000000000000000000 (0x00000)
C1TX0DLC = 0x01C0;
C1TX0B1 = OutData3[0];
C1TX0B2 = OutData3[1];
C1TX0B3 = OutData3[2];
C1TX0B4 = OutData3[3];
C1TX1CON = 0x0002; // High Intermediate priority
C1TX1SID = 0xA855; // SID = 10101010101 (0x555)
C1TX1EID = 0x0004; // EID = 1110000000100100011 (0x00123)
C1TX1DLC = 0x8DA0;
C1TX1DLCbits.DLC = 8; // TEST
C1TX1B1 = OutData4[0];
C1TX1B2 = OutData4[1];
C1TX1B3 = OutData4[2]; // TEST
C1TX1B4 = OutData4[3]; // TEST

C1TX2CON = 0x0001; // Low Intermediate priority


C1TX2SID = 0xA855; // SID = 10101010101 (0x555)
C1TX2EID = 0x000C; // EID = 1110000000100100011 (0x00321)
C1TX2DLC = 0x8590;
C1TX2B1 = OutData5;

#if 0
C2TX0CON = 0x0003; // High priority
C2TX0SID = 0x50A8; // SID = 01010101010 (0x2AA)
C2TX0EID = 0x0000; // EID = 0000000000000000000 (0x00000)
C2TX0DLC = 0x01C0;
C2TX0B1 = OutData0[0];
C2TX0B2 = OutData0[1];
C2TX0B3 = OutData0[2];
C2TX0B4 = OutData0[3];

C2TX1CON = 0x0002; // High Intermediate priority


C2TX1SID = 0xA855; // SID = 10101010101 (0x555)
C2TX1EID = 0x0004; // EID = 1110000000100100011 (0x00123)
C2TX1DLC = 0x8DA0;
C2TX1DLCbits.DLC = 8; // TEST
C2TX1B1 = OutData1[0];
C2TX1B2 = OutData1[1];
C2TX1B3 = OutData1[2]; // TEST
C2TX1B4 = OutData1[3]; // TEST

C2TX2CON = 0x0001; // Low Intermediate priority


C2TX2SID = 0xA855; // SID = 10101010101 (0x555)
C2TX2EID = 0x000C; // EID = 1110000000100100011 (0x00321)
C2TX2DLC = 0x8590;
C2TX2B1 = OutData2;
#endif
// Change to Normal Operation Mode
C1CTRLbits.REQOP = 0;
/// C2CTRLbits.REQOP = 0;
while(C1CTRLbits.OPMODE != 0); // Wait for CAN1 mode change
/// while(C2CTRLbits.OPMODE != 0); // Wait for CAN2 mode change

// Enable transmission
C1TX0CONbits.TXREQ = 1;
//C1TX1CONbits.TXREQ = 1;
//C1TX2CONbits.TXREQ = 1;
///// C2TX0CONbits.TXREQ = 1; // not available on 30F4011
//C2TX1CONbits.TXREQ = 1;
//C2TX2CONbits.TXREQ = 1;

while(1); // loop and wait for interrupt

} // end main

//---------------------------------------------------------------------

// Only in Interrupt mode

void __attribute__((__interrupt__)) _C1Interrupt(void)


{
IFS1bits.C1IF = 0; // clear interrupt flag
if (C1INTFbits.TX0IF)
C1INTFbits.TX0IF = 0;
if (C1INTFbits.TX1IF)
C1INTFbits.TX1IF = 0;
if (C1INTFbits.TX2IF)
C1INTFbits.TX2IF = 0;
if (C1INTFbits.RX0IF)
{
C1INTFbits.RX0IF = 0;
C1RX0CONbits.RXFUL = 0;
InData0[0] = C1RX0B1;
InData0[1] = C1RX0B2;
InData0[2] = C1RX0B3;
InData0[3] = C1RX0B4;
if ( (InData0[0]==OutData0[0]) && (InData0[1]==OutData0[1]) &&
(InData0[2]==OutData0[2]) && (InData0[3]==OutData0[3]) )
LATDbits.LATD0 = 0;
}
if (C1INTFbits.RX1IF)
{
C1INTFbits.RX1IF = 0;
C1RX1CONbits.RXFUL = 0;
InData1[0] = C1RX1B1;
InData1[1] = C1RX1B2;
InData1[2] = C1RX1B3;
InData1[3] = C1RX1B4;
if ( (InData1[0]==OutData1[0]) && (InData1[1]==OutData1[1]) &&
(InData1[2]==OutData1[2]) && (InData1[3]==OutData1[3]) )
LATDbits.LATD1 = 0;
}
if (C1INTFbits.ERRIF)
C1INTFbits.ERRIF = 0;
if (C1INTFbits.IVRIF)
C1INTFbits.IVRIF = 0;
}

//void __attribute__((__interrupt__)) _C2Interrupt(void)


//{
// IFS2bits.C2IF = 0; // clear interrupt flag
// if (C2INTFbits.TX0IF)
// C2INTFbits.TX0IF = 0;
// if (C2INTFbits.TX1IF)
// C2INTFbits.TX1IF = 0;
// if (C2INTFbits.TX2IF)
// C2INTFbits.TX2IF = 0;
// if(C2INTFbits.RX0IF)
// {
// C2INTFbits.RX0IF = 0;
// C2RX0CONbits.RXFUL = 0;
// InData3[0] = C2RX0B1;
// InData3[1] = C2RX0B2;
// InData3[2] = C2RX0B3;
// InData3[3] = C2RX0B4;
// if ( (InData3[0]==OutData3[0]) && (InData3[1]==OutData3[1]) &&
(InData3[2]==OutData3[2]) && (InData3[3]==OutData3[3]) )
// LATDbits.LATD2 = 0;
// }
// if(C2INTFbits.RX1IF)
// {
// C2INTFbits.RX1IF = 0;
// C2RX1CONbits.RXFUL = 0;
// InData4[0] = C2RX1B1;
// InData4[1] = C2RX1B2;
// InData4[2] = C2RX1B3;
// InData4[3] = C2RX1B4;
// if ( (InData4[0]==OutData4[0]) && (InData4[1]==OutData4[1]) &&
(InData4[2]==OutData4[2]) && (InData4[3]==OutData4[3]) )
// LATDbits.LATD3 = 0;
// }
// if (C2INTFbits.ERRIF)
// C2INTFbits.ERRIF = 0;
// if (C2INTFbits.IVRIF)
// C2INTFbits.IVRIF = 0;
//}

//---------------------------------------------------------------------
#include <p30f4011.h>
#include <qei.h>

volatile unsigned char QEI_Event;

void __attribute__((__interrupt__)) _QEIInterrupt(void)


{
IFS2bits.QEIIF = 0; // clear IF flag
QEI_Event = 1;
}

/
******************************************************************
********
* Function Name : CloseQEI()
* Description : This routine disables the QEI and its interrupt bits.
******************************************************************
*********/

void CloseQEI(void)
{
IEC2bits.QEIIE = 0; // disable interrupt
QEICONbits.QEIM = 0x0; // QEI/Timer off
IFS2bits.QEIIF = 0; // clear IF flag
}

/
******************************************************************
***
* Function Name : ConfigIntQEI()
* Description : This function Configures QEI Interrupt and interrupt
* priority and clears the interrupt
flag.
* Parameters : unsigned int
******************************************************************
***/

void ConfigIntQEI(unsigned int config)


{
IFS2bits.QEIIF = 0; // clear Interrupt flag
IPC10bits.QEIIP = config & 0x07; // bits <2:0> is the priority
IEC2bits.QEIIE = (config & 0x8)>>3; // bit 3 is interrupt enable/diable
}

/
******************************************************************
***
* Function Name : OpenQEI()
* Description : This function Clears the CNTERR bit and Configures
register
QEICON and DFLTCON for the QEI/Timer functionality.
* Parameters : unsigned int config1, unsigned int config2
******************************************************************
***/

void OpenQEI(unsigned int config1, unsigned int config2)


{
// clear CNTERR bit
QEICONbits.CNTERR = 0;

// configures the QEI/Timer


QEICON = config1 & 0x2fff;
// assign up/down
QEICONbits.UPDN = config1 >> 11;

// configures the Digital Filters


DFLTCON = config2;
}

#ifndef __QEI_H
#define __QEI_H

/* List of SFRs for QEI */


/* This list contains the SFRs with default (POR) values to be used for
configuring QEI */
/* The user can modify this based on the requirement */
#define QEICON_VALUE 0x0000
#define DFLTCON_VALUE 0x0000
#define POSCNT_VALUE 0x0000
#define MAXCNT_VALUE 0xFFFF

/* QEICON Configuration Bit Definitions */

#define QEI_DIR_SEL_QEB 0xFFFF /* QEB Pin State Defines


Position Counter Direction */
#define QEI_DIR_SEL_CNTRL 0xFFFE /* Control/Status Bit,
QEICON<11>, Defines Timer Counter (POSCNT) Direction */

#define QEI_EXT_CLK 0xFFFF /* External clock from pin TQCKI


(on the rising edge) */
#define QEI_INT_CLK 0xFFFD /* Internal clock (FOSC/4) */

#define QEI_INDEX_RESET_ENABLE 0xFFFF /* QEI Index Pulse


resets Position Counter */
#define QEI_INDEX_RESET_DISABLE 0xFFFB /* Index Pulse does not
reset Position Counter */

#define QEI_CLK_PRESCALE_1 0xFFE7 /* QEI Timer Input Clock


Prescale Select Bits */
#define QEI_CLK_PRESCALE_8 0xFFEF
#define QEI_CLK_PRESCALE_64 0xFFF7
#define QEI_CLK_PRESCALE_256 0xFFFF /* QEI 1:256 prescale value
*/

#define QEI_GATED_ACC_ENABLE 0xFFFF /* QEI Timer gated time


accumulation enabled */
#define QEI_GATED_ACC_DISABLE 0xFFDF /* Timer gated time
accumulation disabled */

#define QEI_LOGIC_CONTROL_IO 0xFFFF /* QEI Position Counter


Direction Status Output Enable(QEI logic controls state of I/O pin) */
#define QEI_NORMAL_IO 0xFFBF /* QEI Position Counter
Direction Status Output Disabled(Normal I/O pin operation) */

#define QEI_INPUTS_SWAP 0xFFFF /* QEI Phase A and Phase B


inputs swapped */
#define QEI_INPUTS_NOSWAP 0xFF7F /* QEI Phase A and Phase B
inputs not swapped */

#define QEI_MODE_x4_MATCH 0xFFFF /* QEI Quadrature Encoder


Interface enabled (x4 mode) with position counter reset by match (MAXCNT)
*/
#define QEI_MODE_x4_PULSE 0xFEFF /* QEI Quadrature Encoder
Interface enabled (x4 mode) with Index Pulse reset of position counter */
#define QEI_MODE_x2_MATCH 0xFDFF /* QEI Quadrature
Encoder Interface enabled (x2 mode) with position counter reset by match
(MAXCNT) */
#define QEI_MODE_x2_PULSE 0xFCFF /* QEI Quadrature Encoder
Interface enabled (x2 mode) with Index Pulse reset of position counter */
#define QEI_MODE_TIMER 0xF9FF /* QEI Starts 16-bit Timer */
#define QEI_MODE_OFF 0xF8FF /* QEI Quadrature Encoder
Interface/Timer off */

#define QEI_UP_COUNT 0xFFFF /* QEI Position Counter


Direction +VE */
#define QEI_DOWN_COUNT 0xF7FF /* QEI Position Counter
Direction -VE */

#define QEI_IDLE_STOP 0xFFFF /* QEI Discontinue module


operation when device enters a idle mode. */
#define QEI_IDLE_CON 0xDFFF /* QEI Continue module
operation in idle mode */
/* defines for the DFLTCON register */

#define QEI_QE_CLK_DIVIDE_1_1 0xFF8F /* QEI QEA/QEB Digital


Filter Clock Divide Select Bits */
#define QEI_QE_CLK_DIVIDE_1_2 0xFF9F
#define QEI_QE_CLK_DIVIDE_1_4 0xFFAF
#define QEI_QE_CLK_DIVIDE_1_16 0xFFBF
#define QEI_QE_CLK_DIVIDE_1_32 0xFFCF
#define QEI_QE_CLK_DIVIDE_1_64 0xFFDF
#define QEI_QE_CLK_DIVIDE_1_128 0xFFEF
#define QEI_QE_CLK_DIVIDE_1_256 0xFFFF /* QEI QEA/QEB Digital
Filter Clock Divide Select Bits */

#define QEI_QE_OUT_ENABLE 0xFFFF /* QEI QEA/QEB Digital


Filter Clock Divide Select Bits */
#define QEI_QE_OUT_DISABLE 0xFF7F /* QEI QEA/QEB Digital
Filter Clock Divide Select Bits */

#define POS_CNT_ERR_INT_ENABLE 0xFFFF /* Enable interrupt due


to position count errors */
#define POS_CNT_ERR_INT_DISABLE 0xFEFF /* Disable interrupt due
to position count errors */

#define MATCH_INDEX_PHASEB_HIGH 0xFFFF


#define MATCH_INDEX_PHASEB_LOW 0xFBFF

#define MATCH_INDEX_PHASEA_HIGH 0xFFFF


#define MATCH_INDEX_PHASEA_LOW 0xFDFF

#define MATCH_INDEX_INPUT_PHASEB 0xFFFF


#define MATCH_INDEX_INPUT_PHASEA 0xFBFF

#define MATCH_INDEX_INPUT_HIGH 0xFFFF


#define MATCH_INDEX_INPUT_LOW 0xFDFF

/* Setting the priority of QEI interrupt */


#define QEI_INT_PRI_0 0xFFF8
#define QEI_INT_PRI_1 0xFFF9
#define QEI_INT_PRI_2 0xFFFA
#define QEI_INT_PRI_3 0xFFFB
#define QEI_INT_PRI_4 0xFFFC
#define QEI_INT_PRI_5 0xFFFD
#define QEI_INT_PRI_6 0xFFFE
#define QEI_INT_PRI_7 0xFFFF

// Enable / Disable QEI interrupt


#define QEI_INT_ENABLE 0xFFFF /* Set the Interrupt enable bit
*/
#define QEI_INT_DISABLE 0xFF7F /* Clear the Interrupt enable bit
*/

#define QEI_EnableInt asm("BSET IEC2,#8")


#define QEI_DisableInt asm("BCLR IEC2,#8")
#define SetPriorityIntQEI(priority) (IPC10bits.QEIIP = priority)

extern volatile unsigned char QEI_Event;


// QEI Interrupt ISR Declaration
void __attribute__((__interrupt__)) _QEIInterrupt(void);

// QEI Function Prototypes

void OpenQEI(unsigned int config1, unsigned int config2) __attribute__


((section (".libperi"))); /* Configure QEI */

void CloseQEI(void) __attribute__ ((section (".libperi"))); /*


Disables the QEI module */

void ConfigIntQEI(unsigned int) __attribute__ ((section (".libperi"))); /*


QEI interrupt configuration */

#endif /*__QEI_H */

// RS232.c
// 12/22/06 From MicroChip C30 Library for dsPIC30F4011

#include <p30f4011.h>
#include "uart.h"

#include <p30f4011.h>
#include "uart.h"
char BusyUART1(void)
{
// Return TRUE if UART1 is busy Transmitting
return(!U1STAbits.TRMT);
}

char BusyUART2(void)
{
// Return TRUE if UART2 is busy Transmitting
return(!U2STAbits.TRMT);
}

void CloseUART1(void)
{
// Disables UART1 and Interrupt; Clear Flags
U1MODEbits.UARTEN = 0;
IEC0bits.U1RXIE = 0;
IEC0bits.U1TXIE = 0;
IFS0bits.U1RXIF = 0;
IFS0bits.U1TXIF = 0;
}

void CloseUART2(void)
{
// Disables UART2 and Interrupt; Clear Flags
U2MODEbits.UARTEN = 0;
IEC1bits.U2RXIE = 0;
IEC1bits.U2TXIE = 0;
IFS1bits.U2RXIF = 0;
IFS1bits.U2TXIF = 0;
}

void ConfigIntUART1(unsigned int config)


{
// clear IF flags
IFS0bits.U1RXIF = 0;
IFS0bits.U1TXIF = 0;
// set priority
IPC2bits.U1RXIP = 0x0007 & config;
IPC2bits.U1TXIP = (0x0070 & config) >> 4;
// enable/disable interrupt
IEC0bits.U1RXIE = (0x0008 & config) >> 3;
IEC0bits.U1TXIE = (0x0080 & config) >> 7;
}

void ConfigIntUART2(unsigned int config)


{
// clear IF flags
IFS1bits.U2RXIF = 0;
IFS1bits.U2TXIF = 0;
// set priority
IPC6bits.U2RXIP = 0x0007 & config;
IPC6bits.U2TXIP = (0x0070 & config) >> 4;
// enable/disable interrupt
IEC1bits.U2RXIE = (0x0008 & config) >> 3;
IEC1bits.U2TXIE = (0x0080 & config) >> 7;
}

char DataRdyUART1(void)
{
// Return true if Data is in the Read buffer
return(U1STAbits.URXDA);
}

char DataRdyUART2(void)
{
// Return true if Data is in the Read buffer
return(U2STAbits.URXDA);
}

/
************************************************************************
******
* Description : This function gets a string of data of specified
length *
* if available in the UxRXREG buffer into the buffer
*
* specified.
*
* Parameters : unsigned int length the length expected
*
* unsigned int *buffer the received data to be
*
* recorded to this array
*
* unsigned int uart_data_wait timeout value
*
* Return Value : unsigned int number of data bytes yet to be
received *
************************************************************************
******/

unsigned int getsUART1(unsigned int length,


unsigned int *buffer,
unsigned int uart_data_wait)
{
int wait = 0;
char *temp_ptr = (char *) buffer;
// read till length is 0
while(length)
{
while(!DataRdyUART1())
{
if (wait < uart_data_wait)
{
// wait for more data
wait++ ;
}
else
{
// Time out- Return words/bytes to be read
return(length);
}
}
wait=0;
// check if TX/RX is 8bits or 9bits
if (U1MODEbits.PDSEL == 3)
{
// data word from HW buffer to SW buffer
*buffer++ = U1RXREG;
}
else
{
// data byte from HW buffer to SW buffer
*temp_ptr++ = U1RXREG & 0xFF;
}
length--;
}
// number of data yet to be received i.e.,0
return(length);
}

unsigned int getsUART2(unsigned int length,unsigned int *buffer,


unsigned int uart_data_wait)

{
// Parameters
// unsigned int length: the length expected
// unsigned int *buffer: the received data to be recorded to this
array
// unsigned int uart_data_wait: timeout value
// Return Value = unsigned int number of data bytes yet to be received
int wait = 0;
char *temp_ptr = (char *) buffer;

// read till length is 0


while(length)
{
while(!DataRdyUART2())
{
if (wait < uart_data_wait)
{
// wait for more data
wait++;
}
else
{
// Time out- Return words/bytes to be read
return(length);
}
}
wait = 0;
// Check if TX/RX is 8bits or 9bits
if (U2MODEbits.PDSEL == 3)
{
// data word from HW buffer to SW buffer
*buffer++ = U2RXREG;
}
else
{
// data byte from HW buffer to SW buffer
*temp_ptr++ = U2RXREG & 0xFF;
}
length--;
}
// Return number of data yet to be received i.e.,0
return(length);
}

void OpenUART1(unsigned int config1,unsigned int config2, unsigned int


ubrg)
{
U1BRG = ubrg; // baud rate
U1MODE = config1; // operation settings
U1STA = config2; // TX & RX interrupt modes
}

void OpenUART2(unsigned int config1,unsigned int config2, unsigned int


ubrg)
{
U2BRG = ubrg; // baud rate
U2MODE = config1; // operation settings
U2STA = config2; // TX & RX interrupt modes
}

void putsUART1(unsigned int *buffer)


{
// Put the data string to be transmitted into the transmit buffer
(till NULL character)
// Parameter = unsigned int *address of the string buffer to be
transmitted
char * temp_ptr = (char *) buffer;
// transmit till NULL character is encountered
// check if TX is 8bits or 9bits
if (U1MODEbits.PDSEL == 3)
{
while(*buffer != '\0')
{
// wait if the buffer is full
while(U1STAbits.UTXBF);
// transfer data word to TX reg
U1TXREG = *buffer++;
}
}
else
{
while(*temp_ptr != '\0')
{
// wait if the buffer is full
while(U1STAbits.UTXBF);
// transfer data word to TX reg
U1TXREG = *temp_ptr++;
}
}
}

void putsUART2(unsigned int *buffer)


{
// Put the data string to be transmitted into the transmit buffer
(till NULL character)
// Parameter = unsigned int *address of the string buffer to be
transmitted
char * temp_ptr = (char *) buffer;
// transmit till NULL character is encountered
if(U2MODEbits.PDSEL == 3) /* check if TX is 8bits or 9bits */
{
while(*buffer != '\0')
{
// wait if the buffer is full
while(U2STAbits.UTXBF);
// transfer data byte to TX reg
U2TXREG = *buffer++;
}
}
else
{
while(*temp_ptr != '\0')
{
// wait if the buffer is full
while(U2STAbits.UTXBF);
// transfer data byte to TX reg
U2TXREG = *temp_ptr++;
}
}
}

unsigned int ReadUART1(void)


{
if (U1MODEbits.PDSEL == 3)
{
return (U1RXREG);
}
else
{
return (U1RXREG & 0xFF);
}
}

unsigned int ReadUART2(void)


{
if (U2MODEbits.PDSEL == 3)
{
return (U2RXREG);
}
else
{
return (U2RXREG & 0xFF);
}
}

void WriteUART1(unsigned int data)


{
// Write data into the UxTXREG
while(U1STAbits.UTXBF);
if (U1MODEbits.PDSEL == 3)
{
U1TXREG = data;
}
else
{
U1TXREG = data & 0xFF;
}
}

void WriteUART2(unsigned int data)


{
// Write data into the UxTXREG
while(U2STAbits.UTXBF);
if(U2MODEbits.PDSEL == 3)
{
U2TXREG = data;
}
else
{
U2TXREG = data & 0xFF;
}
}

void U2Trx_CrLf(void)
{
WriteUART2(0xD);
WriteUART2(0xA);
}

void U2Trx_Cr(void)
{
WriteUART2(0xD);
}
/// Timer1.c :: Timer1 Module
/// 10/30/06 Created
///

#include "p30fxxxx.h"
#include "Timer1.h"

volatile unsigned char Timer1_Done;

/// Initialize Timer1


void T1_Init(void)
{
Timer1_Done = 0;
T1CON = 0; // Timer reset
TMR1 = 0;
PR1 = 0xffff;
IFS0bits.T1IF = 0; // bcf INTCON,TMR0IF; Reset Timer1 Flag
IPC0bits.T1IP = 4; // Timer1 Interrupt priority level=4
IEC0bits.T1IE = 1; // bcf INTCON,TMR0IE; Disable Timer 1 Interrupt
T1CONbits.TON = 1; // Enable Timer1 and start the counter
}

/// Interrupt Service Routine


void __attribute__((__interrupt__)) _T1Interrupt(void)
{
T1CONbits.TON = 0; // Turn off the Timer
IFS0bits.T1IF = 0; // Reset T1 Interrupt Flag
Timer1_Done = 1; // Set the Timer1 Done Status Flag
}

/********************************************************************
Header for UART module library functions
********************************************************************/
#ifndef __UART_H
#define __UART_H

/* List of SFRs for UART */


/* This list contains the SFRs with default (POR) values to be used for
configuring UART */
/* The user can modify this based on the requirement */
#define UxMODE_VALUE 0x0000
#define UxSTA_VALUE 0x0110
#define UxTXREG_VALUE 0x0000
#define UxRXREG_VALUE 0x0000
#define UxBRG_VALUE 0x0000

#define getcUART1 ReadUART1


#define putcUART1 WriteUART1

#define getcUART2 ReadUART2


#define putcUART2 WriteUART2

/* definitions for 30F4011 device */

/* defines for UxMODE register */


#define UART_EN 0xEFE7 /* Module enable */
#define UART_DIS 0x6FE7 /* Module disable */

#define UART_IDLE_CON 0xCFE7 /* Work in IDLE mode */


#define UART_IDLE_STOP 0xEFE7 /* Stop all functions in
IDLE mode*/

/*ALTIO pin for UART1 is defined for following devices */

#define UART_ALTRX_ALTTX 0xEFE7 /*Communication through ALT


pins*/
#define UART_RX_TX 0xEBE7 /*Communication through
the normal pins*/

#define UART_EN_WAKE 0xEFE7 /*Enable Wake-up on


START bit Detect during SLEEP Mode bit*/
#define UART_DIS_WAKE 0xEF67 /*Disable Wake-up on
START bit Detect during SLEEP Mode bit*/

#define UART_EN_LOOPBACK 0xEFE7 /*Loop back enabled*/


#define UART_DIS_LOOPBACK 0xEFA7 /*Loop back disabled*/

#define UART_EN_ABAUD 0xEFE7 /*Input to Capture


module from UxRX pin*/
#define UART_DIS_ABAUD 0xEFC7 /*Input to Capture
module from ICx pin*/

#define UART_NO_PAR_9BIT 0xEFE7 /*No parity 9 bit*/


#define UART_ODD_PAR_8BIT 0xEFE5 /*odd parity 8 bit*/
#define UART_EVEN_PAR_8BIT 0xEFE3 /*even parity 8 bit*/
#define UART_NO_PAR_8BIT 0xEFE1 /*no parity 8 bit*/

#define UART_2STOPBITS 0xEFE7 /*2 stop bits*/


#define UART_1STOPBIT 0xEFE6 /*1 stop bit*/

/* defines for UART Status register */

#define UART_INT_TX_BUF_EMPTY 0xFFFF /* Interrupt on TXBUF


becoming empty */
#define UART_INT_TX 0x7FFF /* Interrupt on transfer
of every character to TSR */

#define UART_TX_PIN_NORMAL 0xF7FF /* UART TX pin operates


normally */
#define UART_TX_PIN_LOW 0xFFFF /* UART TX pin driven
low */

#define UART_TX_ENABLE 0xFFFF /* Transmit enable */


#define UART_TX_DISABLE 0xFBFF /* Transmit disable */

#define UART_INT_RX_BUF_FUL 0xFFFF /* Interrupt on RXBUF


full */
#define UART_INT_RX_3_4_FUL 0xFFBF /* Interrupt on RXBUF
3/4 full */
#define UART_INT_RX_CHAR 0xFF7F /* Interrupt on every
char received */\

#define UART_ADR_DETECT_EN 0xFFFF /* address detect enable


*/
#define UART_ADR_DETECT_DIS 0xFFDF /* address detect
disable */

#define UART_RX_OVERRUN_CLEAR 0xFFFD /* Rx buffer Over run


status bit clear */

/* defines for UART Interrupt configuartion */


#define UART_RX_INT_EN 0xFFFF /*Receive interrupt
enabled*/
#define UART_RX_INT_DIS 0xFFF7 /*Receive interrupt
disabled*/

#define UART_RX_INT_PR0 0xFFF8 /*Priority RX interrupt


0*/
#define UART_RX_INT_PR1 0xFFF9 /*Priority RX interrupt
1*/
#define UART_RX_INT_PR2 0xFFFA /*Priority RX interrupt
2*/
#define UART_RX_INT_PR3 0xFFFB /*Priority RX interrupt
3*/
#define UART_RX_INT_PR4 0xFFFC /*Priority RX interrupt
4*/
#define UART_RX_INT_PR5 0xFFFD /*Priority RX interrupt
5*/
#define UART_RX_INT_PR6 0xFFFE /*Priority RX interrupt
6*/
#define UART_RX_INT_PR7 0xFFFF /*Priority RX interrupt
7*/

#define UART_TX_INT_EN 0xFFFF /*transmit interrupt


enabled*/
#define UART_TX_INT_DIS 0xFF7F /*transmit interrupt
disabled*/

#define UART_TX_INT_PR0 0xFF8F /*Priority TX interrupt


0*/
#define UART_TX_INT_PR1 0xFF9F /*Priority TX interrupt
1*/
#define UART_TX_INT_PR2 0xFFAF /*Priority TX interrupt
2*/
#define UART_TX_INT_PR3 0xFFBF /*Priority TX interrupt
3*/
#define UART_TX_INT_PR4 0xFFCF /*Priority TX interrupt
4*/
#define UART_TX_INT_PR5 0xFFDF /*Priority TX interrupt
5*/
#define UART_TX_INT_PR6 0xFFEF /*Priority TX interrupt
6*/
#define UART_TX_INT_PR7 0xFFFF /*Priority TX interrupt
7*/

/* Macros to Enable/Disable interrupts and set Interrupt priority of


UART1 */
#define EnableIntU1RX asm("BSET IEC0,#9")
#define EnableIntU1TX asm("BSET IEC0,#10")

#define DisableIntU1RX asm("BCLR IEC0,#9")


#define DisableIntU1TX asm("BCLR IEC0,#10")

#define SetPriorityIntU1RX(priority) (IPC2bits.U1RXIP =


priority)
#define SetPriorityIntU1TX(priority) (IPC2bits.U1TXIP =
priority)

/************************Function prototype**************************/
void putsUART1(unsigned int *buffer) __attribute__ ((section
(".libperi")));

void WriteUART1(unsigned int data) __attribute__ ((section


(".libperi")));

void CloseUART1(void) __attribute__ ((section (".libperi")));

void ConfigIntUART1(unsigned int config) __attribute__ ((section


(".libperi")));

char DataRdyUART1(void) __attribute__ ((section (".libperi")));

unsigned int getsUART1(unsigned int length,unsigned int *buffer,


unsigned int uart_data_wait) __attribute__
((section (".libperi")));

void OpenUART1(unsigned int config1,unsigned int config2,


unsigned int ubrg) __attribute__ ((section (".libperi")));

unsigned int ReadUART1(void) __attribute__ ((section


(".libperi")));

char BusyUART1(void) __attribute__ ((section (".libperi")));

/*UART2 is defined in 30F4011 */

/* Macros to Enable/Disable interrupts and set Interrupt priority of


UART2 */
#define EnableIntU2RX asm("BSET
IEC1,#8")
#define EnableIntU2TX asm("BSET
IEC1,#9")

#define DisableIntU2RX asm("BCLR


IEC1,#8")
#define DisableIntU2TX asm("BCLR
IEC1,#9")

#define SetPriorityIntU2RX(priority)
(IPC6bits.U2RXIP = priority)
#define SetPriorityIntU2TX(priority)
(IPC6bits.U2TXIP = priority)

void putsUART2(unsigned int *buffer) __attribute__


((section (".libperi")));

void WriteUART2(unsigned int data) __attribute__


((section (".libperi")));

void CloseUART2(void) __attribute__ ((section


(".libperi")));

void ConfigIntUART2(unsigned int config) __attribute__


((section (".libperi")));
char DataRdyUART2(void) __attribute__ ((section
(".libperi")));

unsigned int getsUART2(unsigned int length,unsigned int


*buffer,
unsigned int uart_data_wait) __attribute__
((section (".libperi")));

void OpenUART2(unsigned int config1,unsigned int


config2, unsigned int ubrg) __attribute__ ((section (".libperi")));

unsigned int ReadUART2(void) __attribute__ ((section


(".libperi")));

char BusyUART2(void) __attribute__ ((section


(".libperi")));

#endif /*__UART_H */
/********************************************************************/
/* Header for SPI module library functions */
/********************************************************************/
#ifndef __SPI_H
#define __SPI_H

/* List of SFRs for SPI */


/* This list contains the SFRs with default (POR) values to be used for
configuring SPI */
/* The user can modify this based on the requirement */

#define SPI1STAT_VALUE 0x0000


#define SPI2STAT_VALUE 0x0000
#define SPI1BUF_VALUE 0x0000
#define SPI2BUF_VALUE 0x0000

#if defined(__dsPIC33FJ64GP206__) || defined(__dsPIC33FJ64GP306__) ||


defined(__dsPIC33FJ64GP310__) || defined(__dsPIC33FJ64GP706__) || \
defined(__dsPIC33FJ64GP708__) || defined(__dsPIC33FJ64GP710__)
|| defined(__dsPIC33FJ128GP206__) || defined(__dsPIC33FJ128GP306__) || \
defined(__dsPIC33FJ128GP310__) || defined(__dsPIC33FJ128GP706__)
|| defined(__dsPIC33FJ128GP708__) || defined(__dsPIC33FJ128GP710__) || \
defined(__dsPIC33FJ256GP506__) || defined(__dsPIC33FJ256GP510__)
|| defined(__dsPIC33FJ256GP710__) || defined(__dsPIC33FJ64MC506__) || \
defined(__dsPIC33FJ64MC508__) || defined(__dsPIC33FJ64MC510__)
|| defined(__dsPIC33FJ64MC706__) || defined(__dsPIC33FJ64MC710__) || \
defined(__dsPIC33FJ128MC506__) || defined(__dsPIC33FJ128MC510__)
|| defined(__dsPIC33FJ128MC706__) || defined(__dsPIC33FJ128MC708__) || \
defined(__dsPIC33FJ128MC710__) || defined(__dsPIC33FJ256MC510__)
|| defined(__dsPIC33FJ256MC710__) ||defined(__PIC24HJ64GP206__) || \
defined(__PIC24HJ64GP210__) || defined(__PIC24HJ64GP506__) ||
defined(__PIC24HJ64GP510__) || defined(__PIC24HJ128GP206__) || \
defined(__PIC24HJ128GP210__) || defined(__PIC24HJ128GP506__) ||
defined(__PIC24HJ128GP510__) || defined(__PIC24HJ128GP306__) || \
defined(__PIC24HJ128GP310__) || defined(__PIC24HJ256GP206__) ||
defined(__PIC24HJ256GP210__) || \
defined(__PIC24HJ256GP610__)

#define SPI1CON1_VALUE 0x0000


#define SPI2CON1_VALUE 0x0000
#define SPI1CON2_VALUE 0x0000
#define SPI2CON2_VALUE 0x0000

#else

#define SPI1CON_VALUE 0x0000


#define SPI2CON_VALUE 0x0000

#endif

/* SPIxCON REGISTER for 33f and 24H devices */

#if defined(__dsPIC33FJ64GP206__) || defined(__dsPIC33FJ64GP306__) ||


defined(__dsPIC33FJ64GP310__) || defined(__dsPIC33FJ64GP706__) || \
defined(__dsPIC33FJ64GP708__) || defined(__dsPIC33FJ64GP710__)
|| defined(__dsPIC33FJ128GP206__) || defined(__dsPIC33FJ128GP306__) || \
defined(__dsPIC33FJ128GP310__) || defined(__dsPIC33FJ128GP706__)
|| defined(__dsPIC33FJ128GP708__) || defined(__dsPIC33FJ128GP710__) || \
defined(__dsPIC33FJ256GP506__) || defined(__dsPIC33FJ256GP510__)
|| defined(__dsPIC33FJ256GP710__) || defined(__dsPIC33FJ64MC506__) || \
defined(__dsPIC33FJ64MC508__) || defined(__dsPIC33FJ64MC510__)
|| defined(__dsPIC33FJ64MC706__) || defined(__dsPIC33FJ64MC710__) || \
defined(__dsPIC33FJ128MC506__) || defined(__dsPIC33FJ128MC510__)
|| defined(__dsPIC33FJ128MC706__) || defined(__dsPIC33FJ128MC708__) || \
defined(__dsPIC33FJ128MC710__) || defined(__dsPIC33FJ256MC510__)
|| defined(__dsPIC33FJ256MC710__) ||defined(__PIC24HJ64GP206__) || \
defined(__PIC24HJ64GP210__) || defined(__PIC24HJ64GP506__) ||
defined(__PIC24HJ64GP510__) || defined(__PIC24HJ128GP206__) || \
defined(__PIC24HJ128GP210__) || defined(__PIC24HJ128GP506__) ||
defined(__PIC24HJ128GP510__) || defined(__PIC24HJ128GP306__) || \
defined(__PIC24HJ128GP310__) || defined(__PIC24HJ256GP206__) ||
defined(__PIC24HJ256GP210__) || \
defined(__PIC24HJ256GP610__)

/*SPIXCON1 REGISTER bits differing from 30F devices*/

#define DISABLE_SCK_PIN 0xffff /* Internal SPI


clock is diabled, pin functions as I/O */
#define ENABLE_SCK_PIN 0xefff /*Internal SPI clock is
enabled */

/*SPIXCON2 REGISTER */
#define FRAME_ENABLE_ON 0xffff /* Frame SPI support
enable */
#define FRAME_ENABLE_OFF 0x7fff /* Frame SPI support
Disable */

#define FRAME_SYNC_INPUT 0xffff /* Frame sync pulse


Input (slave) */
#define FRAME_SYNC_OUTPUT 0xbfff /* Frame sync pulse
Output (master)*/

#define FRAME_POL_ACTIVE_HIGH 0xffff /* Frame sync pulse is


active-high*/
#define FRAME_POL_ACTIVE_LOW 0xdfff /* Frame sync pulse is
active-low */

#define FRAME_SYNC_EDGE_COINCIDE 0xffff /* Frame sync


pulse coincides with first bit clock */
#define FRAME_SYNC_EDGE_PRECEDE 0xfffd /* Frame sync
pulse precedes first bit clock */

#define FIFO_BUFFER_ENABLE 0xffff /* FIFO buffer enabled */


#define FIFO_BUFFER_DISABLE 0xfffe /* FIFO buffer enabled */

#else

/* SPIxCON REGISTER bits in 30F devices differing from 33F and 24H
devices */

#define FRAME_ENABLE_ON 0xffff /* Frame SPI support


enable */
#define FRAME_ENABLE_OFF 0xbfff /* Frame SPI support
Disable */

#define FRAME_SYNC_INPUT 0xffff /* Frame sync pulse


Input (slave) */
#define FRAME_SYNC_OUTPUT 0xdfff /* Frame sync pulse
Output (master)*/

#endif

#define DISABLE_SDO_PIN 0xffff /* SDO pin is not used by module


*/
#define ENABLE_SDO_PIN 0xf7ff /* SDO pin is used by module
*/

#define SPI_MODE16_ON 0xffff /* Communication is word wide


*/
#define SPI_MODE16_OFF 0xfbff /* Communication is byte wide
*/

#define SPI_SMP_ON 0xffff /* Input data sampled at end of


data output time */
#define SPI_SMP_OFF 0xfdff /* Input data sampled at middle
of data output time */

#define SPI_CKE_ON 0xffff /* Transmit happens from active


clock
state to idle clock state*/
#define SPI_CKE_OFF 0xfeff /* Transmit happens on
transition from
idle clock state to active
clock state */

#define SLAVE_ENABLE_ON 0xffff /* Slave Select enbale


*/
#define SLAVE_ENABLE_OFF 0xff7f /* Slave Select not used by
module */

#define CLK_POL_ACTIVE_LOW 0xffff /* Idle state for clock is high,


active is low */
#define CLK_POL_ACTIVE_HIGH 0xffbf /* Idle state for clock is low,
active is high */

#define MASTER_ENABLE_ON 0xffff /* Master Mode */


#define MASTER_ENABLE_OFF 0xffdf /* Slave Mode */

#define SEC_PRESCAL_1_1 0xffff /* Secondary Prescale 1:1 */


#define SEC_PRESCAL_2_1 0xfffb /* Secondary Prescale 2:1 */
#define SEC_PRESCAL_3_1 0xfff7 /* Secondary Prescale 3:1 */
#define SEC_PRESCAL_4_1 0xfff3 /* Secondary Prescale 4:1 */
#define SEC_PRESCAL_5_1 0xffef /* Secondary Prescale 5:1 */
#define SEC_PRESCAL_6_1 0xffeb /* Secondary Prescale 6:1 */
#define SEC_PRESCAL_7_1 0xffe7 /* Secondary Prescale 7:1 */
#define SEC_PRESCAL_8_1 0xffe3 /* Secondary Prescale 8:1 */

#define PRI_PRESCAL_1_1 0xffff /* Primary Prescale 1:1 */


#define PRI_PRESCAL_4_1 0xfffe /* Primary Prescale 4:1 */
#define PRI_PRESCAL_16_1 0xfffd /* Primary Prescale 16:1 */
#define PRI_PRESCAL_64_1 0xfffc /* Primary Prescale 64:1 */

/* SPIxSTAT REGISTER */

#define SPI_ENABLE 0xffff /* Enable module */


#define SPI_DISABLE 0x7fff /* Disable module */

#define SPI_IDLE_CON 0xdfff /* Continue module operation in


idle mode */
#define SPI_IDLE_STOP 0xffff /* Discontinue module operation
in idle mode */

#define SPI_RX_OVFLOW_CLR 0xffbf /* Clear receive overflow bit.*/


#if defined(__dsPIC33FJ64GP206__) || defined(__dsPIC33FJ64GP306__) ||
defined(__dsPIC33FJ64GP310__) || defined(__dsPIC33FJ64GP706__) || \
defined(__dsPIC33FJ64GP708__) || defined(__dsPIC33FJ64GP710__)
|| defined(__dsPIC33FJ128GP206__) || defined(__dsPIC33FJ128GP306__) || \
defined(__dsPIC33FJ128GP310__) || defined(__dsPIC33FJ128GP706__)
|| defined(__dsPIC33FJ128GP708__) || defined(__dsPIC33FJ128GP710__) || \
defined(__dsPIC33FJ256GP506__) || defined(__dsPIC33FJ256GP510__)
|| defined(__dsPIC33FJ256GP710__) || defined(__dsPIC33FJ64MC506__) || \
defined(__dsPIC33FJ64MC508__) || defined(__dsPIC33FJ64MC510__)
|| defined(__dsPIC33FJ64MC706__) || defined(__dsPIC33FJ64MC710__) || \
defined(__dsPIC33FJ128MC506__) || defined(__dsPIC33FJ128MC510__)
|| defined(__dsPIC33FJ128MC706__) || defined(__dsPIC33FJ128MC708__) || \
defined(__dsPIC33FJ128MC710__) || defined(__dsPIC33FJ256MC510__)
|| defined(__dsPIC33FJ256MC710__) ||defined(__PIC24HJ64GP206__) || \
defined(__PIC24HJ64GP210__) || defined(__PIC24HJ64GP506__) ||
defined(__PIC24HJ64GP510__) || defined(__PIC24HJ128GP206__) || \
defined(__PIC24HJ128GP210__) || defined(__PIC24HJ128GP506__) ||
defined(__PIC24HJ128GP510__) || defined(__PIC24HJ128GP306__) || \
defined(__PIC24HJ128GP310__) || defined(__PIC24HJ256GP206__) ||
defined(__PIC24HJ256GP210__) || \
defined(__PIC24HJ256GP610__)

#define FIFO_BUF_LEN_1 0xfff8 /* FIFO buffer length 1


words */
#define FIFO_BUF_LEN_2 0xfff9 /* FIFO buffer length 2
words */
#define FIFO_BUF_LEN_3 0xfffa /* FIFO buffer length 3
words */
#define FIFO_BUF_LEN_4 0xfffb /* FIFO buffer length 4
words */
#define FIFO_BUF_LEN_5 0xfffc /* FIFO buffer length 5
words */
#define FIFO_BUF_LEN_6 0xfffd /* FIFO buffer length 6
words */
#define FIFO_BUF_LEN_7 0xfffe /* FIFO buffer length 7
words */
#define FIFO_BUF_LEN_8 0xffff /* FIFO buffer length 8
words */

#endif

/* SPI Interrupt defines */

#define SPI_INT_EN 0xffff /* SPI Interrupt Enable */


#define SPI_INT_DIS 0xfff7 /* SPI Interrupt Disable */

#define SPI_INT_PRI_0 0xfff8 /* SPI Interrupt Prior Level_0


*/
#define SPI_INT_PRI_1 0xfff9 /* SPI Interrupt Prior Level_1
*/
#define SPI_INT_PRI_2 0xfffa /* SPI Interrupt Prior Level_2
*/
#define SPI_INT_PRI_3 0xfffb /* SPI Interrupt Prior Level_3
*/
#define SPI_INT_PRI_4 0xfffc /* SPI Interrupt Prior Level_4
*/
#define SPI_INT_PRI_5 0xfffd /* SPI Interrupt Prior Level_5
*/
#define SPI_INT_PRI_6 0xfffe /* SPI Interrupt Prior Level_6
*/
#define SPI_INT_PRI_7 0xffff /* SPI Interrupt Prior Level_7
*/

#if defined(__dsPIC33FJ64GP206__) || defined(__dsPIC33FJ64GP306__) ||


defined(__dsPIC33FJ64GP310__) || defined(__dsPIC33FJ64GP706__) || \
defined(__dsPIC33FJ64GP708__) || defined(__dsPIC33FJ64GP710__)
|| defined(__dsPIC33FJ128GP206__) || defined(__dsPIC33FJ128GP306__) || \
defined(__dsPIC33FJ128GP310__) || defined(__dsPIC33FJ128GP706__)
|| defined(__dsPIC33FJ128GP708__) || defined(__dsPIC33FJ128GP710__) || \
defined(__dsPIC33FJ256GP506__) || defined(__dsPIC33FJ256GP510__)
|| defined(__dsPIC33FJ256GP710__) || defined(__dsPIC33FJ64MC506__) || \
defined(__dsPIC33FJ64MC508__) || defined(__dsPIC33FJ64MC510__)
|| defined(__dsPIC33FJ64MC706__) || defined(__dsPIC33FJ64MC710__) || \
defined(__dsPIC33FJ128MC506__) || defined(__dsPIC33FJ128MC510__)
|| defined(__dsPIC33FJ128MC706__) || defined(__dsPIC33FJ128MC708__) || \
defined(__dsPIC33FJ128MC710__) || defined(__dsPIC33FJ256MC510__)
|| defined(__dsPIC33FJ256MC710__) ||defined(__PIC24HJ64GP206__) || \
defined(__PIC24HJ64GP210__) || defined(__PIC24HJ64GP506__) ||
defined(__PIC24HJ64GP510__) || defined(__PIC24HJ128GP206__) || \
defined(__PIC24HJ128GP210__) || defined(__PIC24HJ128GP506__) ||
defined(__PIC24HJ128GP510__) || defined(__PIC24HJ128GP306__) || \
defined(__PIC24HJ128GP310__) || defined(__PIC24HJ256GP206__) ||
defined(__PIC24HJ256GP210__) || \
defined(__PIC24HJ256GP610__)

/* Macros to Enable/Disable interrupts and set Interrupt priority of


SPI1 in 33F*/
#define EnableIntSPI1 asm("BSET IEC0,#10")
#define DisableIntSPI1 asm("BCLR IEC0,#10")
#define SetPriorityIntSPI1(priority) (IPC2bits.SPI1IP =
priority)

#define EnableIntSPI2 asm("BSET IEC2,#10")


#define DisableIntSPI2 asm("BCLR IEC2,#10")
#define SetPriorityIntSPI2(priority) (IPC8bits.SPI2IP =
priority)

/* CloseSPI. Disables SPI module */


void CloseSPI1() __attribute__ ((section (".libperi")));

/* ConfigINtSPI1. Configure Interrupt enable and priorities */


void ConfigIntSPI1(unsigned int config) __attribute__
((section(".libperi")));

/* DataRdySPI */

char DataRdySPI1() __attribute__ ((section (".libperi")));


/* getcSPI. Read byte from SPIBUF register */
#define getcSPI1 ReadSPI1

/* getsSPI.Write string to SPIBUF */


unsigned int getsSPI1(unsigned int length, unsigned int *rdptr,
unsigned int spi_data_wait)
__attribute__ ((section (".libperi")));

/* OpenSPI */
void OpenSPI1(unsigned int config1,unsigned int config2,unsigned
int config3 ) __attribute__ ((section (".libperi")));

/* putcSPI.Write byte/word to SPIBUF register */


#define putcSPI1 WriteSPI1

/* putsSPI Read string from SPIBUF */


void putsSPI1(unsigned int length, unsigned int
*wrptr)__attribute__ ((section (".libperi")));

/* ReadSPI.Read byte/word from SPIBUF register */


unsigned int ReadSPI1() __attribute__ ((section (".libperi")));

/* WriteSPI. Write byte/word to SPIBUF register */


void WriteSPI1(unsigned int data_out) __attribute__ ((section
(".libperi")));

void OpenSPI1(unsigned int config1,unsigned int config2,unsigned


int config3) __attribute__ ((section (".libperi")));;

/* CloseSPI2.Disables SPI module */


void CloseSPI2() __attribute__ ((section (".libperi")));

/* ConfigINtSPI2. Configures Interrupt enable and priorities */


void ConfigIntSPI2(unsigned int config) __attribute__
((section(".libperi")));

/* OpenSPI */
void OpenSPI2(unsigned int config1,unsigned int config2,
unsigned int config3 )__attribute__ ((section(".libperi")));

/* DataRdySPI. Test if SPIBUF register is full */


char DataRdySPI2() __attribute__ ((section (".libperi")));

/* getcSPI.Read byte from SPIBUF register */


#define getcSPI2 ReadSPI2

/* getsSPI.Write string to SPIBUF */


unsigned int getsSPI2(unsigned int length, unsigned int *rdptr,
unsigned int spi_data_wait)
__attribute__ ((section(".libperi")));

/* putcSPI.Write byte/word to SPIBUF register */

#define putcSPI2 WriteSPI2

/* putsSPI. Read string from SPIBUF */


void putsSPI2(unsigned int length, unsigned int
*wrptr)__attribute__ ((section(".libperi")));

/* ReadSPI.Read byte/word from SPIBUF register */


unsigned int ReadSPI2() __attribute__ ((section (".libperi")));

/* WriteSPI. Write byte/word to SPIBUF register */


void WriteSPI2( unsigned int data_out) __attribute__
((section(".libperi")));

#else

/* Macros to Enable/Disable interrupts and set Interrupt priority of


SPI1 in 30F*/
#define EnableIntSPI1 asm("BSET IEC0,#8")
#define DisableIntSPI1 asm("BCLR IEC0,#8")
#define SetPriorityIntSPI1(priority) (IPC2bits.SPI1IP =
priority)

/* FUNCTION PROTOTYPES */

/* CloseSPI. Disables SPI module */


void CloseSPI1() __attribute__ ((section (".libperi")));

/* ConfigINtSPI1. Configure Interrupt enable and priorities */


void ConfigIntSPI1(unsigned int config) __attribute__
((section(".libperi")));

/* DataRdySPI */

char DataRdySPI1() __attribute__ ((section (".libperi")));

/* getcSPI. Read byte from SPIBUF register */


#define getcSPI1 ReadSPI1

/* getsSPI.Write string to SPIBUF */


unsigned int getsSPI1(unsigned int length, unsigned int *rdptr,
unsigned int spi_data_wait)
__attribute__ ((section (".libperi")));
/* OpenSPI */
void OpenSPI1(unsigned int config1,unsigned int config2 )
__attribute__ ((section (".libperi")));

/* putcSPI.Write byte/word to SPIBUF register */


#define putcSPI1 WriteSPI1

/* putsSPI Read string from SPIBUF */


void putsSPI1(unsigned int length, unsigned int
*wrptr)__attribute__ ((section (".libperi")));

/* ReadSPI.Read byte/word from SPIBUF register */


unsigned int ReadSPI1() __attribute__ ((section (".libperi")));

/* WriteSPI. Write byte/word to SPIBUF register */


void WriteSPI1(unsigned int data_out) __attribute__ ((section
(".libperi")));

/* The following devices support SPI2 */

#if defined(__dsPIC30F6010__) || defined(__dsPIC30F5011__) ||


defined(__dsPIC30F6011__) || \
defined(__dsPIC30F6012__) || defined(__dsPIC30F5013__) ||
defined(__dsPIC30F6013__) || \
defined(__dsPIC30F6014__) || defined(__dsPIC30F5015__) ||
defined(__dsPIC30F6010A__) || \
defined(__dsPIC30F6011A__) || defined(__dsPIC30F6012A__) ||
defined(__dsPIC30F6013A__) || \
defined(__dsPIC30F6014A__) || defined(__dsPIC30F5016__) ||
defined(__dsPIC30F6015__)

/* Macros to Enable/Disable interrupts and set Interrupt priority of


SPI2 */
#define EnableIntSPI2 asm("BSET
IEC1,#10")
#define DisableIntSPI2 asm("BCLR
IEC1,#10")
#define SetPriorityIntSPI2(priority)
(IPC6bits.SPI2IP = priority)

/* CloseSPI2.Disables SPI module */


void CloseSPI2() __attribute__ ((section
(".libperi")));

/* ConfigINtSPI2. Configures Interrupt enable and priorities */


void ConfigIntSPI2(unsigned int config) __attribute__
((section(".libperi")));

/* OpenSPI */
void OpenSPI2(unsigned int config1,unsigned int
config2 ) __attribute__ ((section
(".libperi")));

/* DataRdySPI. Test if SPIBUF register is full */


char DataRdySPI2() __attribute__ ((section
(".libperi")));

/* getcSPI.Read byte from SPIBUF register */


#define getcSPI2 ReadSPI2

/* getsSPI.Write string to SPIBUF */


unsigned int getsSPI2(unsigned int length, unsigned int
*rdptr, unsigned int spi_data_wait)
__attribute__ ((section(".libperi")));

/* putcSPI.Write byte/word to SPIBUF register */


#define putcSPI2 WriteSPI2

/* putsSPI. Read string from SPIBUF */


void putsSPI2(unsigned int length, unsigned int
*wrptr)__attribute__ ((section(".libperi")));

/* ReadSPI.Read byte/word from SPIBUF register */


unsigned int ReadSPI2() __attribute__ ((section
(".libperi")));

/* WriteSPI. Write byte/word to SPIBUF register */


void WriteSPI2( unsigned int data_out) __attribute__
((section(".libperi")));

#endif
#endif
#endif /* __SPI_H */
#ifndef __QEI_H
#define __QEI_H

/* List of SFRs for QEI */


/* This list contains the SFRs with default (POR) values to be used for
configuring QEI */
/* The user can modify this based on the requirement */
#define QEICON_VALUE 0x0000
#define DFLTCON_VALUE 0x0000
#define POSCNT_VALUE 0x0000
#define MAXCNT_VALUE 0xFFFF

/* QEICON Configuration Bit Definitions */

#define QEI_DIR_SEL_QEB 0xFFFF /* QEB Pin State Defines


Position Counter Direction */
#define QEI_DIR_SEL_CNTRL 0xFFFE /* Control/Status Bit,
QEICON<11>, Defines Timer Counter (POSCNT) Direction */
#define QEI_EXT_CLK 0xFFFF /* External clock from pin
TQCKI (on the rising edge) */
#define QEI_INT_CLK 0xFFFD /* Internal clock (FOSC/4) */

#define QEI_INDEX_RESET_ENABLE 0xFFFF /* QEI Index Pulse resets


Position Counter */
#define QEI_INDEX_RESET_DISABLE 0xFFFB /* Index Pulse does not reset
Position Counter */

#define QEI_CLK_PRESCALE_1 0xFFE7 /* QEI Timer Input Clock


Prescale Select Bits */
#define QEI_CLK_PRESCALE_8 0xFFEF
#define QEI_CLK_PRESCALE_64 0xFFF7
#define QEI_CLK_PRESCALE_256 0xFFFF /* QEI 1:256 prescale value
*/

#define QEI_GATED_ACC_ENABLE 0xFFFF /* QEI Timer gated time


accumulation enabled */
#define QEI_GATED_ACC_DISABLE 0xFFDF /* Timer gated time
accumulation disabled */

#define QEI_LOGIC_CONTROL_IO 0xFFFF /* QEI Position Counter


Direction Status Output Enable(QEI logic controls state of I/O pin) */
#define QEI_NORMAL_IO 0xFFBF /* QEI Position Counter
Direction Status Output Disabled(Normal I/O pin operation) */

#define QEI_INPUTS_SWAP 0xFFFF /* QEI Phase A and Phase B


inputs swapped */
#define QEI_INPUTS_NOSWAP 0xFF7F /* QEI Phase A and Phase B
inputs not swapped */

#define QEI_MODE_x4_MATCH 0xFFFF /* QEI Quadrature Encoder


Interface enabled (x4 mode) with position counter reset by match
(MAXCNT) */
#define QEI_MODE_x4_PULSE 0xFEFF /* QEI Quadrature Encoder
Interface enabled (x4 mode) with Index Pulse reset of position counter
*/
#define QEI_MODE_x2_MATCH 0xFDFF /* QEI Quadrature Encoder
Interface enabled (x2 mode) with position counter reset by match
(MAXCNT) */
#define QEI_MODE_x2_PULSE 0xFCFF /* QEI Quadrature Encoder
Interface enabled (x2 mode) with Index Pulse reset of position counter
*/
#define QEI_MODE_TIMER 0xF9FF /* QEI Starts 16-bit Timer */
#define QEI_MODE_OFF 0xF8FF /* QEI Quadrature Encoder
Interface/Timer off */

#define QEI_UP_COUNT 0xFFFF /* QEI Position Counter


Direction +VE */
#define QEI_DOWN_COUNT 0xF7FF /* QEI Position Counter
Direction -VE */

#define QEI_IDLE_STOP 0xFFFF /* QEI Discontinue module


operation when device enters a idle mode. */
#define QEI_IDLE_CON 0xDFFF /* QEI Continue module
operation in idle mode */
/* defines for the DFLTCON register */

#define QEI_QE_CLK_DIVIDE_1_1 0xFF8F /* QEI QEA/QEB Digital Filter


Clock Divide Select Bits */
#define QEI_QE_CLK_DIVIDE_1_2 0xFF9F
#define QEI_QE_CLK_DIVIDE_1_4 0xFFAF
#define QEI_QE_CLK_DIVIDE_1_16 0xFFBF
#define QEI_QE_CLK_DIVIDE_1_32 0xFFCF
#define QEI_QE_CLK_DIVIDE_1_64 0xFFDF
#define QEI_QE_CLK_DIVIDE_1_128 0xFFEF
#define QEI_QE_CLK_DIVIDE_1_256 0xFFFF /* QEI QEA/QEB Digital Filter
Clock Divide Select Bits */

#define QEI_QE_OUT_ENABLE 0xFFFF /* QEI QEA/QEB Digital


Filter Clock Divide Select Bits */
#define QEI_QE_OUT_DISABLE 0xFF7F /* QEI QEA/QEB Digital
Filter Clock Divide Select Bits */

#define POS_CNT_ERR_INT_ENABLE 0xFFFF /* Enable interrupt due to


position count errors */
#define POS_CNT_ERR_INT_DISABLE 0xFEFF /* Disable interrupt due to
position count errors */

#define MATCH_INDEX_PHASEB_HIGH 0xFFFF


#define MATCH_INDEX_PHASEB_LOW 0xFBFF

#define MATCH_INDEX_PHASEA_HIGH 0xFFFF


#define MATCH_INDEX_PHASEA_LOW 0xFDFF

#define MATCH_INDEX_INPUT_PHASEB 0xFFFF


#define MATCH_INDEX_INPUT_PHASEA 0xFBFF

#define MATCH_INDEX_INPUT_HIGH 0xFFFF


#define MATCH_INDEX_INPUT_LOW 0xFDFF

/* Setting the priority of QEI interrupt */


#define QEI_INT_PRI_0 0xFFF8
#define QEI_INT_PRI_1 0xFFF9
#define QEI_INT_PRI_2 0xFFFA
#define QEI_INT_PRI_3 0xFFFB
#define QEI_INT_PRI_4 0xFFFC
#define QEI_INT_PRI_5 0xFFFD
#define QEI_INT_PRI_6 0xFFFE
#define QEI_INT_PRI_7 0xFFFF

// Enable / Disable QEI interrupt


#define QEI_INT_ENABLE 0xFFFF /* Set the Interrupt enable
bit */
#define QEI_INT_DISABLE 0xFF7F /* Clear the Interrupt
enable bit */

#define QEI_EnableInt asm("BSET IEC2,#8")


#define QEI_DisableInt asm("BCLR IEC2,#8")
#define SetPriorityIntQEI(priority) (IPC10bits.QEIIP = priority)
extern volatile unsigned char QEI_Event;
extern volatile unsigned char QEI_Dir;
extern volatile int NavSector;

// QEI Interrupt ISR Declaration


void __attribute__((__interrupt__)) _QEIInterrupt(void);

// QEI Function Prototypes

void OpenQEI(unsigned int config1, unsigned int config2) __attribute__


((section (".libperi"))); /* Configure QEI */

void CloseQEI(void) __attribute__ ((section (".libperi")));


/* Disables the QEI module */

void ConfigIntQEI(unsigned int) __attribute__ ((section (".libperi")));


/* QEI interrupt configuration */

#endif /*__QEI_H */

You might also like