Code:
	'*******************************************************************************
;*  Name    : PIC16F887.BAS                                    
;*  Author  : CSANTEX                                 
;*  Date    :                                  
;*  Version : DEFAULT                                               
;*  Notes   :
'*******************************************************************************
;Max Word count available is 8192.  Max EEPROM available is 256 bytes
;*******************************************************************************
;This code displays a number that is incremented for clockwise rotation or decrements
;for counter-clockwise rotation on a 20x4 LCD.  The display has two digits to the
;left of the decimal and three digits to the right of the decimal.  Each time the
;shaft is pushed in, a digit is selected starting from left to right.  This code
;could be used to display voltages that are preset by a user on a diy power supply
;or for Ampere presets or any of the like.
;The code is a bit long but it works well.
;***This work was derrived from the thread "New Approach to Rotary Encoder", based on sample code
;submitted by Ioannis
;COULD USE SOME OPTIMIZATION!
;*******************************************************************************
;*******************************************************************************
'	include	"PIC16F887.PBPINC"	; processor specific variable definitions
    INCLUDE "Modedefs.Bas" 
    @ ERRORLEVEL -306   ; Suppress messages related to Page Boundries.
;*******************************************************************************
    #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
       
    DEFINE LCD_DREG PORTD  ' PORTA is LCD data port 
    DEFINE LCD_DBIT 4  ' PORTA.4 is the data LSB ( 4 BIT MODE ) 
    DEFINE LCD_RSREG PORTB  ' RS is connected to PORTA.1 
    DEFINE LCD_RSBIT 0 
    DEFINE LCD_EREG PORTB  ' E is connected to PORTA.3
    DEFINE LCD_EBIT 1 
    DEFINE LCD_BITS 4  ' 4 lines of data are used (4 BITS)
    DEFINE LCD_LINES 4  ' It is a 4-line display 
    DEFINE LCD_COMMANDUS 1500 ' Use 1500uS command delay 
    DEFINE LCD_DATAUS 44   ' Use 44uS data delay
;*******************************************************************************
    OSCCON  = %01110000     ; Set PIC16F88 to 4MHz = %01100000, or
                            ; 8MHz = %01110000
    TRISA   = %11111111     ; Port A set to inputs
    TRISB   = %11101100     ; Port B set to OUTPUTS
    TRISC   = %01111111     ; Port C set to inputs
    TRISD   = %00000000     ; Port D set to Ouputs
    PORTD.5 = 0             ; Set output low
    ANSEL   = %00000000     ; Set all analog pins to digital
    ANSELH  = %00000000
'    LED            var     PortD.7      ; LED for flashing
    A_IN           VAR     PORTC.6
    B_IN           VAR     PORTC.5
    SW_IN          VAR     PORTC.4
;*******************************************************************************
    ONES            VAR BYTE    ; VARIABLE
    TENS            VAR BYTE    ; VARIABLE
    HUND            VAR BYTE    ; VARIABLE
    THOU            VAR BYTE    ; VARIABLE
    TNTH            VAR BYTE    ; VARIABLE
    SUBTTL          VAR WORD    ; VARIABLE
    TOTAL           VAR WORD    ; TOTAL VALUE
    PLACE           VAR BYTE    ; VARIABLE
    MYFLAGS         VAR BYTE
;*******************************************************************************
;*******************************************************************************
;*******************************************************************************
;*******************************************************************************        
;*******************************************************************************
;*******************************************************************************
;*******************************************************************************
;******************************************************************************* 
INIT: 
    PAUSE 1000
    CLEAR
    PLACE = 6    
'    LCDOUT $FE, $C0, DEC PLACE    ;FOR DEBUG ONLY
'    LCDOUT $FE, $94, DEC5 (TNTH*10000)+(THOU*1000)+(HUND*100)+(TENS*10)+ONES   ;FOR DEBUG ONLY
    LCDOUT $FE, $D4, DEC1 TNTH, DEC1 THOU, ".", DEC1 HUND, DEC1 TENS, DEC1 ONES
