' Program 5CA_DISP.BAS
' Common Anode seven segment display multiplexer
' Displays the contents of the variable D_NUMBER on five common Anode displays
' using a TMR0 interrupt every 1.6ms (assuming a 20mHz oscillator)
' ***********************************************************************

	Include "Modedefs.Bas"
    
' ** Setup the Crystal Frequency, in mHz **

	Define 	OSC		20		' Set Xtal Frequency

' ** Declare the Variables **

	AD_Result	Var	Word		' 10-bit result of A/D conversion

' ** Setup the ADCIN Defines **

	Define	ADC_BITS	10		' Set resolution of conversion
	Define	ADC_CLOCK	0		' Set clock source (x/FOSC)
	Define	ADC_SAMPLEUS	10	' Set sampling time (in uS)
	
    
' ** Declare the Variables **
	LEDS		Var	Byte		' The amount of LEDs in the display 
	O_C		    Var	Byte		' Used by the interrupt for time sharing
	Counter		Var	Word		' General purpose counter
	Del		    Var	Word		' General purpose delay loop variable
	D_Number	Var	Word        ' The number to display on the LEDS 2
    DP		    Var	Byte		' Position of the decimal point
	Disp_Patt	Var	Byte		' Pattern to output to PortC
	Num		    Var	Byte[5]		' Array to hold each digits value
	Digit0		Var	PortB.0		' Controls the first DIGIT on the LED
	Digit1		Var	PortB.1		' Controls the second DIGIT on the LED
	Digit2		Var	PortB.2		' Controls the third DIGIT on the LED
	Digit3		Var	PortB.3		' Controls the fourth DIGIT on the LED
	Digit4		Var	PortB.4		' Controls the fifth DIGIT on the LED
    convert     var word
    Result      var word
    SETUP       VAR PortA.1     ' Led de indicacion de ajuste
    HEAT        var PortA.5     ' Salida 
    LTEMP       VAR PortB.5     ' Pulsador Baja temperatura
    HTEMP       VAR PortB.6     ' Puldasor Aumenta temperatura
    PAD         VAR PortB.7     ' Pulsador para entrar a ajuste
    SETPOINT    VAR WORD
    MINTEMP     VAR WORD
    MAXTEMP     VAR WORD
 
' ** Define the bits within the ADCON1 register **

	ADFM		Var	ADCON1.7	' ADC result format select bit
	PCFG3		Var	ADCON1.3	' ADC port configuration bit
	PCFG2		Var	ADCON1.2	' ADC port configuration bit
	PCFG1		Var	ADCON1.1	' ADC port configuration bit
	PCFG0		Var	ADCON1.0	' ADC port configuration bit    

' ** Declare the bits and flags of the various registers **

	T0IE		Var	INTCON.5	' Timer0 Overflow Interrupt Enable
	T0IF		Var	INTCON.2	' Timer0 Overflow Interrupt Flag
	GIE		    Var	INTCON.7	' Global Interrupt Enable
	PS0		    Var	OPTION_REG.0	' Prescaler division bit-0
	PS1		    Var	OPTION_REG.1	' Prescaler division bit-1
	PS2		    Var	OPTION_REG.2	' Prescaler division bit-2
	PSA		    Var	OPTION_REG.3	' Prescaler Assignment (1= assigned to WDT)
						'		       (0= assigned to oscillator)
	T0CS		Var	OPTION_REG.5	' Timer0 Clock Source Select (0=Internal clock) 
						'			     (1=External PORTA.4)
' ** THE MAIN PROGRAM STARTS HERE **

' Set TMR0 to interrupt
	GIE=0					' Turn off global interrupts
	While GIE=1:GIE=0:Wend	' Make sure they are off
	PSA=0					' Assign the prescaler to external oscillator
	PS0=1					' Set the prescaler
	PS1=0					' to increment TMR0
	PS2=0					' every 32nd instruction cycle
	T0CS=0					' Assign TMR0 clock to internal source
	TMR0=0					' Clear TMR0 initially
	T0IE=1					' Enable TMR0 overflow interrupt
	GIE=1					' Enable global interrupts

        On Interrupt Goto Mult_Int		' Point to the interrupt handler

	TrisC=0:TrisB=%11111000	' Make PortB and PortC outputs
	portC=0:portB=0		             'limpia  puertob
	O_C=0					' Clear the time share variable 
	
	MINTEMP=200
	
	PCFG0=0
	PCFG1=1
	PCFG2=1
	PCFG3=1					' Configure for AN0 as analogue input

	ADFM=1					' Right justified result in ADRESL and ADRESH
	

