motor controller application

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

Upload: luan-nguyen-viet

Post on 14-Oct-2014

221 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Motor Controller Application

; 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

Page 2: Motor Controller Application

;; ORG 0x000018;; goto LO_ISR

HI_ISRmovwf W_Temp ; W_TEMP is in virtual

bankmovff STATUS,STAT_Temp ; STATUS_TEMP located anywheremovff 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 BSRmovff STAT_Temp, STATUS ; Restore STATUSmovwf W_Temp, W ; Restore WREGretfie 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

Page 3: Motor Controller Application

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 Modebcf T0CON,T0CS ; Use Internal Clockbsf 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

Page 4: Motor Controller Application

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,IC2QEIFQEI_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

Page 5: Motor Controller Application

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

Page 6: Motor Controller Application

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/INT2bcf 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

Page 7: Motor Controller Application

; 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

Page 8: Motor Controller Application

; 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

Page 9: Motor Controller Application

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

Page 10: Motor Controller Application

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

Page 11: Motor Controller Application

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

Page 12: Motor Controller Application

; 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_ISRmovwf W_Temp ; W_TEMP is in virtual

bank

Page 13: Motor Controller Application

movff STATUS,STAT_Temp ; STATUS_TEMP located anywheremovff 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 BSRmovff STAT_Temp, STATUS ; Restore STATUSmovwf W_Temp, W ; Restore WREGretfie FAST

Page 14: Motor Controller Application

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 Modebcf T0CON,T0CS ; Use Internal Clockbsf 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

Page 15: Motor Controller Application

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

PWM_INIT clrf Stop_Divs

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

Page 16: Motor Controller Application

;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

Page 17: Motor Controller Application

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/INT2bcf 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

Page 18: Motor Controller Application

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 NUDGEHOME_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_RUNNUDGE_RUN movlw 0x00 btfsc T0CON,TMR0ON goto NUDGE_RUN

Page 19: Motor Controller Application

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

Page 20: Motor Controller Application

bsf PORTD,RD0 bsf QEI_Flags,QF_Run ; Set the QEI Run FlagMOTOR_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

Page 21: Motor Controller Application

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

Page 22: Motor Controller Application

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

Page 23: Motor Controller Application

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

Page 24: Motor Controller Application

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

Page 25: Motor Controller Application

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

Page 26: Motor Controller Application

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

Page 27: Motor Controller Application

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

Page 28: Motor Controller Application

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

Page 29: Motor Controller Application

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

Page 30: Motor Controller Application

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;

Page 31: Motor Controller Application

; 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 anywheremovff 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 BSRmovff STAT_Temp, STATUS ; Restore STATUSmovwf W_Temp, W ; Restore WREG

Page 32: Motor Controller Application

retfie FAST

LO_ISR ; Low Priority Interruptsmovwf W_Temp ; W_TEMP is in virtual

bankmovff STATUS,STAT_Temp ; STATUS_TEMP located anywheremovff 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 BSRmovff STAT_Temp, STATUS ; Restore STATUSmovwf 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

Page 33: Motor Controller Application

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

Page 34: Motor Controller Application

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 Interuptbcf INTCON3,INT1IF ; Clear INT1

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

; Setup RC5/INT2bcf 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

Page 35: Motor Controller Application

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

Page 36: Motor Controller Application

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

Page 37: Motor Controller Application

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

Page 38: Motor Controller Application

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

Page 39: Motor Controller Application

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

Page 40: Motor Controller Application

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

Page 41: Motor Controller Application

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>

Page 42: Motor Controller Application

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 anywheremovff 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 BSRmovff STAT_Temp, STATUS ; Restore STATUSmovwf W_Temp, W ; Restore WREGretfie 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

Page 43: Motor Controller Application

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 TXREGTXi1 bsf PORTE,RE1 btfss PIR1,TXIF goto TXi1 movlw 0x0D movwf TXREGTXi2 bsf PORTE,RE1 btfss PIR1,TXIF goto TXi2

Page 44: Motor Controller Application

movlw 0x0D movwf TXREGTXi3 bsf PORTE,RE1 btfss PIR1,TXIF goto TXi3 movlw 0x2A movwf TXREGTXi4 bsf PORTE,RE1 btfss PIR1,TXIF goto TXi4 movlw 0x0D movwf TXREGTXi5 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_1btfss 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

Page 45: Motor Controller Application

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_2btfss 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_3btfss 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_4goto CHECK_1

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

Page 46: Motor Controller Application

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

TXB5btfss Buttons,5 ; Check for RC5/INT2 Button Flag

goto TXB3 movlw 0x32 movwf TXREG goto TX_J3

TXB3btfss 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 TXREGTX_J4 bsf PORTE,RE1 btfss PIR1,TXIF goto TX_J4

Page 47: Motor Controller Application

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

Page 48: Motor Controller Application

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 anywheremovff 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 BSRmovff STAT_Temp, STATUS ; Restore STATUSmovwf W_Temp, W ; Restore WREGretfie 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

Page 49: Motor Controller Application

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 TXREGTXi1 bsf PORTE,RE1 btfss PIR1,TXIF goto TXi1 movlw 0x0D movwf TXREGTXi2 bsf PORTE,RE1 btfss PIR1,TXIF goto TXi2 movlw 0x0D

Page 50: Motor Controller Application