MAIN:
    IF A_IN < B_IN THEN
        IF PLACE = 6 AND TOTAL < 10000 THEN
            IF MYFLAGS.0 = 0 THEN 
                ONES = ONES + 1
                IF ONES > 9 THEN 
                    ONES = 0
                    TENS = TENS + 1 
                ENDIF                    
                IF TENS > 9 THEN 
                    TENS = 0
                    HUND = HUND + 1 
                ENDIF                        
                IF HUND > 9 THEN
                    HUND = 0
                    THOU = THOU + 1 
                ENDIF 
                IF THOU > 9 THEN
                    THOU = 0
                    TNTH = TNTH + 1 
                ENDIF                           
                IF TNTH > 1 THEN THOU = 0 
                GOSUB SHOW_TOTAL 
            ENDIF 
        ENDIF
        IF MYFLAGS.0 = 1 THEN
            IF TNTH = 0 THEN 
                IF PLACE = 5 THEN  
                    ONES = ONES + 1
                    IF ONES > 9 THEN ONES = 0
                    GOSUB SHOW_ONES
                ENDIF    
                IF PLACE = 4 THEN 
                    TENS = TENS + 1
                    IF TENS > 9 THEN TENS = 0
                    GOSUB SHOW_TENS
                ENDIF    
                IF PLACE = 3 THEN  
                    HUND = HUND + 1
                    IF HUND > 9 THEN HUND = 0 
                    GOSUB SHOW_HUND
                ENDIF    
                IF PLACE = 1 THEN  
                    THOU = THOU + 1
                    IF THOU > 9 THEN THOU = 0
                    GOSUB SHOW_THOU
                ENDIF
            ENDIF
            IF SUBTTL = 0 THEN     
                IF PLACE = 0 THEN
                    TNTH = TNTH + 1
                    IF TNTH > 1 THEN TNTH = 0
                    GOSUB SHOW_TNTH
                    GOTO PUSHBUTTON
                ENDIF
            ENDIF
        ENDIF    
        GOSUB SUM_TOTALS
        IF TOTAL = 10000 THEN 
            LCDOUT $FE, $0C  ;BLINK OFF
            LCDOUT $FE, $80, "MAXIMUM LIMIT"
            PAUSE 1000
            LCDOUT $FE, $80, "             "
        ENDIF        
    ENDIF 
    
PUSHBUTTON:
    IF SW_IN = 0 THEN 
        PLACE = PLACE + 1
        IF PLACE = 2 THEN PLACE = 3 
        IF PLACE > 6 THEN PLACE = 0 
'        LCDOUT $FE, $C0, DEC PLACE    ;FOR DEBUG ONLY
        LCDOUT $FE, $D4+PLACE
        
        IF PLACE = 6 THEN 
            LCDOUT $FE, $0C  ;BLINK OFF
            MYFLAGS.0 = 0
        ELSE
            LCDOUT $FE, $0F
            LCDOUT $FE, $D4+PLACE
            MYFLAGS.0 = 1
        ENDIF  
               
        GOSUB DEBOUNCE  ;DO NOTHING WHILE WE WAIT TO RELEASE THE BUTTON.         
    ENDIF
    GOSUB SUM_TOTALS        
    IF PLACE != 6 THEN  
        LCDOUT $FE, $0F
        LCDOUT $FE, $D4+PLACE
'        MYFLAGS.0 = 1
    ENDIF  
