You must be trying to set the configuration fuses more than once.
In the PBP part of the code?
In the ASM part?
In the *.inc file?
http://www.picbasic.co.uk/forum/showthread.php?t=543
You must be trying to set the configuration fuses more than once.
In the PBP part of the code?
In the ASM part?
In the *.inc file?
http://www.picbasic.co.uk/forum/showthread.php?t=543
Dave
Always wear safety glasses while programming.
Again -
I think you would be FAR better off if you would just use Darrel's code as a starting point. Since you have two priorities, you need to put the following in your DEFINE block.
DEFINE USE_LOWPRIORITY 1
Then use Darrel's INCLUDE files as needed.
INCLUDE "DT_INTS-18.bas" ; Base Interrupt System
INCLUDE "ReEnterPBP-18.bas" ; Include if using PBP interrupts
INCLUDE "ReEnterPBP-18LP.bas" ; Include if using Low Pr. PBP INTS
Then define your variables in PBP. If you have enough space, you can define all of them as BankA SYSTEM. If you don't, make certain that you define all the ones that you want to pass between PBP and ASM as bankA System
The variables will be case-sensitive.
Set up all timer prescalers, clock sources and triggering edges first.
Now put in Darrel's interrupt control block -
Change the labels as necessary.
Hopefully, I haven't forgotten something. !Code:ASM INT_LIST macro ; IntSource, Label, Type, ResetFlag? INT_Handler TMR0_INT, SystemTimer, ASM, yes INT_Handler RX1_INT, _GetCharPort1, PBP, yes endm INT_CREATE ; Creates the interrupt processor INT_LIST_L macro ; IntSource, Label, Type, ResetFlag? INT_Handler PIC_YOUR_INT, StepperControl, ASM,no endm INT_CREATE_L ; Creates the Low Priority interrupt processor ENDASM Goto OverInt ------------------------------------------ ASM (Put all your ASM ISR code here) @ INT_RETURN ENDASM ------------------------------------------- [Put all your PBP ISR code here] @ INT_RETURN --------------------------------------------- Overint: (Clear INT flags) @ INT_ENABLE (name of INT) @ INT_ENABLE (name of other INT) @ INT_ENABLE (name of other INT) NothingLoop: Goto NothingLoop ; do nothing until you get an int.
Doing things this way will not only likely get you to a running program much faster, it will make it easier for others to give you the help you need. After all, this IS a PBP forum, not an ASM forum.
Charles Linquist
Hi Bill,
I like to encourage everyone to learn assembly, and how to handle interrupts. Where would we be here if DT never learned assembly or interrupts...;o)
Here's a simple modified version of what you had. Look at the changes I made VS your original. I could point to every single change,
but it wouldn't help you learn much.
I think you're much better off putting both interrupts in the same handler, and just checking for which one caused the interrupt VS having a high pri interrupt your low pri, so you can use the auto restore for W, STATUS & BSR.Code:;****************************************************************************** LIST P=18F8722 ; Directive to define processor #include "P18F8722.inc" ; Drocessor specific variable definitions ;****************************************************************************** ; Configuration bits CONFIG OSC = HSPLL ; Run at 4X speed CONFIG CP0=OFF ; Disable code protect CONFIG PWRT = OFF ; Power up timer off so DEBUG works CONFIG WDT=OFF ; WDT off CONFIG LVP = OFF ; LVP off CONFIG WAIT = OFF ; External bus data wait disabled ;****************************************************************************** ; Variable definitions in data memory CBLOCK 0x0000 ; all in ACCESS RAM Count_pulse ; Loop delay in 5 uS pulse to motor driver X_delay : 2 ; Inter-pulse delay for X axis, 2 bytes Y_delay : 2 ; Inter-pulse delay for Y axis, 2 bytes X_steps : 2 ; Number of steps to do on X axis, 2 bytes ENDC ;****************************************************************************** ; Reset vector in program memory ORG 0x0000 goto Main_ASM ; Go to start of main code ;****************************************************************************** ; All interrupts vector to here, Priorities disabled ORG 0x0008 bra Tmr_ints ; Go to interrupt routine ;****************************************************************************** ;****************************************************************************** ; Higher priority for Timer0 overflows, send out stepper ; drive pulse for X axis on PORTD.0 Tmr_ints btfss INTCON,TMR0IF ; did Timer0 interrupt? bra LowPri ; no. branch to Timer1 int bsf PORTD,0 ; yes. High PORTD.0 call Pulse_out ; Send 5uS pulse on PORTB.0 bcf PORTD,0 ; Low PORTD.0 (Timer1 interrupts around here) bcf INTCON,TMR0IF ; Clear Timer0 interrupt flag movff X_delay+1,TMR0H ; Load timer0 with X_delay high byte movff X_delay,TMR0L ; Load timer0 with X_delay low byte movf X_steps,W ; load WREG for compare after subtraction decf X_steps,F ; Decrement X_steps low byte cpfslt X_steps ; if X_steps < WREG then jump over next decrement decf X_steps+1 ; else, decrement high byte ; Lower priority for Timer1 overflows, send out stepper ; drive pulse for Y axis on PORTD.3 LowPri btfss PIR1,TMR1IF ; Timer1 int pending? bra IntExit ; no. exit bsf PORTD,3 ; High PORTD.3 call Pulse_out ; Delay for 10 microseconds bcf PORTD,3 ; High PORTD.3 bcf PIR1,TMR1IF ; Clear Timer1 interrupt flag movff Y_delay+1,TMR1H ; Load Timer1 with Y_delay high byte movff Y_delay,TMR1L ; Load timer1 with Y_delay low byte IntExit retfie FAST ; return & restore WREG, STATUS, BSR ;****************************************************************************** * ; SUBROUTINES * * ;****************************************************************************** Pulse_out ; Delay = 3.n + 7 [0.1 microseconds] movlw 0xff ; Load w with n movwf Count_pulse ; Load Count with n Pulse_loop decfsz Count_pulse ; Decrament the file Count goto Pulse_loop ; Loop if not zero return ;****************************************************************************** * ; MAIN ASM * * ;****************************************************************************** Main_ASM clrf TRISA ; PORTA is output clrf TRISB ; PORTB is output clrf TRISC ; PORTC is output clrf TRISD ; PORTD is output clrf TRISE ; PORTE is output clrf TRISF ; PORTF is output clrf TRISG ; PORTG is output clrf TRISH ; PORTH is output clrf TRISJ ; PORTJ is output clrf PORTA ; Clear PORTA clrf PORTB ; Clear PORTB clrf PORTC ; Clear PORTC clrf PORTD ; Clear PORTD clrf PORTE ; Clear PORTE clrf PORTF ; Clear PORTF clrf PORTG ; Clear PORTG clrf PORTH ; Clear PORTH clrf PORTJ ; Clear PORTJ movlw 0x0f movwf ADCON1 ; PORTA is digital I/O movlw 0x07 movwf CMCON ; Comparator off ; Set up interrupt conditions for Timer0 and Timer1 bcf RCON,7 ; disable priority levels on interrupts,IPEN=0 bsf INTCON,7 ; Enable all interrupts bsf INTCON,6 ; Enable all peripheral interrupts bcf INTCON,3 ; Disable PORTB interrupts bcf INTCON2,2 ; Make Timer0 overflow low priority bcf IPR1,0 ; Make Timer1 overflow low priority bsf INTCON,5 ; Enable Timer0 overflow int bsf PIE1,0 ; Enable Timer1 overflow int ; Set up Timer0 conditions bcf T0CON,6 ; Timer0 uses 16 bits bcf T0CON,5 ; Timer0 uses internal osc bcf T0CON,4 ; Timer0 count on rising edge og osc bsf T0CON,3 ; Timer0 pre-scaler not assigned clrf TMR0H ; Zero the clock clrf TMR0L ; Zero the clock bsf T0CON,7 ; Timer0 on ; Set up Timer1 conditions bsf T1CON,7 ; Timer1 uses 16 bits bcf T1CON,1 ; Timer1 uses internal osc clrf TMR1H ; Zero the clock clrf TMR1L ; Zero the clock bsf T1CON,0 ; Timer1 on ; Temp code to simmulate PBP input for the delays clrf X_delay ; this handles the low byte clrf X_delay+1 ; this handles the high byte clrf Y_delay clrf Y_delay+1 clrf X_steps clrf X_steps+1 ; End of Temp code ; Check if X_steps_lb=0 (decremented in high priority interrupt) ; If so, check X_steps_hb and if zero, end ; If not, decrement X_steps_hb, set X_steps_lb and go again Main_loop movff X_steps+1,PORTC ; high byte to portc ;btg PORTC,1 ; toggle RC1 (note: comf only works with whole 8-bit registers) movff X_steps,PORTD ; low byte to portd ;btg PORTD,1 ; toggle RD1 tstfsz X_steps ; Test, skip next if zero goto Main_loop ; More steps to do, so loop tstfsz X_steps+1 ; Test, skip next if zero bra Re_load_lb goto All_done Re_load_lb decf X_steps+1,F ; Decrement hb and then carry to lb setf X_steps ; Decremented hb, so load ff to lb goto Main_loop All_done bcf INTCON,7 ; Clear GIE, disable ALL interrupts clrwdt sleep goto $-2 end
Bruce,
Wow, what a lot of effort on your part - thanks very much. I will now re-fire up MPLAB and give it a detailed run.
I do take note of CL's comments about this being a PICBASIC site but most entheuastic PBP users will want to experiment with ASM - for fun and speed?
I know that every minuit I've spent on ASM in MPLAB had added greatly to my ability to write software in PBP.
Perhaps there is space for an 'ASM' sub-section in this forum? I can understand that most newcomers will not be interested in this lower level stuff but it seems essential to make the most of PBP.
We are in the middle of a heatwave here in West Australia - almost no rain for 3 months - too hot to do much outside so plenty of key-board time.
Thanks again for your input.
Regards Bill Legge
My goal was not to discourage ASM use (I use a lot of it myself), but only to point out that DT_INTs would make things easier for you. And since a lot of people on this forum are familiar with their use, a lot more people would be able to help you if you chose that route.
Charles Linquist
Charles & Bruce,
Thanks for your help.
Bruce: the code you provided works well and I've tested it in MPLAB with a variety of inputs and it's all OK.
I have 'glued it into PBP and still can't get it to compile. The things I changed between the ASM_only and PBP_ASM are:
1. Deleted the .asm CONFIGS because they come from my programmer.
2. Deleted the .asm variable definitions in data memory, defined them in PBP, watched out for caes sensitivity and changed the .asm definitions to have a leading underscore (e.g. _X_steps).
SORRY, I HIT THE WRONG BUTTON BEFORE I HAD COMPLETED THE POST
PLEASE READ ON..........
Charles & Bruce,
Thanks for your help.
Bruce: the code you provided works well and I've tested it in MPLAB with a variety of inputs and it's all OK.
I have 'glued' it into PBP and still can't get it to compile. The things I changed between the 'ASM only' and 'PBP_ASM' are:
1. Deleted the .asm CONFIGS because they come from my programmer.
2. Deleted the .asm variable definitions in data memory, defined them in PBP, watched out for caes sensitivity and changed the .asm definitions to have a leading underscore (e.g. _X_steps).
3. Took out the .asm PORT and TRIS lines because it's done in PBP.
4. Took out the temp code to load the variables because they should come from PBP.
5. Deleted the last 3 lines of code - not needed I presume?
My, failed attempt to get the PBP to run looks like:
You used a .asm technique of defining a data address like:Code:' File...... 8722 Scan_ASM_Test ' Purpose... Drive two steppers to achieve diagonal moves ' ***************************************************************************** ' * * ' * INCLUDE & DEFINES * ' * * ' ***************************************************************************** clear define OSC 40 ' Use HSPLL during compilation ' ***************************************************************************** ' * * ' * VARIABLES * ' * * ' ***************************************************************************** X_steps var word ' Steps to move, not reusable Count_pulse var WORD Bank0 System ' Pulse duration = 3.n + 7 X_delay var WORD Bank0 System Y_delay var WORD Bank0 System goto Start ' Skip over ASM code ' ***************************************************************************** ' * * ' * ASSEMBLER CODE * ' * * ' ***************************************************************************** Run_ASM: ASM LIST P=18F8722 ; Directive to define processor #include "P18F8722.inc" ; Drocessor specific variable definitions ; Reset vector in program memory ORG 0x0000 goto Main_ASM ; Go to start of main code ;****************************************************************************** ; All interrupts vector to here in program memory, Priorities disabled ; This is high priority only so wsave etc is automatic ORG 0x0008 bra Tmr_ints ; Go to interrupt routine ;****************************************************************************** ; Higher priority for Timer0 overflows, send out stepper ; drive pulse for X axis on PORTD.0 Tmr_ints btfss INTCON,TMR0IF ; did Timer0 interrupt? bra LowPri ; no. branch to Timer1 int bsf PORTD,0 ; yes. High PORTD.0 call Pulse_out ; Call delay routine bcf PORTD,0 ; Low PORTD.0 bcf INTCON,TMR0IF ; Clear Timer0 interrupt flag movff _X_delay+1,TMR0H ; Load timer0 with _X_delay high byte movff _X_delay,TMR0L ; Load timer0 with _X_delay low byte decf _X_steps,F ; Decrement X_steps low byte ; Lower priority for Timer1 overflows, send out stepper ; drive pulse for Y axis on PORTD.3 LowPri btfss PIR1,TMR1IF ; Timer1 int pending? bra IntExit ; no. exit bsf PORTD,3 ; High PORTD.3 call Pulse_out ; Call delay routine bcf PORTD,3 ; High PORTD.3 bcf PIR1,TMR1IF ; Clear Timer1 interrupt flag movff _Y_delay+1,TMR1H ; Load Timer1 with Y_delay high byte movff _Y_delay,TMR1L ; Load timer1 with Y_delay low byte IntExit retfie FAST ; return & restore WREG, STATUS, BSR ;****************************************************************************** * ; SUBROUTINES * * ;****************************************************************************** Pulse_out ; Delay = 3.n + 7 [0.1 microseconds] movlw 0xff ; Load w with n movwf _Count_pulse ; Load Count with n Pulse_loop decfsz _Count_pulse ; Decrament the file Count goto Pulse_loop ; Loop if not zero return ;****************************************************************************** * ; MAIN ASM * * ;****************************************************************************** Main_ASM ; Set up interrupt conditions for Timer0 and Timer1 bcf RCON,7 ; Disable priority levels on interrupts,IPEN=0 bsf INTCON,7 ; Enable all interrupts bsf INTCON,6 ; Enable all peripheral interrupts bcf INTCON,3 ; Disable PORTB interrupts bcf INTCON2,2 ; Make Timer0 overflow low priority bcf IPR1,0 ; Make Timer1 overflow low priority bsf INTCON,5 ; Enable Timer0 overflow int bsf PIE1,0 ; Enable Timer1 overflow int ; Set up Timer0 conditions bcf T0CON,6 ; Timer0 uses 16 bits bcf T0CON,5 ; Timer0 uses internal osc bcf T0CON,4 ; Timer0 count on rising edge og osc bsf T0CON,3 ; Timer0 pre-scaler not assigned clrf TMR0H ; Zero the clock clrf TMR0L ; Zero the clock bsf T0CON,7 ; Timer0 on ; Set up Timer1 conditions bsf T1CON,7 ; Timer1 uses 16 bits bcf T1CON,1 ; Timer1 uses internal osc clrf TMR1H ; Zero the clock clrf TMR1L ; Zero the clock bsf T1CON,0 ; Timer1 on ; Temp code to simulate PBP input for the delays ; Removed - should come from PBP ; Check if X_steps_lb=0 (decremented in high priority interrupt) ; If so, check X_steps_hb and if zero, end ; If not, decrement X_steps_hb, set X_steps_lb and go again Main_loop movff _X_steps+1,PORTJ ; Steps hi to PORTJ movff _X_steps,PORTB ; Steps lo to PORTB tstfsz _X_steps ; Test steps lo, skip next if zero goto Main_loop ; More steps to do, so loop tstfsz _X_steps+1 ; Test steps hi, skip next if zero bra Re_load_lb goto All_done Re_load_lb decf _X_steps+1,F ; Decrement hb and then carry to lb setf _X_steps ; Decremented hb, so load ff to lb goto Main_loop All_done bcf INTCON,7 ; Clear GIE, disable ALL interrupts clrwdt ENDASM RETURN ' ***************************************************************************** ' * * ' * INITIALISE * ' * * ' ***************************************************************************** Start: ADCON1 = %00001101 ' A0, A1 analog, rest digital CMCON = %00000111 ' Comparators off, this frees up PORTF TRISA = %00000000 TRISB = %00000000 TRISC = %00000000 TRISD = %00000000 ' D.0 is X drive. D.3 is Y drive TRISE = %00000000 ' LEDs to display X_steps lo byte TRISF = %00000000 TRISG = %00000000 TRISH = %00000000 TRISJ = %00000000 ' LEDs to display X_steps hi byte ' ***************************************************************************** ' * * ' * MAIN * ' * * ' ***************************************************************************** Main: X_delay = $FFFF Y_delay = $FFFF X_steps = $FFFF Count_pulse = $FFFF gosub Run_ASM pause 100 goto Main end
_X_delay : 2 ; Reserve two bytes in data memory
If I have a variable in PBP like
X_delay VAR WORD
Will the WORD from PBP find it's way to the .asm?
Charles L: I'm still going to do it using DT's interrupts
Regards Bill Legge
Bookmarks