I am sorry Richar for having posted the file that is not the final one:
please change the following:
A VAR PORTD.0 ' encoder A PHASE
shAll be:
A VAR PORTB.0
This is the interrupt input !
I would be happy to know ...
Thanks and regards,
Ambrogio
I am sorry Richar for having posted the file that is not the final one:
please change the following:
A VAR PORTD.0 ' encoder A PHASE
shAll be:
A VAR PORTB.0
This is the interrupt input !
I would be happy to know ...
Thanks and regards,
Ambrogio
I did capture the output of the terminal printout for a better check.
There are about 200 changes of the cnt obtained by "manually" turning the encoder knob on my control panel. Probably sometims cw and ccw.
I noted very few spikes : I am not shure if they are due to the time required for the serial port output or to the encoder software.
Any improvement to the program is very much appreciated.
I am really searching for a good solution.
Thanks
regards,
Ambrogio
I do it this way
enc pins must be sequential and on same port
both enc pins must be able to generate an interrupt (ioc on neg and pos edge is best , ioc, rac,rbc on neg or pos edge will work as will int0 int1)
enc pins must be pulled up (10k) and have 0.1uF filter caps
I have an asm version that's 100 bytes smaller and has about 1 tenth of the irq latency and is much faster too
Code:'**************************************************************** '* Name : rotary encoder.BAS * '* Author : richard * '* Notice : Copyright (c) 2013 * '* : All Rights Reserved * '* Date : 9/4/2013 * '* Version : 1.0 16f1825 * '* Notes : enca porta.2 encb porta.3 * '* : note mclr disabled ,full quad decode * '**************************************************************** #CONFIG __config _CONFIG1, _FOSC_INTOSC & _CP_OFF & _WDTE_ON & _PWRTE_ON & _MCLRE_OFF & _CLKOUTEN_OFF __config _CONFIG2, _PLLEN_ON & _LVP_OFF #ENDCONFIG include "dt_ints-14.bas" include "REENTERPBP.bas" asm INT_LIST macro INT_HANDLER IOC_INT, _enc_isr,pbp,NO endm INT_CREATE ENDASM DEFINE OSC 32 OSCCON=$70 ANSELA=0 OPTION_REG.6=0 ev VAR BYTE bank0 cnt VAR WORD bank0 TMP VAR BYTE bank0 enca VAR porta.2 encb VAR porta.3 TRISA = 111110 lata.0=1 IOCAP=12 ;enca porta.2 encb porta.3 pos edge trigger IOCAN=12 ;enca porta.2 encb porta.3 neg edge trigger pause 4000 serout2 PORTA.0,84,[ "ready",13,10] IOCAF=0 INTCON=$C8 mainloop: serout2 PORTA.0,84,[13,10, "C",#CNT] pause 1000 goto mainloop enc_isr: ev=ev<<2 ;shift last reading into position ev=ev|((porta&12)>>2) ;read enc pins 2,3 mask off others then combine this reading with last reading LOOKUP (ev&$f),[0,255, 1, 0, 1, 0, 0, 255, 255, 0, 0, 1, 0, 1, 255, 0],tmp ;lookup the decision matrix if tmp then ; decide to inc , dec or ignore if tmp.7 then cnt=cnt-1 else cnt=cnt+1 endif endif intcon.0=0 ; clean up and exit iocaf=0 @ INT_RETURN
Thanks Richard for the code.
I am just a little bit busy on these days and so I plan to try your code on next days.
As you have seen I am using pic18f452: Is your code applicable to this micro ?
If no, what should I modify or adapt ?
Thanks
Regards,
Ambrogio
for a pic18f452 you need to use RBC_INT for best results and pins portb.4,5 or portb.6,7 or portb.5,6
this line needs to match chosen p1ns
for pins portb.4,5 it would beev=ev|((porta&12)>>2) ;read enc pins 2,3 mask off others then combine this reading with last reading
ev=ev|((portb&48)>>4)would beCode:INT_LIST macro INT_HANDLER IOC_INT, _enc_isr,pbp,NO endm INT_CREATE
Code:INT_LIST macro INT_HANDLER RBC_INT, _enc_isr,pbp,NO endm INT_CREATEwould beIOCAP=12 ;enca porta.2 encb porta.3 pos edge trigger
IOCAN=12 ;enca porta.2 encb porta.3 neg edge trigger
IOCAF=0
INTCON=$C8
dummy_var = portb
INTCON=$C8
any references to IOCAF need to be deleted , trisb must be appropiate
Hi Richard,
I am going to modify my previous program with your indications.
Probably I did something wrong and it is not working.
I am attaching the full code : could you please have a look of it ?
Thanks again for the assistance
regards,
Ambro
I would do it like this
Code:'**************************************************************** '* Name : pic controlled power supply * '* Author : [select VIEW...EDITOR OPTIONS] * '* Notice : Copyright (c) 2015 [select VIEW...EDITOR OPTIONS] * '* : All Rights Reserved * '* Date : 11/09/2015 * '* Version : 1.0 * '* Notes : pic18f452 10mhz x 4 pll = 40 MHZ * '**************************************************************** ';Program Configuration Register 1H @ __CONFIG _CONFIG1H, _OSCS_OFF_1H & _HSPLL_OSC_1H ';Program Configuration Register 2L @ __CONFIG _CONFIG2L, _BOR_OFF_2L & _BORV_20_2L & _PWRT_ON_2L ';Program Configuration Register 2H @ __CONFIG _CONFIG2H, _WDT_OFF_2H & _WDTPS_128_2H ';Program Configuration Register 3H @ __CONFIG _CONFIG3H, _CCP2MX_OFF_3H ';Program Configuration Register 4L @ __CONFIG _CONFIG4L, _STVR_OFF_4L & _LVP_OFF_4L & _DEBUG_OFF_4L ';Program Configuration Register 5L @ __CONFIG _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L & _CP2_OFF_5L & _CP3_OFF_5L ';Program Configuration Register 5H @ __CONFIG _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H ';Program Configuration Register 6L @ __CONFIG _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L & _WRT2_OFF_6L & _WRT3_OFF_6L ';Program Configuration Register 6H @ __CONFIG _CONFIG6H, _WRTC_OFF_6H & _WRTB_OFF_6H & _WRTD_OFF_6H ';Program Configuration Register 7L @ __CONFIG _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L & _EBTR2_OFF_7L & _EBTR3_OFF_7L ';Program Configuration Register 7H @ __CONFIG _CONFIG7H, _EBTRB_OFF_7H ' *************************************************************************** DEFINE OSC 40 ' XTAL= 10 MHZ CLOCK= 40 MHZ INCLUDE "MODEDEFS.BAS" include "dt_ints-14.bas" include "REENTERPBP.bas" CNT VAR WORD ' COUNTER TO BE DISPLAYED ON TERMINAL CNT= 32000 CNTOLD VAR WORD CNTOLD=32000 counter VAR WORD counter= 32000 ' DEBUG INTERFACE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ '' Set Debug pin port ________________________________________ DEFINE DEBUG_REG PORTD '' Set Debug pin bit _________________________________________ PIC_PIN_30 DEFINE DEBUG_BIT 7 '' Set Debug baud rate _________________________________________ DEFINE DEBUG_BAUD 115200 '' Set Debug mode: 0 = true, 1 = inverted ______________________ DEFINE DEBUG_MODE 1 DEBUG 13,10,13,10, " PROGRAM IS STARTING...", 13, 10, 13, 10 ADCON1=7 ' all digital ! ASM INT_LIST macro ; IntSource, Label, Type, ResetFlag? INT_Handler RBC_INT, _enc_isr, PBP, NO endm INT_CREATE ; Creates the interrupt processor ENDASM '@ INT_ENABLE RBC_INT ; enable external (INT) interrupts ev VAR BYTE BANK0 TMP VAR BYTE BANK0 enca VAR portb.4 encb VAR portb.5 TRISA = 255 lata.0=1 tmp = portb ;; read portb to establish pin change status INTCON=$C8 ; enable RBC_INT and clear rbcif Main: PAUSE 1000 gosub get_cnt: IF counter <> CNTOLD THEN DEBUG DEC CNT,13,10 CNTOLD=counter ENDIF GOTO Main enc_isr: ev=ev<<2 ;shift last reading into position ev=ev|((portb&48)>>4) ;read enc pins 4+5 mask off others then combine this reading with last reading LOOKUP (ev&$f),[0,255, 1, 0, 1, 0, 0, 255, 255, 0, 0, 1, 0, 1, 255, 0],tmp ;lookup the decision matrix if tmp then ; decide to inc , dec or ignore if tmp.7 then cnt=cnt-1 else cnt=cnt+1 endif endif intcon.0=0 ; clean up and exit @ INT_RETURN get_cnt: ; cnt is not atomic this is needed to avoid rollover miss reads intcon.3=0 counter=cnt intcon.3=1 return
Bookmarks