DECREMENT:
    IF B_IN < A_IN THEN 
        IF PLACE = 6 AND TOTAL > 0 THEN
            IF MYFLAGS.0 = 0 THEN
                ONES = ONES - 1   
                IF ONES > 9 THEN 
                    ONES = 9  
                    TENS = TENS - 1
                ENDIF
                IF TENS > 9 THEN 
                    TENS = 9                     
                    HUND = HUND - 1 
                ENDIF             
                IF HUND > 9 THEN 
                    HUND = 9                  
                    THOU = THOU - 1 
                ENDIF      
                IF THOU > 9 THEN 
                    THOU = 9
                    TNTH = TNTH - 1
                ENDIF
                IF TNTH > 1 THEN THOU = 0  
                GOSUB SHOW_TOTAL 
            ENDIF
        ENDIF
        IF MYFLAGS.0 = 1 THEN
            IF TNTH = 0 THEN 
                IF PLACE = 5 THEN  
                    ONES = ONES - 1
                    IF ONES > 9 THEN ONES = 9
                    GOSUB SHOW_ONES
                    GOTO MAIN
                ENDIF      
                IF PLACE = 4 THEN  
                    TENS = TENS - 1
                    IF TENS > 9 THEN TENS = 9 
                    GOSUB SHOW_TENS
                    GOTO MAIN
                ENDIF    
                IF PLACE = 3 THEN  
                    HUND = HUND - 1
                    IF HUND > 9 THEN HUND = 9
                    GOSUB SHOW_HUND
                    GOTO MAIN
                ENDIF    
                IF PLACE = 1 THEN  
                    THOU = THOU - 1
                    IF THOU > 9 THEN THOU = 9
                    GOSUB SHOW_THOU
                    GOTO MAIN
                ENDIF
            ENDIF 
            IF SUBTTL = 0 THEN       
                IF PLACE = 0 THEN
                    TNTH = TNTH - 1
                    IF TNTH > 1 THEN TNTH = 1
                    GOSUB SHOW_TNTH
                    GOTO MAIN
                ENDIF
            ENDIF
        ENDIF  
        GOSUB SUM_TOTALS
        IF TOTAL = 0 THEN 
            LCDOUT $FE, $0C  ;BLINK OFF
            LCDOUT $FE, $80, "MINIMUM LIMIT"
            PAUSE 1000
            LCDOUT $FE, $80, "             "
        ENDIF     
    ENDIF 
    GOTO MAIN
    
SHOW_TOTAL: 
'    LCDOUT $FE, $94, DEC5 (TNTH*10000)+(THOU*1000)+(HUND*100)+(TENS*10)+ONES    ;FOR DEBUG ONLY
    LCDOUT $FE, $D4, DEC1 TNTH, DEC1 THOU, ".", DEC1 HUND, DEC1 TENS, DEC1 ONES     
DEBOUNCE:    
    WHILE A_IN=0 OR B_IN=0 OR SW_IN=0   ;DO NOTHING WHILE WE WAIT TO RELEASE THE BUTTON.
    WEND
    RETURN 
;******************************************************************************* 
SHOW_TNTH:
    LCDOUT $FE, $0C ;BLINK OFF
    LCDOUT $FE, $D4, DEC1 TNTH
    LCDOUT $FE, $D4
    LCDOUT $FE, $0F ;BLINK ON
    GOSUB DEBOUNCE  ;DO NOTHING WHILE WE WAIT TO RELEASE THE BUTTON.
    RETURN
SHOW_THOU:
    LCDOUT $FE, $0C ;BLINK OFF
    LCDOUT $FE, $D5, DEC1 THOU
    LCDOUT $FE, $D5
    LCDOUT $FE, $0F
    GOSUB DEBOUNCE  ;DO NOTHING WHILE WE WAIT TO RELEASE THE BUTTON.
    RETURN
SHOW_HUND:
    LCDOUT $FE, $0C ;BLINK OFF
    LCDOUT $FE, $D7, DEC1 HUND
    LCDOUT $FE, $D7
    LCDOUT $FE, $0F
    GOSUB DEBOUNCE  ;DO NOTHING WHILE WE WAIT TO RELEASE THE BUTTON.
    RETURN
SHOW_TENS:
    LCDOUT $FE, $0C ;BLINK OFF
    LCDOUT $FE, $D8, DEC1 TENS
    LCDOUT $FE, $D8
    LCDOUT $FE, $0F
    GOSUB DEBOUNCE  ;DO NOTHING WHILE WE WAIT TO RELEASE THE BUTTON.
    RETURN
SHOW_ONES:
    LCDOUT $FE, $0C ;BLINK OFF
    LCDOUT $FE, $D9, DEC1 ONES
    LCDOUT $FE, $D9
    LCDOUT $FE, $0F
    GOSUB DEBOUNCE  ;DO NOTHING WHILE WE WAIT TO RELEASE THE BUTTON.
    RETURN
SUM_TOTALS:
    TOTAL = (TNTH*10000)+(THOU*1000)+(HUND*100)+(TENS*10)+ONES
    SUBTTL = (THOU*1000)+(HUND*100)+(TENS*10)+ONES
    RETURN
;******************************************************************************* 
  
;*******************************************************************************
    END
 
				
Bookmarks