Motor Controller Application
Motor Controller Application
include <P18f4431.INC>
ORG 0x000000
goto RESET_1
HI_ISR
movwf W_Temp ; W_TEMP is in virtual
bank
movff STATUS,STAT_Temp ; STATUS_TEMP located anywhere
movff BSR,BSR_Temp ; BSR_TMEP located anywhere
HI_ISR_1
btfsc INTCON,INT0IF
bsf ButtonPress,3 ; Set RC3 Button Flag
bcf INTCON,INT0IF
RESET_1
bcf INTCON,GIE ; Disable Global Interrupt
bsf OSCCON,6 ; Kick the INT OSC up to maximum
8MHz with x111xxxx
bsf OSCCON,5
bsf OSCCON,4
clrf ButtonPress ; Clear the Buttons flags
bsf PORTC,RC3 ; Setup PORTC I/O
bsf PORTC,RC4 ; I/O is Active LO
bsf PORTC,RC5
bsf TRISC,RC3 ; RC3/INT0
bsf TRISC,RC4 ; RC4/INT1
bsf TRISC,RC5 ; RC5/INT2
TIMER_INIT
; Utility Timer Initialization
bcf INTCON,TMR0IE ; Disable Timer 0 Interrupt
bcf INTCON,TMR0IF
bcf T0CON,TMR0ON ; Turn off Timer 0
clrf TMR0H
clrf TMR0L
clrf T0CON
bcf T0CON,T016BIT ; Set 16 bit Counter Mode
bcf T0CON,T0CS ; Use Internal Clock
bsf T0CON,PSA ; Prescaler Off
;bcf T0CON,T0PS2
;bcf T0CON,T0PS1
;bcf T0CON,T0PS0
; T0PS2:T0PS0
; 111 =1:256 prescale value
; 110 =1:128 prescale value
; 101 =1:64 prescale value
; 100 =1:32 prescale value
; 011 =1:16 prescale value
; 010 =1:8 prescale value
; 001 =1:4 prescale value
; 000 =1:2 prescale value
bsf INTCON,TMR0IE ; Enable Timer0 Interrupt
QEI_INIT
clrf PORTA ; Setup PORTA I/O
; QEI Inputs
bcf ANSEL0,ANS2 ; RA2/Index = Digital
bsf TRISA,RA2 ; RA2 = Input
bcf ANSEL0,ANS3 ; RA3/QEA = Digital
bsf TRISA,RA3 ; RA3 = Input
bcf ANSEL0,ANS4 ; RA4/QEB = Digital
bsf TRISA,RA4 ; RA4 = Input
PWM_INIT
clrf Stop_Div
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)
PWM_INIT_END
RESET_1_INT_ON
; Setup RC3/INT0
bsf INTCON3,INT2IE ; Enable INT2 Interrupt
bcf INTCON,INT0IF ; Clear INT0
bsf INTCON,INT0IE ; Enable INT0 Interrupt
bcf INTCON2,INTEDG0 ; Set External I/O INTs to Trailing Edge
bcf INTCON2,INTEDG1
bcf INTCON2,INTEDG2
; Setup RC4/INT1 Interupt
bcf INTCON3,INT1IF ; Clear INT1
bsf INTCON3,INT1IP ; Set INT1 to High Priority
bsf INTCON3,INT1IE ; Enable INT1 Interrupt
; Setup RC5/INT2
bcf INTCON3,INT2IF ; Clear INT2
bsf INTCON3,INT2IP ; Set INT2 to High Priority
bsf INTCON3,INT2IE ; Enable INT2 Interrupt
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
RC3_PRESSED
;; Do RC3 Stuff Here
btfss A39_,A_Sleep
goto A39_SLEEP_ON
A39_SLEEP_OFF ; -- RUN --
bcf A39_,A_Sleep
bcf PORTB,RB2 ; LO ENABLE (on)
bcf PORTB,RB3 ; LO MODE
bsf PORTB,RB4 ; HI BREAK (off)
bsf PWMCON0,PWMEN0 ; Turn On Motor
goto RC3_DONE
A39_SLEEP_ON
bsf A39_,A_Sleep
bcf PWMCON0,PWMEN0 ; Turn Off Motor
bsf PORTB,RB2 ; HI ENABLE (off)
bsf PORTB,RB3 ; HI MODE
bsf PORTB,RB4 ; HI BREAK (off)
;goto RC3_DONE
RC3_DONE
bsf INTCON,GIE ; Enable Global Interrupts
BUTTON_RC4_CHECK
btfss ButtonPress,4
goto BUTTON_RC5_CHECK
BUTTON_RC4_PRESSED
bcf INTCON,GIE ; Disable Global Interrupts
btfss KeyBounce,4 ; Check Bounce Setting
goto RC4_SET_TIMER ; Set Bounce Timer
goto RC4_CHECK_TIMER
RC4_SET_TIMER
; Set Bounce Timer
bsf KeyBounce,4
call BOUNCE_TIMER
goto RC4_DONE
RC4_CHECK_TIMER
btfsc T0CON,TMR0ON ; Check Timer
goto RC4_DONE ; Waiting, Jump to Done
; Time Expired
bcf ButtonPress,4 ; Clear Button Press Flag
bcf KeyBounce,4 ; Clear Bounce Setting
btfsc PORTC,RC4 ; Check RC Again (Active LO)
goto RC4_DONE ; Not Pressed
RC4_PRESSED
;; Do RC4 Stuff Here
; Increment Through Motor Speed Selection
; We are driving the motor with PWM on PHASE 50% Duty Cycle =
0x1FFF
movlw 0x00
cpfsgt Motor_Speed
goto MSPD_00
addlw 8
cpfsgt Motor_Speed
goto MSPD_01
addlw 1
cpfsgt Motor_Speed
goto MSPD_00
addlw 8
cpfsgt Motor_Speed
goto MSPD_02
goto MS_DONE
MSPD_00
; Pause
movlw 0x1F
movwf PDC0H
movlw 0xFF
movwf PDC0L
goto MS_DONE
MSPD_01
; Forward
movlw 0x04
addwf PDC0H,1
goto MS_DONE
MSPD_02
; Reverse
movlw 0x04
cpfslt PDC0H
goto MSPD_REV1
movlw 0x00
movwf PDC0H
movwf PDC0L
goto MS_DONE
MSPD_REV1
subwf PDC0H,1
goto MS_DONE
MS_DONE
incf Motor_Speed,1
movf Motor_Speed,0
movlw 0x12
cpfseq Motor_Speed ; Skip if Equal 4
goto RC4_DONE
MS_RESET
clrf Motor_Speed
RC4_DONE
bsf INTCON,GIE ; Enable Global Interrupts
BUTTON_RC5_CHECK
btfss ButtonPress,5
goto NEXT_STATE
BUTTON_RC5_PRESSED
bcf INTCON,GIE ; Disable Global Interrupts
btfss KeyBounce,5 ; Check Bounce Setting
goto RC5_SET_TIMER ; Set Bounce Timer
goto RC5_CHECK_TIMER
RC5_SET_TIMER
; Set Bounce Timer
bsf KeyBounce,5
call BOUNCE_TIMER
goto RC5_DONE
RC5_CHECK_TIMER
btfsc T0CON,TMR0ON ; Check Timer
goto RC5_DONE ; Waiting, Jump to Done
; Time Expired
bcf ButtonPress,5 ; Clear Button Press Flag
bcf KeyBounce,5 ; Clear Bounce Setting
btfsc PORTC,RC5 ; Check RC Again
goto RC5_CLEAR ; Not Pressed
RC5_PRESSED
;; Do RC Stuff Here
btg LATB,RB4
RC5_CLEAR
; bcf TRISC,RC5 ; Set RC to output
; bcf LATC,RC5 ; Clear RC
; bsf TRISC,RC5 ; Set RC back to input
RC5_DONE
bsf INTCON,GIE ; Enable Global Interrupts
NEXT_STATE
PROG_LOOP_DONE
goto PROG_LOOP
end
Motor Controller Application
; 11/04/06 QEI
; 10/27/06 PWM on ENABLE
; 10/16/06 Active LO I/O INTs, PWM on PHASE
; 10/06/06 ajs Derived from Index Table Application
;
; PIC18F4431 I/O
; --------------
; INPUT
; User Interface Digital Input Buttons. Debounce performed by button
hardware
; #1: RE3/MCLR => MCU Reset
; #2: RC3/INT0 => A3953 Sleep ON/OFF (Motor ON/OFF)
; #3: RC4/INT1 => Motor Speed Select
; #4: RC5/INT2 =>
;
; Quadrature Encoder Interface Digital Inputs
; RA2 => Index
; RA3 => Channel A
; RA4 => Channel B
;
; OUTPUT
; RB0/PWM0 => Not Used
; RB1/PWM1 => A3959 Enable
; RB2 => A3959 Phase
; RB3 => A3959 Extended Mode
;
;
; Operational Variables
; QEI_Flags: QEI Monitoring Flags
; QEI_Flags,0 = Monitoring of QEI Flags is Enabled
; QEI_Flags,1 = Interrupt on Position = Max Count
; QEI_Flags,2 = Max Count Changed
; QEI_Flags,3 = Repeat Run
; QEI_Flags,7 = Rotation Direction Changed
include <P18f4431.INC>
ORG 0x000000
goto RESET_1
;; ORG 0x000018
;; goto LO_ISR
HI_ISR
movwf W_Temp ; W_TEMP is in virtual
bank
movff STATUS,STAT_Temp ; STATUS_TEMP located anywhere
movff BSR,BSR_Temp ; BSR_TMEP located anywhere
;; Check 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
HI_ISR_1
btfsc INTCON,INT0IF
bsf ButtonPress,3 ; Set RC3 Button Flag
bcf INTCON,INT0IF
TIMER_INIT
; Utility Timer Initialization
bcf INTCON,TMR0IE ; Disable Timer 0 Interrupt
bcf INTCON,TMR0IF
bcf T0CON,TMR0ON ; Turn off Timer 0
clrf TMR0H
clrf TMR0L
clrf T0CON
bcf T0CON,T016BIT ; Set 16 bit Counter Mode
bcf T0CON,T0CS ; Use Internal Clock
bsf T0CON,PSA ; Prescaler Off
;bcf T0CON,T0PS2
;bcf T0CON,T0PS1
;bcf T0CON,T0PS0
; T0PS2:T0PS0
; 111 =1:256 prescale value
; 110 =1:128 prescale value
; 101 =1:64 prescale value
; 100 =1:32 prescale value
; 011 =1:16 prescale value
; 010 =1:8 prescale value
; 001 =1:4 prescale value
; 000 =1:2 prescale value
bsf INTCON,TMR0IE ; Enable Timer0 Interrupt
QEI_INIT
clrf PORTA ; Setup PORTA I/O
; QEI Inputs
bcf ANSEL0,ANS2 ; RA2/Index = Digital
bsf TRISA,RA2 ; RA2 = Input
bcf ANSEL0,ANS3 ; RA3/QEA = Digital
bsf TRISA,RA3 ; RA3 = Input
bcf ANSEL0,ANS4 ; RA4/QEB = Digital
bsf TRISA,RA4 ; RA4 = Input
PWM_INIT
clrf Stop_Divs
bcf TRISD,RD0
bcf PORTD,RD0
movlw 0x02
movwf Motor_Speed
movlw 0x3F
movwf PDC0H
movlw 0xFF
movwf PDC0L
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
; Setup RC5/INT2
bcf INTCON3,INT2IF ; Clear INT2
bsf INTCON3,INT2IP ; Set INT2 to High Priority
bsf INTCON3,INT2IE ; Enable INT2 Interrupt
GOTO_HOME
call NUDGE
bcf PIE3,IC2QEIE ; Disable QEI Interupts
bcf RCON,IPEN ; Disable Interrupt Priority
bcf INTCON,PEIE ; Disable Peripheral Interrupts
bcf INTCON,GIE ; Disable Global Interrupt
bcf QEI_Flags,QF_Home ; Clear Homing Flag
bsf QEI_Flags,QF_Nudge ; Set Nudging ON in case we are already Home
movlw 0x02
movwf Motor_Speed
call SPEED_1
bcf A39_,A_Sleep
call RESET_INTERRUPTS
call NUDGE
HOME_RUN
movlw 0x00
btfsc PORTC,RC2
goto HOME_RUN
RESET_QEI
call MOTOR_STOP
clrf POSCNTH
clrf POSCNTL ; Clear Position Counter
movf MAXCNTH,0
movwf CAP3BUFH
movf MAXCNTL,0
movwf CAP3BUFL
clrf POSCNTH
clrf POSCNTL ; Clear Position Counter
clrf CAP2BUFH
clrf CAP2BUFL
call RESET_INTERRUPTS
return
NUDGE
movlw 0x00
movwf TMR0H
movlw 0x00
movwf TMR0L
bsf QEI_Flags,QF_Nudge
bsf T0CON,TMR0ON ; Turn Timer ON
call MOTOR_RUN
NUDGE_RUN
movlw 0x00
btfsc T0CON,TMR0ON
goto NUDGE_RUN
return
SPEED_1
movlw 0x20
movwf PDC0H
;movlw 0x0f
;subwf PDC0H,1
return
SPEED_2
movlw 0x10
movwf PDC0H
;movlw 0x0f
;subwf PDC0H,1
return
SPEED_3
movlw 0x00
movwf PDC0H
movlw 0x00
movwf PDC0L
;movlw 0x0f
;subwf PDC0H,1
return
MOTOR_STOP
;bsf A39_,A_Sleep
bcf PWMCON0,PWMEN0 ; Turn Off Motor
bsf PORTB,RB1 ; HI ENABLE (off)
bsf PORTB,RB3 ; HI MODE
bcf PORTB,RB4 ; BREAK (off)
bcf PORTD,RD0
return
MOTOR_RUN
btfsc A39_,A_Sleep
goto MOTOR_DONE
bcf PORTB,RB1 ; LO ENABLE (on)
bcf PORTB,RB3 ; LO MODE
bsf PORTB,RB4 ; BREAK (ON)
bsf PWMCON0,PWMEN0 ; Turn On Motor
bsf PORTD,RD0
bsf QEI_Flags,QF_Run ; Set the QEI Run Flag
MOTOR_DONE
return
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
; Time Expired
bcf ButtonPress,3 ; Clear Button Press Flag
bcf KeyBounce,3 ; Clear Bounce Setting
btfsc PORTC,RC3 ; Check RC Again (Active LO)
goto RC3_DONE ; Not Pressed
RC3_PRESSED
;; Do RC3 Stuff Here
btfsc PWMCON0,PWMEN0
goto A39_SLEEP_ON
A39_SLEEP_OFF ; -- RUN --
bcf A39_,A_Sleep
bsf INTCON,GIE ; Enable Global Interrupts
call NUDGE
call MOTOR_RUN
;bcf PORTB,RB1 ; LO ENABLE (on)
;bcf PORTB,RB3 ; LO MODE
;bsf PORTB,RB4 ; BREAK (ON)
;bsf PWMCON0,PWMEN0 ; Turn On Motor
;bsf PORTD,RD0
goto RC3_DONE
A39_SLEEP_ON
bsf A39_,A_Sleep
call MOTOR_STOP
;bcf PWMCON0,PWMEN0 ; Turn Off Motor
;bsf PORTB,RB1 ; HI ENABLE (off)
;bsf PORTB,RB3 ; HI MODE
;bcf PORTB,RB4 ; BREAK (off)
;bcf PORTD,RD0
;goto RC3_DONE
RC3_DONE
bsf INTCON,GIE ; Enable Global Interrupts
BUTTON_RC4_CHECK
btfss ButtonPress,4
goto BUTTON_RC5_CHECK
BUTTON_RC4_PRESSED
bcf INTCON,GIE ; Disable Global Interrupts
btfss KeyBounce,4 ; Check Bounce Setting
goto RC4_SET_TIMER ; Set Bounce Timer
goto RC4_CHECK_TIMER
RC4_SET_TIMER
; Set Bounce Timer
bsf KeyBounce,4
call BOUNCE_TIMER
goto RC4_DONE
RC4_CHECK_TIMER
btfsc T0CON,TMR0ON ; Check Timer
goto RC4_DONE ; Waiting, Jump to Done
; Time Expired
bcf ButtonPress,4 ; Clear Button Press Flag
bcf KeyBounce,4 ; Clear Bounce Setting
btfsc PORTC,RC4 ; Check RC Again (Active LO)
goto RC4_DONE ; Not Pressed
RC4_PRESSED
;; Do RC4 Stuff Here
; Increment Through Motor Speed Selection
; We are driving the motor with PWM on ENABLE
movlw 0x00
cpfsgt Motor_Speed
goto MSPD_PAUSE
addlw 1
cpfsgt Motor_Speed
goto MSPD_FORWARD_1
addlw 1
cpfsgt Motor_Speed
goto MSPD_FORWARD_2
addlw 1
cpfsgt Motor_Speed
goto MSPD_FORWARD_3
addlw 1
cpfsgt Motor_Speed
goto MSPD_PAUSE
addlw 1
cpfsgt Motor_Speed
goto MSPD_REVERSE_1
addlw 1
cpfsgt Motor_Speed
goto MSPD_REVERSE_2
addlw 1
cpfsgt Motor_Speed
goto MSPD_REVERSE_3
goto MS_DONE
MSPD_PAUSE
movlw 0x3F
movwf PDC0H
movlw 0xFF
movwf PDC0L
goto MS_DONE
MSPD_FORWARD_1
bcf LATB,RB2
call SPEED_1
goto MS_DONE
MSPD_FORWARD_2
bcf LATB,RB2
call SPEED_2
goto MS_DONE
MSPD_FORWARD_3
bcf LATB,RB2
call SPEED_3
goto MS_DONE
MSPD_REVERSE_1
bsf LATB,RB2
call SPEED_1
goto MS_DONE
MSPD_REVERSE_2
bsf LATB,RB2
call SPEED_2
goto MS_DONE
MSPD_REVERSE_3
bsf LATB,RB2
call SPEED_3
goto MS_DONE
MS_DONE
incf Motor_Speed,1
movf Motor_Speed,0
movlw 0x08
cpfseq Motor_Speed ; Skip if Equal 4
goto RC4_DONE
MS_RESET
clrf Motor_Speed
RC4_DONE
bsf INTCON,GIE ; Enable Global Interrupts
BUTTON_RC5_CHECK
btfss ButtonPress,5
goto NEXT_STATE
BUTTON_RC5_PRESSED
bcf INTCON,GIE ; Disable Global Interrupts
btfss KeyBounce,5 ; Check Bounce Setting
goto RC5_SET_TIMER ; Set Bounce Timer
goto RC5_CHECK_TIMER
RC5_SET_TIMER
; Set Bounce Timer
bsf KeyBounce,5
call BOUNCE_TIMER
goto RC5_DONE
RC5_CHECK_TIMER
btfsc T0CON,TMR0ON ; Check Timer
goto RC5_DONE ; Waiting, Jump to Done
; Time Expired
bcf ButtonPress,5 ; Clear Button Press Flag
bcf KeyBounce,5 ; Clear Bounce Setting
btfsc PORTC,RC5 ; Check RC Again
goto RC5_DONE ; Not Pressed
RC5_PRESSED
;; Select Stop Divisions
; Reset Position Counters
clrf POSCNTL ; Clear Position Counter
clrf POSCNTH
DIV_180
movlw 0xFF ; 65433.6 = 0xFF99
movwf MAXCNTH ; Set Counter Maximum
movlw 0x99
movwf MAXCNTL
goto DIV_DONE
DIV_90
movlw 0x7F ; 32716.8 = 0x7FCC
movwf MAXCNTH
movlw 0xCC
movwf MAXCNTL
goto DIV_DONE
DIV_60
movlw 0x55
movwf MAXCNTH
movlw 0x32
movwf MAXCNTL
goto DIV_DONE
DIV_45
movlw 0x3F ; 16358.4 = 0x3FE6
movwf MAXCNTH
movlw 0xE6
movwf MAXCNTL
goto DIV_DONE
DIV_30
movlw 0x2A ; 10905.6 = 0x2A99
movwf MAXCNTH
movlw 0x99
movwf MAXCNTL
goto DIV_DONE
DIV_10
movlw 0x0A
movwf MAXCNTH
movlw 0xA6
movwf MAXCNTL
goto DIV_DONE
DIV_01
movlw 0x00 ; 181.76 = 0x00B5
movwf MAXCNTH
movlw 0xAA
movwf MAXCNTL
goto DIV_DONE
DIV_DONE
incf Stop_Divs,1
movf Stop_Divs,0
movlw 0x08
cpfseq Stop_Divs
goto RC5_DONE
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
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
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
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
RUN_OVER_DONE
bsf INTCON,GIE ; Enable Global Interrupt
PROG_LOOP_DONE
bsf INTCON,GIE ; Enable Global Interrupt
goto PROG_LOOP
end
; Index Table Motor Controller Application
; 09/23/06 ajs Initial Application Template
;
; PIC18F4431 I/O
; --------------
; INPUT
; User Interface Digital Input Buttons. Debounce performed by button
hardware
; #1: RE3/MCLR => MCU Reset
; #2: RC4/INT1 => Stop Divisions Count
; #3: RC5/INT2 => Motor Speed and Direction
; #4: RC3/INT0 => Run
;
; Quadrature Encoder Interface Digital Inputs
; RA2 => Index
; RA3 => Channel A
; RA4 => Channel B
;
; OUTPUT
; RB0/PWM0 => A3959 Enable
; RB1/PWM1 => Inverse of PWM0, Activity LED
; RB2 => A3959 Phase
; RB3 => A3959 Extended Mode
;
; RD
;
; Operational Variables
; QEI_Flags: QEI Monitoring Flags
; QEI_Flags,0 = Monitoring of QEI Flags is Enabled
; QEI_Flags,1 = Interrupt on Position = Max Count
; QEI_Flags,2 = Max Count Changed
; QEI_Flags,3 = Repeat Run
; QEI_Flags,7 = Rotation Direction Changed
include <P18f4431.INC>
btfsc INTCON,INT0IF
bsf Buttons,3 ; Set Button Flag 3
bcf INTCON,INT0IF
bcf PIR3,PTIF
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
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
; Setup RC5/INT2
bcf INTCON3,INT2IF ; Clear INT2
bsf INTCON3,INT2IP ; Set INT2 to High Priority
bsf INTCON3,INT2IE ; Enable INT2 Interrupt
; Setup RC3/INT0
bsf INTCON3,INT2IE ; Enable INT2 Interrupt
bcf INTCON,INT0IF ; Clear INT0
bsf INTCON,INT0IE ; Enable INT0 Interrupt
D_360
movf LATD,0 ; Get the current Div Stop Setting
xorlw 0x10 ; XOR with 0x10 = 360 deg
tstfsz WREG ; Test
goto D_180 ; Not Zero so try 180 deg
movlw 0xFF ; 65433.6 = 0xFF99
movwf MAXCNTH ; Set Counter Maximum
movlw 0x99
movwf MAXCNTL
goto QEI_ENABLE
D_180
movf LATD,0
xorlw 0x20 ; XOR with 0x20 = 180 deg
tstfsz WREG
goto D_90
movlw 0x7F ; 32716.8 = 0x7FCC
movwf MAXCNTH
movlw 0xCC
movwf MAXCNTL
goto QEI_ENABLE
D_90
movf LATD,0
xorlw 0x30 ; XOR with 0x30 = 90 deg
tstfsz WREG
goto D_60
movlw 0x3F ; 16358.4 = 0x3FE6
movwf MAXCNTH
movlw 0xE6
movwf MAXCNTL
goto QEI_ENABLE
D_60
movf LATD,0
xorlw 0x40 ; XOR with 0x40 = 60 deg
tstfsz WREG
goto D_45
movlw 0x2A ; 10905.6 = 0x2A99
movwf MAXCNTH
movlw 0x99
movwf MAXCNTL
goto QEI_ENABLE
D_45
movf LATD,0
xorlw 0x50 ; XOR with 0x50 = 45 deg
tstfsz WREG
goto D_10
movlw 0x1F ; 8179.2 = 0x1FF3
movwf MAXCNTH
movlw 0xF3
movwf MAXCNTL
goto QEI_ENABLE
D_10
movf LATD,0
xorlw 0x60 ; XOR with 0x60 = 10 deg
tstfsz WREG
goto D_01
movlw 0x07 ; 1817.6 = 0x0719
movwf MAXCNTH
movlw 0x19
movwf MAXCNTL
goto QEI_ENABLE
D_01
movf LATD,0
xorlw 0x70 ; XOR with 0x70 = 1 deg
tstfsz WREG
goto D_RESET
movlw 0x00 ; 181.76 = 0x00B5
movwf MAXCNTH
movlw 0xB5
movwf MAXCNTL
goto QEI_ENABLE
QEI_ENABLE
bcf Buttons,4 ; Reset Buttons 4 Flag
bsf INTCON,GIE ; Enable Global Interrupt
MS_INCREASE
movlw 0x10 ; Else Increase Speed
addwf LATB
MS_SLOW
movf LATB,0 ; Get the current Motor Speed setting
xorlw 0x10 ; XOR with 0x10 = Slow
tstfsz WREG ; Test
goto MS_FASTER ; Not Zero so try Faster
movlw 0x0F ; 1535 = 0x5FF
movwf PDC0H ; Set Duty Cycle
movlw 0xFF
movwf PDC0L
goto MS_DONE
MS_FASTER
movf LATB,0
xorlw 0x20 ; XOR with 0x20 = Faster
tstfsz WREG
goto MS_MAX
movlw 0x1F ; 2815 0xAFF
movwf PDC0H
movlw 0xFF
movwf PDC0L
goto MS_DONE
MS_MAX
movf LATB,0
xorlw 0x30 ; XOR with 0x30 = Maximum Speed
tstfsz WREG
goto MS_DONE
movlw 0x2F ; 4095 = 0xFFF
movwf PDC0H
movlw 0xFF
movwf PDC0L
goto MS_DONE
MS_DONE
bcf Buttons,5 ; Reset Buttons 5 Flag
bsf INTCON,GIE ; Enable Global Interrupt
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
STATE_QEI_0
bcf INTCON,GIE ; Disable Global Interrupt
bcf QEI_Flags,QF_Dir ; Clear Direction Change Flag
;QEI_0_DONE
bsf INTCON,GIE ; Enable Global Interrupt
STATE_QEI_1
bcf INTCON,GIE ; Disable Global Interrupt
QEI_1_STOP_RUN
bcf PWMCON0,PWMEN0 ; Stop PWM
QEI_RUN
bcf QEI_Flags,QF_Run ; Clear Run Flag
QEI_1_DONE
bcf QEI_Flags,QF_MaxChg ; Clear QEI Max Changed
bcf QEI_Flags,QF_PosMax ; Clear QEI Position = Max Count Flag
bsf INTCON,GIE ; Enable Global Interrupt
FINAL_CHECK
goto PROG_LOOP
end
Motor Controller Unit Test 7
; 08/31/06 ajs A3959: For Demo Index Table: PHASE[RC5/INT2 button ->
RD5] ON = CW
; 08/26/06 ajs DS275: Transmit Test
;
; PIC18F4431 I/O
; Input Output
; RC3/INT0 -> RB0/PWM0 => A3959 Enable
; RC4/INT1 -> RD4 => A3959 Mode
; RC5/INT2 -> RD5 => A3959 Phase
;
; Unit Test Scope
; Verify Operation of Motor on A3959 at 100% ON/OFF with Vbb = 12V
; Verify Transmission of Data on DS275 at 2400 baud
;
include <P18f4431.INC>
ORG 0x0000 ; MCLR Reset Entry Point Vector
goto RESET_1 ; Jump to Initialization
btfsc INTCON,INT0IF
bsf Buttons,3 ; Set Button Flag 3
bcf INTCON,INT0IF
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
bcf PORTE,RE1
bcf TRISE,RE1
Setup_Async_Mode
#define TXSTA_INIT 0x20
#define RCSTA_INIT 0x90
movlw 0x33 ; 0x81 for 20MHz OSC
movwf SPBRG ; baud rate generator is reset & initialized
movlw TXSTA_INIT
movwf TXSTA ; 8-bit transmission, async mode
movlw RCSTA_INIT
movwf RCSTA ; 8-bit reception, enable serial port,
bcf PIR1,TXIF
movlw 0x0D
movwf TXREG
TXi1
bsf PORTE,RE1
btfss PIR1,TXIF
goto TXi1
movlw 0x0D
movwf TXREG
TXi2
bsf PORTE,RE1
btfss PIR1,TXIF
goto TXi2
movlw 0x0D
movwf TXREG
TXi3
bsf PORTE,RE1
btfss PIR1,TXIF
goto TXi3
movlw 0x2A
movwf TXREG
TXi4
bsf PORTE,RE1
btfss PIR1,TXIF
goto TXi4
movlw 0x0D
movwf TXREG
TXi5
bsf PORTE,RE1
btfss PIR1,TXIF
goto TXi5
bcf PORTE,RE1
; Setup RC4/INT1 Interupt
bcf INTCON3,INT1IF ; Clear INT1
bsf INTCON3,INT1IP ; Set INT1 to High Priority
bsf INTCON3,INT1IE ; Enable INT1 Interrupt
bcf INTCON3,INT2IF ; Clear INT2
bsf INTCON3,INT2IP ; Set INT2 to High Priority
bsf INTCON3,INT2IE ; Enable INT0 Interrupt
CHECK_1
btfss Buttons,4 ; Check for RC4/INT1 Button Flag
goto CHECK_2 ; flag not set, goto next run state
CHECK_2
btfss Buttons,5 ; Check for RC5/INT2
goto CHECK_3 ; flag not set, goto next run state
CHECK_3
btfss Buttons,3 ; Check for RC3/INT0
goto CHECK_4 ; flag not set, goto next run state
CHECK_4
goto CHECK_1
TX_BUTTON
TX_J1
bsf PORTE,RE1
btfss PIR1,TXIF
goto TX_J1
movlw 0x21 ; "!"
movwf TXREG
TX_J2
bsf PORTE,RE1
btfss PIR1,TXIF
goto TX_J2
movlw 0x55 ; "U"
movwf TXREG
TXB4
bsf PORTE,RE1
btfss PIR1,TXIF
goto TXB4
TXB5
btfss Buttons,5 ; Check for RC5/INT2 Button Flag
goto TXB3
movlw 0x32
movwf TXREG
goto TX_J3
TXB3
btfss Buttons,3 ; Check for RC3/INT0 Button Flag
goto TX_J3
movlw 0x33
movwf TXREG
TX_J3
bsf PORTE,RE1
btfss PIR1,TXIF
goto TX_J3
movlw 0x0D
movwf TXREG
TX_J4
bsf PORTE,RE1
btfss PIR1,TXIF
goto TX_J4
bcf PORTE,RE1
return
;Get_Serial_Data_Poll
; movlb 1 ; PIR is in bank 1
;PollRcv
; btfss PIR,0 ; check the RBIF bit
; goto PollRcv ; loop until char received, assume WDT is off
; movlb 0 ; RCREG is in bank 0
; movpf RCREG,SerInData
; return ; Received 8-bits are in SerInData
W_Temp res 1
STAT_Temp res 1
BSR_Temp res 1
Buttons res 1 ; Button Flags 1=ON, 0=OFF
Button_Press res 1
end
; Motor Controller Unit Test 8
; 09/04/06 ajs PWM Test
; 09/02/06 ajs PIC18F4431 QEI Test
; 08/31/06 ajs A3959: For Demo Index Table: PHASE[RC5/INT2 button ->
RD5] ON = CW
; 08/26/06 ajs DS275: Transmit Test
;
; PIC18F4431 I/O
; Input Output
; RC3/INT0 -> RB0/PWM0 => A3959 Enable
; RC4/INT1 -> RD4 => A3959 Mode
; RC5/INT2 -> RD5 => A3959 Phase
;
; Unit Test Scope
; Verify Operation of Motor on A3959 at 100% ON/OFF with Vbb = 12V
; Verify Transmission of Data on DS275 at 2400 baud
;
include <P18f4431.INC>
btfsc INTCON,INT0IF
bsf Buttons,3 ; Set Button Flag 3
bcf INTCON,INT0IF
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 PORTA
clrf PORTB ; Setup PORTB I/O
bcf TRISB,RB0 ; RB0 = Output
;bcf TRISB,RB5 ; RB5 = Output
;bcf TRISB,RB4 ; RB4 = Output
bcf PORTE,RE1
bcf TRISE,RE1
Setup_Async_Mode
#define TXSTA_INIT 0x20
#define RCSTA_INIT 0x90
movlw 0x33 ; 0x81 for 20MHz OSC
movwf SPBRG ; baud rate generator is reset & initialized
movlw TXSTA_INIT
movwf TXSTA ; 8-bit transmission, async mode
movlw RCSTA_INIT
movwf RCSTA ; 8-bit reception, enable serial port,
bcf PIR1,TXIF
movlw 0x0D
movwf TXREG
TXi1
bsf PORTE,RE1
btfss PIR1,TXIF
goto TXi1
movlw 0x0D
movwf TXREG
TXi2
bsf PORTE,RE1
btfss PIR1,TXIF
goto TXi2
movlw 0x0D
movwf TXREG
TXi3
bsf PORTE,RE1
btfss PIR1,TXIF
goto TXi3
movlw 0x2A
movwf TXREG
TXi4
bsf PORTE,RE1
btfss PIR1,TXIF
goto TXi4
movlw 0x0D
movwf TXREG
TXi5
bsf PORTE,RE1
btfss PIR1,TXIF
goto TXi5
bcf PORTE,RE1
QEI_INIT
bcf ANSEL0,ANS4
bcf ANSEL0,ANS3
bcf ANSEL0,ANS2
bsf TRISA,RA4
bsf TRISA,RA3
bsf TRISA,RA2
movlw 0xFF
movwf MAXCNTH
movwf MAXCNTL
movwf CAP2BUFH
movwf CAP2BUFL
movwf CAP3BUFH
movwf CAP3BUFL
clrf POSCNTL
clrf POSCNTH
clrf QEICON
bsf QEICON,VELM
bsf QEICON,QEIM1
PWM_INIT
clrf PWMCON0 ; Disable PWM, clear configuration
bcf PTCON1,PTEN ; Disable PWM Timer
clrf PTCON0 ; Clear PWM Timer
;movlw 0x3E
movwf PDC0H
movlw 0xFF
movwf PDC0L
bsf PTCON0,PTMOD1
bsf PTCON0,PTMOD0
bsf PTCON1,PTEN
bsf PWMCON0,PMOD0
CHECK_1
btfss Buttons,4 ; Check for RC4/INT1 Button Flag
goto CHECK_2 ; flag not set, goto next run state
CHECK_2
btfss Buttons,5 ; Check for RC5/INT2
goto CHECK_3 ; flag not set, goto next run state
CHECK_3
btfss Buttons,3 ; Check for RC3/INT0
goto CHECK_4 ; flag not set, goto next run state
CHECK_4
btfss PORTA,RA3
goto CLEAR_LED
SET_LED
bsf PORTD,RD0
goto CHECK_5
CLEAR_LED
bcf PORTD,RD0
goto CHECK_5
CHECK_5
goto CHECK_1
PWM_STOP
bcf PTCON1,PTEN ; Disable PWM Timer
return
PWM_RUN
movlw 0x20
movwf PWMCON0
bsf PTCON1,PTEN
return
TX_BUTTON
TX_J1
bsf PORTE,RE1
btfss PIR1,TXIF
goto TX_J1
movlw 0x21 ; "!"
movwf TXREG
TX_J2
bsf PORTE,RE1
btfss PIR1,TXIF
goto TX_J2
movlw 0x55 ; "U"
movwf TXREG
TXB4
bsf PORTE,RE1
btfss PIR1,TXIF
goto TXB4
TXB5
btfss Buttons,5 ; Check for RC5/INT2 Button Flag
goto TXB3
movlw 0x32
movwf TXREG
goto TX_J3
TXB3
btfss Buttons,3 ; Check for RC3/INT0 Button Flag
goto TX_J3
movlw 0x33
movwf TXREG
TX_J3
bsf PORTE,RE1
btfss PIR1,TXIF
goto TX_J3
movlw 0x0D
movwf TXREG
TX_J4
bsf PORTE,RE1
btfss PIR1,TXIF
goto TX_J4
bcf PORTE,RE1
return
;Get_Serial_Data_Poll
; movlb 1 ; PIR is in bank 1
;PollRcv
; btfss PIR,0 ; check the RBIF bit
; goto PollRcv ; loop until char received, assume WDT is off
; movlb 0 ; RCREG is in bank 0
; movpf RCREG,SerInData
; return ; Received 8-bits are in SerInData
W_Temp res 1
STAT_Temp res 1
BSR_Temp res 1
Buttons res 1 ; Button Flags 1=ON, 0=OFF
Button_Press res 1
end
; Index Table Motor Controller Application
; 09/23/06 ajs Initial Application Template
;
; PIC18F4431 I/O
; --------------
; INPUT
; User Interface Digital Input Buttons. Debounce performed by button
hardware
; #1: RE3/MCLR => MCU Reset
; #2: RC4/INT1 => Stop Divisions Count
; #3: RC5/INT2 => Motor Speed and Direction
; #4: RC3/INT0 => Run
;
; Quadrature Encoder Interface Digital Inputs
; RA2 => Index
; RA3 => Channel A
; RA4 => Channel B
;
; OUTPUT
; RB0/PWM0 => A3959 Enable
; RB1/PWM1 => Inverse of PWM0, Activity LED
; RB2 => A3959 Phase
; RB3 => A3959 Extended Mode
;
; RD
;
; Operational Variables
; QEI_Flags: QEI Monitoring Flags
; QEI_Flags,0 = Monitoring of QEI Flags is Enabled
; QEI_Flags,1 = Interrupt on Position = Max Count
; QEI_Flags,2 = Max Count Changed
; QEI_Flags,3 = Repeat Run
; QEI_Flags,7 = Rotation Direction Changed
include <P18f4431.INC>
bcf PIR3,PTIF
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
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
PWM_INIT
clrf Motor_Digit
clrf Stop_Digit
; Setup RC5/INT2
bcf INTCON3,INT2IF ; Clear INT2
bsf INTCON3,INT2IP ; Set INT2 to High Priority
bsf INTCON3,INT2IE ; Enable INT2 Interrupt
; Setup RC3/INT0
bsf INTCON3,INT2IE ; Enable INT2 Interrupt
bcf INTCON,INT0IF ; Clear INT0
bsf INTCON,INT0IE ; Enable INT0 Interrupt
D_360
movf LATD,0 ; Get the current Div Stop Setting
xorlw 0x10 ; XOR with 0x10 = 360 deg
tstfsz WREG ; Test
goto D_180 ; Not Zero so try 180 deg
movlw 0xFF ; 65433.6 = 0xFF99
movwf MAXCNTH ; Set Counter Maximum
movlw 0x99
movwf MAXCNTL
goto QEI_ENABLE
D_180
movf LATD,0
xorlw 0x20 ; XOR with 0x20 = 180 deg
tstfsz WREG
goto D_90
movlw 0x7F ; 32716.8 = 0x7FCC
movwf MAXCNTH
movlw 0xCC
movwf MAXCNTL
goto QEI_ENABLE
D_90
movf LATD,0
xorlw 0x30 ; XOR with 0x30 = 90 deg
tstfsz WREG
goto D_60
movlw 0x3F ; 16358.4 = 0x3FE6
movwf MAXCNTH
movlw 0xE6
movwf MAXCNTL
goto QEI_ENABLE
D_60
movf LATD,0
xorlw 0x40 ; XOR with 0x40 = 60 deg
tstfsz WREG
goto D_45
movlw 0x2A ; 10905.6 = 0x2A99
movwf MAXCNTH
movlw 0x99
movwf MAXCNTL
goto QEI_ENABLE
D_45
movf LATD,0
xorlw 0x50 ; XOR with 0x50 = 45 deg
tstfsz WREG
goto D_10
movlw 0x1F ; 8179.2 = 0x1FF3
movwf MAXCNTH
movlw 0xF3
movwf MAXCNTL
goto QEI_ENABLE
D_10
movf LATD,0
xorlw 0x60 ; XOR with 0x60 = 10 deg
tstfsz WREG
goto D_01
movlw 0x07 ; 1817.6 = 0x0719
movwf MAXCNTH
movlw 0x19
movwf MAXCNTL
goto QEI_ENABLE
D_01
movf LATD,0
xorlw 0x70 ; XOR with 0x70 = 1 deg
tstfsz WREG
goto D_RESET
movlw 0x00 ; 181.76 = 0x00B5
movwf MAXCNTH
movlw 0xB5
movwf MAXCNTL
goto QEI_ENABLE
QEI_ENABLE
bcf Buttons,4 ; Reset Buttons 4 Flag
bsf INTCON,GIE ; Enable Global Interrupt
MS_INCREASE
movlw 0x10 ; Else Increase Speed
addwf LATB
MS_SLOW
movf LATB,0 ; Get the current Motor Speed setting
xorlw 0x10 ; XOR with 0x10 = Slow
tstfsz WREG ; Test
goto MS_FASTER ; Not Zero so try Faster
movlw 0x0F ; 1535 = 0x5FF
movwf PDC0H ; Set Duty Cycle
movlw 0xFF
movwf PDC0L
goto MS_DONE
MS_FASTER
movf LATB,0
xorlw 0x20 ; XOR with 0x20 = Faster
tstfsz WREG
goto MS_MAX
movlw 0x1F ; 2815 0xAFF
movwf PDC0H
movlw 0xFF
movwf PDC0L
goto MS_DONE
MS_MAX
movf LATB,0
xorlw 0x30 ; XOR with 0x30 = Maximum Speed
tstfsz WREG
goto MS_DONE
movlw 0x2F ; 4095 = 0xFFF
movwf PDC0H
movlw 0xFF
movwf PDC0L
goto MS_DONE
MS_DONE
bcf Buttons,5 ; Reset Buttons 5 Flag
bsf INTCON,GIE ; Enable Global Interrupt
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
STATE_QEI_0
bcf INTCON,GIE ; Disable Global Interrupt
bcf QEI_Flags,QF_Dir ; Clear Direction Change Flag
;QEI_0_DONE
bsf INTCON,GIE ; Enable Global Interrupt
STATE_QEI_1
bcf INTCON,GIE ; Disable Global Interrupt
QEI_1_STOP_RUN
bcf PWMCON0,PWMEN0 ; Stop PWM
QEI_RUN
bcf QEI_Flags,QF_Run ; Clear Run Flag
QEI_1_DONE
bcf QEI_Flags,QF_MaxChg ; Clear QEI Max Changed
bcf QEI_Flags,QF_PosMax ; Clear QEI Position = Max Count Flag
bsf INTCON,GIE ; Enable Global Interrupt
FINAL_CHECK
goto PROG_LOOP
end
******************************************************************
***/
/* Header for IO ports module library functions */
/
******************************************************************
***/
#ifndef __PORTS_H
#define __PORTS_H
/* List of SFRs for IO ports */
/* This list contains the SFRs with default (POR) values to be used for
configuring IOports */
/* The user can modify this based on the requirement */
#define CNEN1_VALUE 0x0000
#define CNPU1_VALUE 0x0000
#endif
//////////////////////////////////////////////////////////////////////////////////////////////
/* Macros to Enable External interrupts */
#else
#endif
/* Function Prototypes */
/* ConfigCNPullups
* Enable/ disable pull up registers
*/
void ConfigCNPullups(long int) __attribute__ ((section (".libperi")));
/* ConfigIntCN
* Enable/Disable CN interrupt and set priority
*/
void ConfigIntCN(long int) __attribute__ ((section (".libperi")));
/* configINT0
* Enable/disable INT0 interrupts,set priority and falling edge/rising edge
*/
void configINT0(unsigned int) __attribute__ ((section (".libperi")));
/* CloseINT0
* Disable INT0 interrupts, registers
*/
void CloseINT0() __attribute__ ((section (".libperi")));
/* configINT1
* Enable/disable INT1 interrupt,set priority and falling edge/rising edge
*/
void configINT1(unsigned int) __attribute__ ((section (".libperi")));
/* CloseINT1
* Disable INT1 interrupts, registers
*/
void CloseINT1() __attribute__ ((section (".libperi")));
/* configINT2
* Enable/disable INT2 interrupt,set priority and falling edge/rising edge
*/
void configINT2(unsigned int) __attribute__ ((section (".libperi")));
/* CloseINT2
* Disable INT2 interrupts, registers
*/
void CloseINT2() __attribute__ ((section (".libperi")));
/* CloseINT3
* Disable INT3 interrupts, registers
*/
void CloseINT3() __attribute__ ((section (".libperi")));
/* configINT4
* Enable/disable INT4 interrupt,set priority and falling edge/rising edge
*/
void configINT4(unsigned int) __attribute__ ((section (".libperi")));
/* CloseINT4
* Disable INT4 interrupts, registers
*/
void CloseINT4() __attribute__ ((section (".libperi")));
#endif
#endif
// include files
#include <p30fxxxx.h>
#include <can.h>
#define dataarray 0x0900
// config bits
_FOSC(ECIO);
_FWDT(WDT_OFF);
// defines
// function prototypes
void CAN_Init(void);
void PIC_Init(void);
int SendCANMsg (void);
// global vars
// CAN variables
/* Length of data to be transmitted/read */
unsigned char datalen;
unsigned char Txdata[] = {'M','I','C','R','O','C','H','I','P','\0'};
unsigned int TXConfig, RXConfig;
unsigned long MaskID,MessageID;
char FilterNo, tx_rx_no;
unsigned char * datareceived = (unsigned char *) dataarray; /* Holds
the data received */
int main(void)
{
unsigned int eeAddr, eeData, i, j;
Nop();
PIC_Init();
Nop();
CAN_Init();
while(1)
{
// send msg on buttonpress
if(PORTDbits.RD8 == 0)
{
// small debounce
for(i=0; i<0xFFFF; i++);
if(PORTDbits.RD8 == 0)
{
j = 0;
j = SendCANMsg();
}
}
}
return 0;
}
//
// function definitions
void PIC_Init(void)
{
// all digital I/O
ADPCFG = 0xFFFF;
TRISD = 0xFFFF;
TRISFbits.TRISF0 = 1;
TRISFbits.TRISF1 = 0;
TRISBbits.TRISB0 = 0;
TRISBbits.TRISB1 = 0;
Nop();
}
//
void CAN_Init(void)
{
CAN_REQ_OPERMODE_CONFIG &
CAN_CAPTURE_DIS);
CAN_PROPAGATIONTIME_SEG_TQ(3) &
CAN_SEG2_FREE_PROG &
CAN_SAMPLE3TIMES);
CAN1SetFilter( FilterNo,
CAN_FILTER_SID(0x0821) &
CAN_RX_EID_DIS,
CAN_FILTER_EID(0x00000000));
PORTBbits.RB1 = 1;
return;
}
//
/* 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();
PORTBbits.RB0 = 1;
/* Read received data from receive buffer and store it into user
defined dataarray */
CAN1ReceiveMessage(datareceived, datalen, tx_rx_no);
Nop();
return(1);
}
//
//*****************************************************************
//* CAN_Crosswire.c *
//*****************************************************************
//* *
//* Written by: Priyabrata Sinha *
//* Applications Engr. *
//* Microchip Technology Inc. *
//* Date: 6 April 2004 *
//* Revision: 1.00 *
//*****************************************************************
// modified to test on 30F4011 *
//*****************************************************************
#include "p30F4011.h"
//---------------------------------------------------------------------
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
C1INTF = 0;
IFS1bits.C1IF = 0;
C1INTE = 0x00FF; // Enable all interrupt sources
IEC1bits.C1IE = 1;
#if 0
C2CTRLbits.CANCKS = 1;
C2CFG1 = ((FCY/32)/BITRATE)-1;
// C2CFG2 = 0x06F0; // SEG1PH=7Tq, SEG2PH=7Tq, PRSEG=1Tq
// Sample 3 times
// Each bit time is 16Tq
C2INTF = 0;
IFS2bits.C2IF = 0;
C2INTE = 0x00FF; // Enable all interrupt sources
IEC2bits.C2IE = 1;
#endif
INTCON1bits.NSTDIS = 1;
//---------------------------------------------------------------------
#if 0
C1RX0CON = C1RX1CON = C2RX0CON = C2RX1CON = 0x0000;
C1RXF0SID = 0x0AA8;
C1RXF2SID = 0x1555;
C1RXF2EIDH = 0x0004;
C1RXF2EIDL = 0x8C00;
#if 0
C2RXF0SID = 0x0AA8;
C2RXF2SID = 0x1555;
C2RXF2EIDH = 0x0004;
C2RXF2EIDL = 0x8C00;
#endif
#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];
// Enable transmission
C1TX0CONbits.TXREQ = 1;
//C1TX1CONbits.TXREQ = 1;
//C1TX2CONbits.TXREQ = 1;
///// C2TX0CONbits.TXREQ = 1; // not available on 30F4011
//C2TX1CONbits.TXREQ = 1;
//C2TX2CONbits.TXREQ = 1;
} // end main
//---------------------------------------------------------------------
//---------------------------------------------------------------------
#include <p30f4011.h>
#include <qei.h>
/
******************************************************************
********
* Function Name : CloseQEI()
* Description : This routine disables the QEI and its interrupt bits.
******************************************************************
*********/
void CloseQEI(void)
{
IEC2bits.QEIIE = 0; // disable interrupt
QEICONbits.QEIM = 0x0; // QEI/Timer off
IFS2bits.QEIIF = 0; // clear IF flag
}
/
******************************************************************
***
* Function Name : ConfigIntQEI()
* Description : This function Configures QEI Interrupt and interrupt
* priority and clears the interrupt
flag.
* Parameters : unsigned int
******************************************************************
***/
/
******************************************************************
***
* 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
******************************************************************
***/
#ifndef __QEI_H
#define __QEI_H
#endif /*__QEI_H */
// RS232.c
// 12/22/06 From MicroChip C30 Library for dsPIC30F4011
#include <p30f4011.h>
#include "uart.h"
#include <p30f4011.h>
#include "uart.h"
char BusyUART1(void)
{
// Return TRUE if UART1 is busy Transmitting
return(!U1STAbits.TRMT);
}
char BusyUART2(void)
{
// Return TRUE if UART2 is busy Transmitting
return(!U2STAbits.TRMT);
}
void CloseUART1(void)
{
// Disables UART1 and Interrupt; Clear Flags
U1MODEbits.UARTEN = 0;
IEC0bits.U1RXIE = 0;
IEC0bits.U1TXIE = 0;
IFS0bits.U1RXIF = 0;
IFS0bits.U1TXIF = 0;
}
void CloseUART2(void)
{
// Disables UART2 and Interrupt; Clear Flags
U2MODEbits.UARTEN = 0;
IEC1bits.U2RXIE = 0;
IEC1bits.U2TXIE = 0;
IFS1bits.U2RXIF = 0;
IFS1bits.U2TXIF = 0;
}
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 *
************************************************************************
******/
{
// 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;
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"
/********************************************************************
Header for UART module library functions
********************************************************************/
#ifndef __UART_H
#define __UART_H
/************************Function prototype**************************/
void putsUART1(unsigned int *buffer) __attribute__ ((section
(".libperi")));
#define SetPriorityIntU2RX(priority)
(IPC6bits.U2RXIP = priority)
#define SetPriorityIntU2TX(priority)
(IPC6bits.U2TXIP = priority)
#endif /*__UART_H */
/********************************************************************/
/* Header for SPI module library functions */
/********************************************************************/
#ifndef __SPI_H
#define __SPI_H
#else
#endif
/*SPIXCON2 REGISTER */
#define FRAME_ENABLE_ON 0xffff /* Frame SPI support
enable */
#define FRAME_ENABLE_OFF 0x7fff /* Frame SPI support
Disable */
#else
/* SPIxCON REGISTER bits in 30F devices differing from 33F and 24H
devices */
#endif
/* SPIxSTAT REGISTER */
#endif
/* DataRdySPI */
/* OpenSPI */
void OpenSPI1(unsigned int config1,unsigned int config2,unsigned
int config3 ) __attribute__ ((section (".libperi")));
/* OpenSPI */
void OpenSPI2(unsigned int config1,unsigned int config2,
unsigned int config3 )__attribute__ ((section(".libperi")));
#else
/* FUNCTION PROTOTYPES */
/* DataRdySPI */
/* OpenSPI */
void OpenSPI2(unsigned int config1,unsigned int
config2 ) __attribute__ ((section
(".libperi")));
#endif
#endif
#endif /* __SPI_H */
#ifndef __QEI_H
#define __QEI_H
#endif /*__QEI_H */