movwf TXREGTXi3 bsf PORTE,RE1 btfss PIR1,TXIF goto TXi3 movlw 0x2A movwf TXREGTXi4 bsf PORTE,RE1 btfss PIR1,TXIF goto TXi4 movlw 0x0D movwf TXREGTXi5 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

Page 51: Motor Controller Application

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

Page 52: Motor Controller Application

bsf INTCON,GIE ; Enable Global Interrupt

CHECK_1btfss 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_2btfss 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_3btfss 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

Page 53: Motor Controller Application

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

Page 54: Motor Controller Application

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

TXB5btfss Buttons,5 ; Check for RC5/INT2 Button Flag

goto TXB3 movlw 0x32 movwf TXREG goto TX_J3

TXB3btfss 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

Page 55: Motor Controller Application

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;

Page 56: Motor Controller Application

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

Page 57: Motor Controller Application

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

movff BSR_Temp,BSR ; Restore BSRmovff STAT_Temp, STATUS ; Restore STATUSmovwf W_Temp, W ; Restore WREGretfie FAST

LO_ISR ; Low Priority Interruptsmovwf W_Temp ; W_TEMP is in virtual

bankmovff STATUS,STAT_Temp ; STATUS_TEMP located anywheremovff 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 BSRmovff STAT_Temp, STATUS ; Restore STATUSmovwf 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

Page 58: Motor Controller Application

; 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

Page 59: Motor Controller Application

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 Interuptbcf INTCON3,INT1IF ; Clear INT1

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

; Setup RC5/INT2bcf INTCON3,INT2IF ; Clear INT2

bsf INTCON3,INT2IP ; Set INT2 to High Priority bsf INTCON3,INT2IE ; Enable INT2 Interrupt

Page 60: Motor Controller Application

; 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

Page 61: Motor Controller Application

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

Page 62: Motor Controller Application

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

Page 63: Motor Controller Application

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

Page 64: Motor Controller Application

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

Page 65: Motor Controller Application

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

Page 66: Motor Controller Application

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

Page 67: Motor Controller Application

/* 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__) || \

Page 68: Motor Controller Application

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

Page 69: Motor Controller Application

#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__) || \

Page 70: Motor Controller Application

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__) || \

Page 71: Motor Controller Application

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")

Page 72: Motor Controller Application

#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")

Page 73: Motor Controller Application

#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__) || \

Page 74: Motor Controller Application

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__)

Page 75: Motor Controller Application

/* 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)

Page 76: Motor Controller Application

#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")));

Page 77: Motor Controller Application

/* 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__)

Page 78: Motor Controller Application

/* 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 prototypesvoid CAN_Init(void);void PIC_Init(void);int SendCANMsg (void);

// global vars// CAN variables

Page 79: Motor Controller Application

/* 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 buttonpressif(PORTDbits.RD8 == 0){

// small debouncefor(i=0; i<0xFFFF; i++);

if(PORTDbits.RD8 == 0){

j = 0;j = SendCANMsg();

}}

}

return 0;}//

Page 80: Motor Controller Application

// function definitions

void PIC_Init(void){

// all digital I/OADPCFG = 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 enteredwhile(C1CTRLbits.OPMODE <=3);

/* Load configuration register */CAN1Initialize( CAN_SYNC_JUMP_WIDTH2 &

CAN_BAUD_PRE_SCALE(5),

Page 81: Motor Controller Application

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 enteredwhile(C1CTRLbits.OPMODE != 0);

/* Set request for Loopback mode */

Page 82: Motor Controller Application

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

Page 83: Motor Controller Application

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

Page 84: Motor Controller Application

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;

Page 85: Motor Controller Application

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

Page 86: Motor Controller Application

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

Page 87: Motor Controller Application

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

Page 88: Motor Controller Application

} 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)

Page 89: Motor Controller Application

// { // 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

Page 90: Motor Controller Application

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;

Page 91: Motor Controller Application

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

Page 92: Motor Controller Application

#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 */

Page 93: Motor Controller Application

/* 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

Page 94: Motor Controller Application

#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 Declarationvoid __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"

Page 95: Motor Controller Application

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

Page 96: Motor Controller Application

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

Page 97: Motor Controller Application

{ // 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) {

Page 98: Motor Controller Application

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

Page 99: Motor Controller Application

// 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 {

Page 100: Motor Controller Application

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 Timer1void T1_Init(void)

Page 101: Motor Controller Application

{ 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 Routinevoid __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*/

Page 102: Motor Controller Application

#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*/

Page 103: Motor Controller Application

#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**************************/

Page 104: Motor Controller Application

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

Page 105: Motor Controller Application

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__) || \

Page 106: Motor Controller Application

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 */

Page 107: Motor Controller Application

#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 */

Page 108: Motor Controller Application

#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.*/

Page 109: Motor Controller Application

#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 */

Page 110: Motor Controller Application

#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")));

Page 111: Motor Controller Application

/* 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 */

Page 112: Motor Controller Application

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

Page 113: Motor Controller Application

/* 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

Page 114: Motor Controller Application

(".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 */

Page 115: Motor Controller Application

#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 */

Page 116: Motor Controller Application

/* 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)

Page 117: Motor Controller Application

extern volatile unsigned char QEI_Event;extern volatile unsigned char QEI_Dir;extern volatile int NavSector;

// QEI Interrupt ISR Declarationvoid __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 */