Ok, I'm explaining what I'm trying to do, my codes are little bit long.
I'm controlling 6 motors seperately and applying them PWM signals by using TMR0, I'm getting encoder data back and counting them to control positions of motors.
Here is my first code without DT-INTS, I'm compiling them with PBP247, I want to count 50 pulses from each to get them correct position and make them spin for 1 quarter round, and it's working as it has to be.
Code:
'Defining controller properties
@ DEVICE PIC16F877A
@ DEVICE PIC16F877A,HS_OSC
@ DEVICE PIC16F877A,WDT_OFF
@ DEVICE PIC16F877A,LVP_OFF
DEFINE OSC 16
on interrupt goto kesme
OPTION_REG=%10000100
INTCON=%10100000
ADCON1=7
'Defining Port usages and clearing ports for start
TRISA=%00000000
TRISB=%00000000
TRISC=%11110000
TRISD=%00000011
TRISE=%00000000
PORTA=0
PORTB=0
PORTC=0
PORTD=0
PORTE=0
'DEFINE ENCODER INPUTS
SYMBOL EN1=PORTC.7
SYMBOL EN2=PORTC.6
SYMBOL EN3=PORTC.5
SYMBOL EN4=PORTC.4
SYMBOL EN5=PORTD.1
SYMBOL EN6=PORTD.0
'DEFINE MOTOR CONTROL OUTPUTS
SYMBOL M1A=PORTB.7
SYMBOL M1B=PORTB.6
SYMBOL M2A=PORTB.5
SYMBOL M2B=PORTB.4
SYMBOL M3A=PORTB.3
SYMBOL M3B=PORTB.2
SYMBOL M4A=PORTD.7
SYMBOL M4B=PORTD.6
SYMBOL M5A=PORTD.5
SYMBOL M5B=PORTD.4
SYMBOL M6A=PORTD.3
SYMBOL M6B=PORTD.2
'DEFINE VARIABLES
EN1PRE var BIT
EN1NOW var BIT
EN2PRE var BIT
EN2NOW var BIT
EN3PRE var BIT
EN3NOW var BIT
EN4PRE var BIT
EN4NOW var BIT
EN5PRE var BIT
EN5NOW var BIT
EN6PRE var BIT
EN6NOW var BIT
M1STEPSIZE VAR BYTE
M2STEPSIZE VAR BYTE
M3STEPSIZE VAR BYTE
M4STEPSIZE VAR BYTE
M5STEPSIZE VAR BYTE
M6STEPSIZE VAR BYTE
M1STATE VAR BYTE
M2STATE VAR BYTE
M3STATE VAR BYTE
M4STATE VAR BYTE
M5STATE VAR BYTE
M6STATE VAR BYTE
STANDC VAR BYTE
M1C var BIT
M2C var BIT
M3C var BIT
M4C var BIT
M5C var BIT
M6C var BIT
walk_mode var byte
duty_check var BIT
duty_ctrl var BIT
duty1 var byte
duty0 var byte
M1POWER var BIT
M2POWER var BIT
M3POWER var BIT
M4POWER var BIT
M5POWER var BIT
M6POWER var BIT
STANDUP_COUNT VAR BYTE
RST:
CLEAR 'Clear all variables
'Defining starting values of some variables
M1STEPSIZE=50
M2STEPSIZE=50
M3STEPSIZE=50
M4STEPSIZE=50
M5STEPSIZE=50
M6STEPSIZE=50
EN1PRE=EN1
EN2PRE=EN2
EN3PRE=EN3
EN4PRE=EN4
EN5PRE=EN5
EN6PRE=EN6
M1POWER=1
M2POWER=1
M3POWER=1
M4POWER=1
M5POWER=1
M6POWER=1
STANDUP_COUNT=50
pause 3000
walk_mode=0 'walk_mode defines which movement mode RHEX will use
TMR0=255 'Start Timer so interrupts and movement will start
'RHEX IS STANDING UP
'Check every motor encoder value and stop releated motor if it reached to
'defined position
'MXC is used for motor running control, if a motor is reached to desired
'position and stopped, do not check and lose time on it
STANDUP:
GOSUB ENCOUNTER
IF M1C=0 THEN
IF M1STATE>=STANDUP_COUNT THEN
M1POWER=0
M1C=1
STANDC=STANDC+1
ENDIF
ENDIF
IF M2C=0 THEN
IF M2STATE>=STANDUP_COUNT THEN
M2POWER=0
M2C=1
STANDC=STANDC+1
ENDIF
ENDIF
IF M3C=0 THEN
IF M3STATE>=STANDUP_COUNT THEN
M3POWER=0
M3C=1
STANDC=STANDC+1
ENDIF
ENDIF
IF M4C=0 THEN
IF M4STATE>=STANDUP_COUNT THEN
M4POWER=0
M4C=1
STANDC=STANDC+1
ENDIF
ENDIF
IF M5C=0 THEN
IF M5STATE>=STANDUP_COUNT THEN
M5POWER=0
M5C=1
STANDC=STANDC+1
ENDIF
ENDIF
IF M6C=0 THEN
IF M6STATE>=STANDUP_COUNT THEN
M6POWER=0
M6C=1
STANDC=STANDC+1
ENDIF
ENDIF
IF STANDC>=6 THEN
M1STATE=0
M2STATE=0
M3STATE=0
M4STATE=0
M5STATE=0
M6STATE=0
STANDC=0
PAUSE 3000
GOTO RST
ELSE
GOTO STANDUP
ENDIF
GOTO RST
'COUNTING PULSES FROM ENCODER OUTPUTS
'Read values of encoders and if they are different from previous value
'then it means, a transition is occured, so a pulse is given
'increase the releated encoder count
'Note: This will cause 2 counts for every pulse, not 1 count for 1 pulse.
ENCOUNTER:
EN1NOW=EN1
EN2NOW=EN2
EN3NOW=EN3
EN4NOW=EN4
EN5NOW=EN5
EN6NOW=EN6
IF EN1NOW!=EN1PRE THEN
M1STATE=M1STATE+1
ENDIF
EN1PRE=EN1NOW
IF EN2NOW!=EN2PRE THEN
M2STATE=M2STATE+1
ENDIF
EN2PRE=EN2NOW
IF EN3NOW!=EN3PRE THEN
M3STATE=M3STATE+1
ENDIF
EN3PRE=EN3NOW
IF EN4NOW!=EN4PRE THEN
M4STATE=M4STATE+1
ENDIF
EN4PRE=EN4NOW
IF EN5NOW!=EN5PRE THEN
M5STATE=M5STATE+1
ENDIF
EN5PRE=EN5NOW
IF EN6NOW!=EN6PRE THEN
M6STATE=M6STATE+1
ENDIF
EN6PRE=EN6NOW
RETURN
'TMR0 INTERRUPT ROUTINE
'All motor movements are provided by this interrupt routine
'A PWM signal is created by using TMR0 timer and applied to
'motors, all PWM signals will be created by TMR0 for all movement types
disable
kesme:
if walk_mode=0 then
duty1=128
duty0=(256-duty1)
if duty_check=0 then
duty_ctrl=1
M1A=M1POWER
M1B=0
M2A=0
M2B=M2POWER
M3A=M3POWER
M3B=0
M4A=0
M4B=M4POWER
M5A=M5POWER
M5B=0
M6A=0
M6B=M6POWER
TMR0=duty1
endif
if duty_check=1 then
duty_ctrl=0
M1A=0
M1B=0
M2A=0
M2B=0
M3A=0
M3B=0
M4A=0
M4B=0
M5A=0
M5B=0
M6A=0
M6B=0
TMR0=duty0
endif
endif
if duty_ctrl=1 then
duty_check=1
else
duty_check=0
endif
INTCON.2=0
resume
enable
end
And this is the version of same code I used DT-INTS, although I changed and count for only 20 pulses from encoders, motors are spininning 4 rounds when they need to spin for only a quarter round
Code:
DEFINE OSC 16
INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR0_INT, _kesme, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
OPTION_REG=%10000100
@ INT_ENABLE TMR0_INT ; enable Timer 0 interrupts
ADCON1=7
'Defining Port usages and clearing ports for start
TRISA=%00000000
TRISB=%00000000
TRISC=%11110000
TRISD=%00000011
TRISE=%00000000
PORTA=0
PORTB=0
PORTC=0
PORTD=0
PORTE=0
'DEFINE ENCODER INPUTS
SYMBOL EN1=PORTC.7
SYMBOL EN2=PORTC.6
SYMBOL EN3=PORTC.5
SYMBOL EN4=PORTC.4
SYMBOL EN5=PORTD.1
SYMBOL EN6=PORTD.0
'DEFINE MOTOR CONTROL OUTPUTS
SYMBOL M1A=PORTB.7
SYMBOL M1B=PORTB.6
SYMBOL M2A=PORTB.5
SYMBOL M2B=PORTB.4
SYMBOL M3A=PORTB.3
SYMBOL M3B=PORTB.2
SYMBOL M4A=PORTD.7
SYMBOL M4B=PORTD.6
SYMBOL M5A=PORTD.5
SYMBOL M5B=PORTD.4
SYMBOL M6A=PORTD.3
SYMBOL M6B=PORTD.2
'DEFINE VARIABLES
wsave VAR BYTE $70 SYSTEM ' alternate save location for W
' if using $70, comment wsave1-3
wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1
wsave2 VAR BYTE $120 SYSTEM ' location for W if in bank2
wsave3 VAR BYTE $1A0 SYSTEM ' location for W if in bank3
EN1PRE var BIT
EN1NOW var BIT
EN2PRE var BIT
EN2NOW var BIT
EN3PRE var BIT
EN3NOW var BIT
EN4PRE var BIT
EN4NOW var BIT
EN5PRE var BIT
EN5NOW var BIT
EN6PRE var BIT
EN6NOW var BIT
M1STEPSIZE VAR BYTE
M2STEPSIZE VAR BYTE
M3STEPSIZE VAR BYTE
M4STEPSIZE VAR BYTE
M5STEPSIZE VAR BYTE
M6STEPSIZE VAR BYTE
M1STATE VAR BYTE
M2STATE VAR BYTE
M3STATE VAR BYTE
M4STATE VAR BYTE
M5STATE VAR BYTE
M6STATE VAR BYTE
STANDC VAR BYTE
M1C var BIT
M2C var BIT
M3C var BIT
M4C var BIT
M5C var BIT
M6C var BIT
walk_mode var byte
duty_check var BIT
duty_ctrl var BIT
duty1 var byte
duty0 var byte
M1POWER var BIT
M2POWER var BIT
M3POWER var BIT
M4POWER var BIT
M5POWER var BIT
M6POWER var BIT
STANDUP_COUNT VAR BYTE
RST:
CLEAR 'Clear all variables
'Defining starting values of some variables
M1STEPSIZE=50
M2STEPSIZE=50
M3STEPSIZE=50
M4STEPSIZE=50
M5STEPSIZE=50
M6STEPSIZE=50
EN1PRE=EN1
EN2PRE=EN2
EN3PRE=EN3
EN4PRE=EN4
EN5PRE=EN5
EN6PRE=EN6
M1POWER=0
M2POWER=0
M3POWER=0
M4POWER=0
M5POWER=0
M6POWER=0
STANDUP_COUNT=20
pause 3000
walk_mode=0 'walk_mode defines which movement mode RHEX will use
TMR0=255 'Start Timer so interrupts and movement will start
'RHEX IS STANDING UP
'Check every motor encoder value and stop releated motor if it reached to
'defined position
'MXC is used for motor running control, if a motor is reached to desired
'position and stopped, do not check and lose time on it
STANDUP:
GOSUB ENCOUNTER
IF M1C=0 THEN
IF M1STATE>=STANDUP_COUNT THEN
M1POWER=1
M1C=1
STANDC=STANDC+1
ENDIF
ENDIF
IF M2C=0 THEN
IF M2STATE>=STANDUP_COUNT THEN
M2POWER=1
M2C=1
STANDC=STANDC+1
ENDIF
ENDIF
IF M3C=0 THEN
IF M3STATE>=STANDUP_COUNT THEN
M3POWER=1
M3C=1
STANDC=STANDC+1
ENDIF
ENDIF
IF M4C=0 THEN
IF M4STATE>=STANDUP_COUNT THEN
M4POWER=1
M4C=1
STANDC=STANDC+1
ENDIF
ENDIF
IF M5C=0 THEN
IF M5STATE>=STANDUP_COUNT THEN
M5POWER=1
M5C=1
STANDC=STANDC+1
ENDIF
ENDIF
IF M6C=0 THEN
IF M6STATE>=STANDUP_COUNT THEN
M6POWER=1
M6C=1
STANDC=STANDC+1
ENDIF
ENDIF
IF STANDC>=6 THEN
M1STATE=0
M2STATE=0
M3STATE=0
M4STATE=0
M5STATE=0
M6STATE=0
STANDC=0
PAUSE 3000
GOTO RST
ELSE
GOTO STANDUP
ENDIF
GOTO RST
'COUNTING PULSES FROM ENCODER OUTPUTS
'Read values of encoders and if they are different from previous value
'then it means, a transition is occured, so a pulse is given
'increase the releated encoder count
'Note: This will cause 2 counts for every pulse, not 1 count for 1 pulse.
ENCOUNTER:
EN1NOW=EN1
EN2NOW=EN2
EN3NOW=EN3
EN4NOW=EN4
EN5NOW=EN5
EN6NOW=EN6
IF EN1NOW!=EN1PRE THEN
M1STATE=M1STATE+1
ENDIF
EN1PRE=EN1NOW
IF EN2NOW!=EN2PRE THEN
M2STATE=M2STATE+1
ENDIF
EN2PRE=EN2NOW
IF EN3NOW!=EN3PRE THEN
M3STATE=M3STATE+1
ENDIF
EN3PRE=EN3NOW
IF EN4NOW!=EN4PRE THEN
M4STATE=M4STATE+1
ENDIF
EN4PRE=EN4NOW
IF EN5NOW!=EN5PRE THEN
M5STATE=M5STATE+1
ENDIF
EN5PRE=EN5NOW
IF EN6NOW!=EN6PRE THEN
M6STATE=M6STATE+1
ENDIF
EN6PRE=EN6NOW
RETURN
'TMR0 INTERRUPT ROUTINE
'All motor movements are provided by this interrupt routine
'A PWM signal is created by using TMR0 timer and applied to
'motors, all PWM signals will be created by TMR0 for all movement types
kesme:
if walk_mode=0 then
duty1=150
duty0=(256-duty1)
if duty_check=0 then
duty_ctrl=1
M1A=1
M1B=M1POWER
M2A=M2POWER
M2B=1
M3A=1
M3B=M3POWER
M4A=M4POWER
M4B=1
M5A=1
M5B=M5POWER
M6A=M6POWER
M6B=1
TMR0=duty1
endif
if duty_check=1 then
duty_ctrl=0
M1A=0
M1B=0
M2A=0
M2B=0
M3A=0
M3B=0
M4A=0
M4B=0
M5A=0
M5B=0
M6A=0
M6B=0
TMR0=duty0
endif
endif
if duty_ctrl=1 then
duty_check=1
else
duty_check=0
endif
'INTCON.2=0
@ INT_RETURN
end
PS: Second code is compiling with MPASM as DT asks
Bookmarks