main:  ADCIN 0, CONVERT

    RESULT=(CONVERT*2)/4
	D_Number=RESULT			' Place the value to display into D_NUMBER
	DP=0					' Disable the decimal point
	Gosub Display           ' Display the value 
 	 Pauseus 10				' using smaller delays
 	 gosub calienta
 	 gosub set
 	
       
 	 
 	 
 	 
	 	 
 	 
 	 
 	 
INF: Goto Main				' Do it forever


' Build up the seperate digits of variable D_NUMBER
' into the array NUM. Each LED is assigned to each array variable.
' LED-0 (right) displays the value of NUM[0]
' LED-1 (middle) displays the value of NUM[1]
' LED-2 (lef) displays the value of NUM[2]
' The decimal point is placed by loading the variable DP
' with the LED of choice to place the point (0..5). where 1 is the farthest right LED
' and 0 disables the decimal point. 
Display:
	For LEDS=4 to 0 step -1 			' Loop for 5 digits (0-65535)
	Disable						' Disable the interrupt while we calculate
	Num[LEDS]=D_Number dig LEDS 			' Extract the seperate digits into the array
	If D_Number<10 and LEDS=1 then Num[LEDS]=10	' Zero Suppression for the second digit
	If D_Number<100 and LEDS=2 then Num[LEDS]=10	' Zero Suppression for the Third digit
	If D_Number<1000 and LEDS=3 then Num[LEDS]=10	' Zero Suppression for the Forth digit
	If D_Number<10000 and LEDS=4 then Num[LEDS]=10	' Zero Suppression for the Fifth digit
	Enable						' Re-enable the interrupt
	Next	


' INTERRUPT HANDLER 
' Multiplexes the 5-digits
' 
     disable            			' Disable all interupts during the interrupt handler
Mult_Int: 
	Lookup Num[O_C],[192,249,164,176,153,146,131,248,128,152,255],Disp_Patt ' Decode the segments for the LED
' Process the first display (farthest right)
	If O_C=0 then				' If it is our turn then
	Digit4=0				' Turn OFF the fifth LED
	PortC=Disp_Patt				' Place the digit pattern on portC
	If DP=1 then PortC.7=0			' Check the value of DP and Turn ON the decimal point
	Digit0=1				' Turn ON the first LED
	Endif
' Process the second display
	If O_C=1 then				' If it is our turn then
	Digit0=0				' Turn OFF the first LED
	PortC=Disp_Patt				' Place the digit pattern on portC
	If DP=2 then PortC.7=0			' Check the value of DP and Turn ON the decimal point
	Digit1=1				' Turn ON the second LED
	Endif
' Process the third display
	If O_C=2 then				' If it is our turn then
	Digit1=0				' Turn OFF the second LED
	PortC=Disp_Patt				' Place the digit pattern on portC
	If DP=3 then PortC.7=0			' Check the value of DP and Turn ON the decimal point
	Digit2=1				' Turn ON the third LED
	Endif
' Process the fourth display
	If O_C=3 then				' If it is our turn then
	Digit2=0				' Turn OFF the third LED
	PortC=Disp_Patt				' Place the digit pattern on portC
	If DP=4 then PortC.7=0			' Check the value of DP and Turn ON the decimal point
	Digit3=1				' Turn ON the fourth LED
	Endif
' Process the fifth display (leftmost display)
	If O_C=4 then				' If it is our turn then
	Digit3=0				' Turn OFF the fourth LED
	PortC=Disp_Patt				' Place the digit pattern on portC
	If DP=5 then PortC.7=0			' Check the value of DP and Turn ON the decimal point
	Digit4=1				' Turn ON the fifth LED
	Endif

	O_C=O_C+1				' Increment the time share counter
	If O_C>=5 then O_C=0			' If it reaches 5 or over then clear it

	T0IF=0    				' Reset TMR0 interrupt flag
        Resume					' Exit the interrupt
	enable					' Allow more interrupts
	
CALIENTA:if result<200 then 
        high HEAt
        pause 10
        low heat
        pause 10
        endif
      
      
      
SET: if pad=0 then
    high setup
    pause 10
    low setup
    pause 10 
        
    setpoint=mintemp
           
    d_number=setpoint
    gosub Display
    dp=0
    
    IF LTEMP=0 THEN
    GOSUB MINUS
    endif
    
    IF HTEMP=0 THEN
    GOSUB MAST
    ENDIF
    
    
    ENDIF
    if pad=1 then gosub main
    gosub set
    
MAST: MINTEMP=(MINTEMP+5)
      RETURN 
    
MINUS: MINTEMP=(MINTEMP-5)
       RETURN    

