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