Here I post an update of the code posted in #18. This new code has a more efficient ISR so it can read at higher frequency. I don't know the maximum frequency that the system can acheive, so if someone with some spare time will give a try and post the result, could be useful.
As the previuos code, the mainloop doesn't do much, it simply update the display.
Here the code revised:
Code:
' PicBasic program to demonstrate how to read an optical encoder
' in quadrature. The code uses a 2 lines LCD in 4-bits mode
' **** MCU USED: PIC 16F628 ***
'
' ------------------ LCD should be connected as follows -------------------
' LCD PIC Port
' --- --------
' DB4 PortA.0
' DB5 PortA.1
' DB6 PortA.2
' DB7 PortA.3
' RS PortA.4 (add 4.7K pullup resistor to 5 volts)
' E PortB.0
' RW Ground
' Vdd 5 volts
' Vss Ground
' Vo 20K potentiometer (or ground)
' DB0-3 No connected
'-------------------------------------------------------------------------
' Encoder channel A PortB.6 (use pullups resistor if necessary)
' Encoder channel B PortB.7 (use pullups resistor if necessary)
' N/U PortB.0 (output)
' N/U PortB.1 (output)
' N/U PortB.2 (output)
' N/U PortB.3 (output)
' N/U PortB.4 (input - to be grounded)
' N/U PortB.5 (input - to be grounded)
'
'-------------------------------------------------------------------------
INCLUDE "DT_INTS-14.bas" ' Base Interrupt System (by Darrel Taylor)
DEFINE OSC 20
eeprom 0,[2,0,3,1,1,3,0,2]
Define LCD_DREG PORTA
Define LCD_DBIT 0
Define LCD_RSREG PORTA
define LCD_RSBIT 4
define LCD_EREG PORTB
define LCD_EBIT 0
define LCD_BITS 4
define LCD_LINES 2
define LCD_COMMANDUS 2000
define LCD_DATAUS 50
CMCON = %00000111
TrisA = %00000000
TrisB = %11110000
PortB = 0
Flag var bit
wsave VAR BYTE $70 SYSTEM ' alternate save location for W
Q_New var Byte
Q_Old var byte
M_Count var byte [4]
P_Count var byte [4]
Q_Count var word
' ---------------------- Set variable value @ startup ----------------------
For Q_Old = 0 to 3
Read Q_Old,M_Count[Q_Old]
Read Q_Old + 4,P_Count[Q_Old]
Next Q_Old
Q_Count = 0
Q_New = 0
Q_Old = 0
Flag = 0
ASM
INT_LIST macro ; IntSource, Label, Type, Resetflag?
INT_Handler RBC_INT, _Encoder, ASM, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
@ INT_ENABLE RBC_INT ; enable external (INT) interrupts
'---------------------------- Initialize LCD ----------------------------
Lcdout $fe, 1 ' Clear LCD screen
Lcdout "System Ready" ' Display message
Pause 500 ' Wait .5 second
Goto Main_Loop
Encoder: ' ISR
Q_New = PortB.7 + PortB.7 + PortB.6 ' get port status
If M_Count[Q_Old] = Q_New then ' if M_Count code satisfied then minus
Q_Count = Q_Count - 1
Flag = 1 ' set flag to true to update display
goto Q_Skip
endif
If P_Count[Q_Old] = Q_New then ' if M_Count code satisfied then plus
Q_Count = Q_Count + 1
Flag = 1 ' set flag to true to update display
endif
Q_Skip:
Q_Old = Q_New ' update Q_Old Byte
@ INT_RETURN
Main_Loop:
if Flag = 1 then
Lcdout $fe, 1 ' Clear LCD screen
lcdout dec Q_Count ' Display encoder position (counts)
Flag = 0 ' reset flag to false, display updated
endif
goto Main_Loop
end
Cheers
Al.
Bookmarks