if you do it more algorithmically the size can be reduced dramatically ,it becomes scalable digit wise
more functions can easily be added and the mcu can be employed to perform a real task like pid control of a power supply and not just become a display controller
ps note my lcd defines suite my setup and are different
Code:'**************************************************************** '* Name : LCD_TEST.BAS * '* Author : RICHARD * ' '* Date : 4/8/2017 * '* Version : 1.0 * '* Notes : * '* : 16f887 * '**************************************************************** #CONFIG __CONFIG _CONFIG1, _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_ON & _CPD_OFF & _CP_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _INTOSCIO __CONFIG _CONFIG2, _WRT_OFF & _BOR40V #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 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-1] 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_sw var PORTC.4 enc_a var portc.5 enc_b var portc.6 clear d_index = num_digits re = porta&48 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 = portc&96 if re != last_re then ;encoder has moved ev=ev<<2 ;shift old reading into position for compare ev=ev|((portc&96)>>5) ;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],tmp1 ;lookup the decision matrix to determine rotation endif ;service encoder result if there is one if tmp1 && 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 tmp1 = 255 then gosub dec_digit else gosub inc_digit endif endif gosub dup tmp1 = 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 if tmp1 = 1 then LCDOUT ".", digit[tmp1]+$30 else LCDOUT digit[tmp1]+$30 endif wend gosub SUM_TOTALS LCDOUT $FE, $80, dec5 total set_cursor: ;update cursor if d_index == num_digits then LCDOUT $FE,$0C elseif d_index > 1 then LCDOUT $FE,$0f,$fe,$94 + (num_digits - 1) - d_index else LCDOUT $FE,$0f,$fe,$94 + num_digits - d_index endif return inc_digit: ;inc current digit d_inx = d_index gosub norollu ;optional if noroll_flg then ;optional digit[d_index] = digit[d_index] + 1 gosub chk_ovf while overflow digit[d_inx] = 0 d_inx = d_inx + 1 if d_inx >= num_digits then return gosub norollu ;optional if noroll_flg then ;optional digit[d_inx] = digit[d_inx] + 1 gosub chk_ovf endif ;optional wend endif ;optional return chk_ovf: ;check if overflow occured overflow = 0 if digit[d_inx] > 9 then overflow = 1 return chk_unf: ;check if underflow occured underflow = 0 if digit[d_inx] > 127 then underflow = 1 return dec_digit: ;decrement current digit d_inx = d_index gosub norolld ;optional if noroll_flg then ;optional digit[d_index] = digit[d_index] - 1 gosub chk_unf while underflow digit[d_inx] = 9 d_inx= d_inx + 1 if d_inx >= num_digits then return gosub norolld ;optional if noroll_flg then ;optional digit[d_inx] = digit[d_inx] - 1 gosub chk_unf endif ;optional wend endif ;optional 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 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