moved enc to porta 234 on 16f648a, reduced nesting by two levels
now works
Code:
'****************************************************************
'* Name : LCD_TEST.BAS *
'* Author : RICHARD *
'
'* Date : 4/8/2017 *
'* Version : 1.0 *
'* Notes : *
'* : 16f648a *
'****************************************************************
#CONFIG
__config _HS_OSC & _WDT_ON & _PWRTE_OFF & _MCLRE_ON & _BODEN_ON & _LVP_OFF & _CP_OFF
#ENDCONFIG
DEFINE OSC 8
'LCD defines begin here
DEFINE LCD_BITS 4 'defines the number of data interface lines (4 or 8)
DEFINE LCD_DREG PORTB 'defines the port where data lines are connected to
DEFINE LCD_DBIT 0 'defines the position of data lines for 4-bit interface (0 or 4)
DEFINE LCD_RSREG PORTB 'defines the port where RS line is connected to
DEFINE LCD_RSBIT 4 'defines the pin where RS line is connected to
DEFINE LCD_EREG PORTB 'defines the port where E line is connected to
DEFINE LCD_EBIT 5 'defines the pin where E line is connected
DEFINE LCD_COMMANDUS 1500 'defines the delay after LCDOUT statement
DEFINE LCD_DATAUS 50 'delay in micro seconds
'END of LCD DEFINES
DEFINE LCD_LINES 4
cmcon=7
Pause 500 ' LCD initialize time
lcdout $FE,1
num_digits con 5 ; range 4 t0 9 tested ok note sum_total will not work for more than 5 digits
sw_threshhold con 10
lp_threshhold con 100 ;long press
sw_inhibit_time con 100
msd_limit con 5 ;limit value for msd note sum_total will not work for more than 5 digits and limit > 5 ;optional
digit var byte[num_digits]
d_index var byte
overflow var bit
underflow var bit
noroll_flg var bit ;optional
d_inx var byte
sw_cnt var byte
sw_flag var bit
re var byte
last_re var byte
ev var byte
tmp1 var byte
tmp2 var byte ;optional
tmp3 var byte ;optional
sw_inhibit var byte
total var word
enc_act var byte
enc_sw var PORTa.4
enc_a var porta.2
enc_b var porta.3
clear
d_index = num_digits
re = porta&12
last_re = re
gosub dup
main:
if !sw_inhibit then gosub chk_sw
if sw_flag then ;service the sw if active
if sw_cnt > lp_threshhold then ;long press clears settings
for d_index = 0 to (num_digits-1)
digit[d_index] = 0
next
gosub dup
else
d_index = d_index - 1 ;increment set digit {index posn 6 will stop editing of settinge}
if d_index > num_digits then d_index = num_digits
gosub set_cursor
sw_inhibit = sw_inhibit_time ; don't reactivate sw immediately [more user friendly]
endif
sw_cnt = 0
sw_flag = 0
endif
;poll encoder a poll rate of 5-10ms is adequate
re = porta&12
if re != last_re then ;encoder has moved
last_re = re ; this line fell off pic18 version
ev=ev<<2 ;shift old reading into position for compare
ev=ev|((porta&12)>>2) ;read enc pins 4,5 mask off others then combine this reading with last reading
;lookup table is a form of digital filter to debounce encoder [no caps used on encoder at all]
LOOKUP (ev&$f),[0,255, 1, 0, 1, 0, 0, 255, 255, 0, 0, 1, 0, 1, 255, 0],enc_act ;lookup the decision matrix to determine rotation
endif
;service encoder result if there is one
if enc_act && (re == 0) then ; tmp1 255 is anticlockwise or 1 for clockwise [swap a/b pins if direction incorrect]
if d_index != num_digits then
if enc_act = 255 then
d_inx = d_index
gosub norolld ;optional
if noroll_flg then ;optional
digit[d_index] = digit[d_index] - 1
underflow = 0
if digit[d_inx] > 127 then underflow = 1
while underflow
underflow = 0
digit[d_inx] = 9
d_inx= d_inx + 1
if d_inx < num_digits then
gosub norolld ;optional
if noroll_flg then ;optional
digit[d_inx] = digit[d_inx] - 1
if digit[d_inx] > 127 then underflow = 1
endif ;optional
endif
wend
endif ;optional
else
d_inx = d_index
gosub norollu ;optional
if noroll_flg then ;optional
digit[d_index] = digit[d_index] + 1
overflow = 0
if digit[d_inx] > 9 then overflow = 1
while overflow
overflow = 0
digit[d_inx] = 0
d_inx = d_inx + 1
if d_inx < num_digits then
gosub norollu ;optional
if noroll_flg then ;optional
digit[d_inx] = digit[d_inx] + 1
if digit[d_inx] > 9 then overflow = 1
endif ;optional
endif
wend
endif ;optional
endif
gosub dup
endif
enc_act = 0
endif
;service sw inhibit if necessary
if sw_inhibit then sw_inhibit = sw_inhibit - 1 ; [make sw action more user friendly]
pause 5 ;adjust to suite desired responsiveness or more functions in loop
goto main
dup: ;update lcd
LCDOUT $FE, $94
tmp1=num_digits
while tmp1
tmp1=tmp1-1
tmp2 = digit[tmp1]+$30
if tmp1 = 1 then
LCDOUT ".", tmp2
else
LCDOUT tmp2
endif
wend
gosub SUM_TOTALS
LCDOUT $FE, $80, dec5 total
set_cursor: ;update cursor
if d_index == num_digits then
LCDOUT $FE,$0C
else
tmp2 = $94 + num_digits - d_index
if d_index > 1 then tmp2=tmp2-1
LCDOUT $FE,$0f,$fe,tmp2
endif
return
chk_sw: ;see if switch is active
if sw_flag then return
if !enc_sw then
if sw_cnt < 255 then sw_cnt = sw_cnt + 1
else
if sw_cnt > sw_threshhold then
sw_flag = 1
else
sw_cnt=0
endif
endif
return
norolld: ; stop rollunder from 0000.00 to 9999.99 ;optional
tmp3=digit[d_inx] ;optional
noroll_flg=0 ;optional
for tmp2=(d_inx+1) to (num_digits -1) ;optional
tmp3=tmp3+digit[tmp2] ;optional
next ;optional
if tmp3 then noroll_flg = 1 ;optional
return ;optional
norollu: ; stop rollover from 9999.99 to 0000.00 and limit msd
noroll_flg=0 ;optional
if d_inx < (num_digits -1) then ;optional
tmp3=9-digit[d_inx] ;optional
for tmp2=(d_inx+1) to (num_digits -2) ;optional
tmp3=tmp3+(9-digit[tmp2] ) ;optional
next ;optional
tmp3=tmp3+(msd_limit-digit[tmp2] ) ;optional
else ;optional
tmp3=msd_limit-digit[d_inx] ;optional
endif ;optional
if tmp3 then noroll_flg = 1 ;optional
return ;optional
SUM_TOTALS: ;max digit is 5 and max_msd = 5 or else result will overflow
tmp1=num_digits
total=0
while tmp1
tmp1=tmp1-1
total=total*10
total=total+digit[tmp1]
wend
return
Bookmarks