View Full Version : Probe to read quadrature encoder with DT_INT need help
phoenix_1
- 30th August 2009, 11:47
When I compile MCSP return next error's (compile with MPASM).
PBP 2.50C
Procesor 16F877 @ 20MHz.
ERROR's:
error[128]877 qei.asm 87 : Missing argument(s)
error[118]877 qei.asm 87 : Overwriting previus address contents (2007)
@ __config & _WDT_ON & _PWRTE_OFF & _BODEN_ON & _LVP_OFF & _CP_OFF & _DATA_CP_OFF
'@ Device pic16F877, HS_OSC, BOD_ON, PWRT_OFF, WDT_ON, PROTECT_OFF
Define osc 20
DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
DEFINE HSER_SPBRG 64 ' 19200 Baud @ 20MHz, 0.16%
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
ADCON1 = 7
old_val VAR BYTE
new_val VAR BYTE
direction_bit VAR BIT
enc_counter VAR WORD
enc_counter = 10000
new_val = PORTB & %00000011
TRISB = %00000011
INCLUDE "DT_INTS-14-0.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP-0.bas" ' Include if using PBP interrupts
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler INT_INT, _QEI, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
@ INT_ENABLE INT_INT ; enable external (INT) interrupts
rs232:
pause 1
goto rs232
QEI:
old_val = new_val
new_val = PORTB & %00000011
IF new_val = old_val Then again
direction_bit = old_val.bit0 ^ new_val.bit1
IF direction_bit = 1 Then
enc_counter = enc_counter + 1
else
enc_counter = enc_counter - 1
endif
hserout [dec enc_counter]
again:
@ INT_RETURN
aratti
- 30th August 2009, 13:55
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler INT_INT, _QEI, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
_QEI label ; PBP and yes not correctly allined. Change as per the following
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler INT_INT, _QEI, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
Al.
phoenix_1
- 30th August 2009, 14:03
@ __config & _WDT_ON & _PWRTE_OFF & _BODEN_ON & _LVP_OFF & _CP_OFF & _DATA_CP_OFF
'@ Device pic16F877, HS_OSC, BOD_ON, PWRT_OFF, WDT_ON, PROTECT_OFF
Define osc 20
DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
DEFINE HSER_SPBRG 64 ' 19200 Baud @ 20MHz, 0.16%
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
ADCON1 = 7
old_val VAR BYTE
new_val VAR BYTE
direction_bit VAR BIT
enc_counter VAR WORD
enc_counter = 10000
new_val = PORTB & %00000011
TRISB = %00000011
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 RBC_INT, _LED, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
@ INT_ENABLE INT_INT ; enable external (INT) interrupts
rs232:
pause 1
goto rs232
LED:
old_val = new_val
new_val = PORTB & %00000011
IF new_val = old_val Then again
direction_bit = old_val.bit0 ^ new_val.bit1
IF direction_bit = 1 Then
enc_counter = enc_counter + 1
else
enc_counter = enc_counter - 1
endif
hserout [dec enc_counter]
again:
@ INT_RETURN
PBP 2.47 , 250 or 250C in all version same errors ???
can you edit and post my code full please sir?
Acetronics2
- 30th August 2009, 15:17
Hi,
Your error is double ...
1)
@ __config & _WDT_ON & _PWRTE_OFF & _BODEN_ON & _LVP_OFF & _CP_OFF & _DATA_CP_OFF
do not use " & " before the first data : WDT_ON ...
2)
You have to comment the CONFIG lines already existing in your 16F877 .inc file ( PBP folder ) if you want custom ones ... see FAQ for details.
Alain
phoenix_1
- 30th August 2009, 15:25
Acetronics your help is 100% work.
Thank's many thanks man.
And one question more...how DT interupt can be fast ?
Acetronics2
- 30th August 2009, 17:58
And one question more...how DT interupt can be fast ?
Hi,
I do not know exactly ...
but it's roughly the time to save and restore all the PBP variables in use, added to the "classic" ASM interrupts time ...
You can Use the MPLAB SIM ... You will have a very good idea !
Alain
phoenix_1
- 30th August 2009, 20:10
DT_INT with TIMER_1 and led blink work 100% on 16f877 when I test it but:
define OSC 20
ADCON1 = 7
TRISB = %00000011
INTCON = %10001000
LED1 VAR PORTA.0
LED2 VAR PORTA.1
LOW LED1
low LED2
INCLUDE "DT_INTS-14.bas"
INCLUDE "ReEnterPBP.bas"
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler RBC_INT, _TEST, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
@ INT_ENABLE RBC_INT
Main:
PAUSE 1
GOTO Main
'---[RBC_INT - interrupt handler]------------------------------------------
TEST:
high led1
high led2
@ INT_RETURN
Dont want to work for me...why ?
Acetronics2
- 30th August 2009, 20:20
Just try PortB.7 and PortB.6 ...
and read the '877 Databook , Interrupts section :
WHICH are the 4 pins that create "interrupts on change" ???
HOW to avoid the " Mismatch condition " ???
Alain
phoenix_1
- 30th August 2009, 21:14
These code count pulses from one pin of quadrature encoder good and fast.
It use RB0 INT very good.
Now I need idea to implement full reading quadrature encoder A and B inputs with count of pulses and direction indication..
Encoder is with 500 pulses per full revolution.
How - need idea..?
Procesor 16F877 @ 20MHz
define OSC 20
DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
DEFINE HSER_SPBRG 64 ' 19200 Baud @ 20MHz, 0.16%
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
ADCON1 = 7
TRISB = %00000011
a var word
a = 0
INTCON = %10010000 ; Enable INTE RB0 interrupt $90
INCLUDE "DT_INTS-14.bas"
INCLUDE "ReEnterPBP.bas"
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler INT_INT, _TEST, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
Main:
if a >= 5000 then
a = 0
endif
hserout [ dec a ]
pause 100
GOTO Main
'---[INT_INT - interrupt handler]------------------------------------------
TEST:
a = a + 1
@ INT_RETURN
Regards Robert :rolleyes:
aratti
- 30th August 2009, 22:51
Connect encoder channel A to portB.0 (I assume you already have it) and channel B to portB.1. Since channel A is out of phase on channel B turning your encoder CW channel A will be high before channel B and turning it CCW channel B will be high first.
In your interrupt handler check the above conditions
If portB & %00000011 = 1 Then
a = a + 1
CW = 1
Else
a = a - 1
CW = 0
Endif
If variable CW is 1 then your motor is turning clockwise if CW = 0 then is turning counterclockwise, while word variable a will contain the updated count.
Al.
aratti
- 31st August 2009, 06:38
I have forgotten to say, in my previuos post, that the code snippet is not a quadrature count, and it counts only channel A, while Channel B is used only for direction. So total count per encoder turn will be n/2.
To get a quadrature count you need to detect the rising and falling edges of the square waves, thing that is not possible with the pic you have in use. To obtain the quadrature count you either need additional external logic or you have to choose a pic with the quadrature counter. (Much easier)
Al.
phoenix_1
- 31st August 2009, 20:43
I have forgotten to say, in my previuos post, that the code snippet is not a quadrature count, and it counts only channel A, while Channel B is used only for direction. So total count per encoder turn will be n/2.
To get a quadrature count you need to detect the rising and falling edges of the square waves, thing that is not possible with the pic you have in use. To obtain the quadrature count you either need additional external logic or you have to choose a pic with the quadrature counter. (Much easier)
Al.
Yes I was buy today 18F4431 for start...
But there is 400 pages of datasheet and I need to be a WIZARD to SETUP that PIC :D
Regards Robert:p
Powered by vBulletin® Version 4.1.7 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.