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:
CheersCode:' 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
Al.





Bookmarks