I made this schematic; I use this code. Works fine, but.... I don't know how to display "minus sign" for negative temperatures. I try differents variants, but without results...Any advice it's wellcome ! Thanks in advance !
Code:
' *************************************************************
' * For use with EXPERIMENTING WITH THE PICBASIC PRO COMPILER *
' * *
' * This source code may be freely used within your own *
' * programs. However, if it is used for profitable reasons, *
' * please give credit where credit is due. *
' * And make a reference to myself or Rosetta Technologies *
' * *
' * Les. Johnson *
' *************************************************************
'
' Common Anode seven segment display multiplexer
' Displays the contents of the variable D_NUMBER on five common Anode displays
' using a TMR0 interrupt
' ***********************************************************************
@ DEVICE pic16F648A, XT_OSC, WDT_OFF, PWRT_OFF, BOD_OFF, MCLR_OFF, LVP_OFF, CPD_OFF
CMCON = 7
VRCON = 0
INTCON = 0
Include "Modedefs.bas"
' ** Setup the Crystal Frequency, in mHz **
Define OSC 4 ' Set Xtal Frequency
' ** 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
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 PortA.0 ' Controls the first DIGIT on the LED
Digit1 Var PortA.1 ' Controls the second DIGIT on the LED
Digit2 Var PortA.2 ' Controls the third DIGIT on the LED
Digit3 Var PortA.3 ' Controls the fourth DIGIT on the LED
temperature var word
TempC Var word
Temp Var byte
Float Var word
V Var word
Twist Var bit
Dummy Var byte
Sign var byte
busy var bit
DS18B20_12bit CON %01111111 ' 750ms, 0.0625°C
DQ var PortA.4
' ** 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)
' 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=0 ' Set the prescaler
PS1=1 ' to increment TMR0
PS2=0 ' every 64th 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
TrisB=0 ' Make PortB outputs
TrisA.0=0:TrisA.1=0:TrisA.2=0 ' Make only the specific bits of PortA outputs
TrisA.3=0:TrisA.4=1
PortA=0:PortB=0 ' Clear PortB and PortA
O_C=0 ' Clear the time share variable
OWOut DQ, 1, [$CC, $4E, 0, 0, DS18B20_12bit]
Output DQ ' Make Pin Output
DQ=0 ' OneWire line Low
PauseUs 480 ' Keep down for 480 µS
Input DQ ' Make Pin Input
PauseUs 70 ' Wait 70 µS
W1:
OWIN DQ,4,[busy] ' Check for still busy converting
IF busy = 0 THEN W1 ' Still busy? then loop
' ** THE MAIN PROGRAM STARTS HERE **
Main:
OWOut DQ, 1, [$CC, $44]
OWOut DQ, 1, [$CC, $BE]
OWIn DQ, 2, [temperature.byte0, temperature.byte1]
If Temperature.15 then
Temperature= ~Temperature +1
Twist = 1
Sign = 1
Endif
Dummy = 625 * Temperature
TempC = DIV32 10
TempC = (Temperature & $7FF) >> 4
Float = ((Temperature.Lowbyte & $0F ) * 25 )>>2
Temperature = TempC*100 + Float
If Twist then
V= 10000 - Temperature ' 25 C=12500 0 C=10000 -10 C=9000
Twist = 0
else
V= 10000 + Temperature
EndIf
If V >= 10000 then ' Above 0 C.
Temperature=V-10000
sign = " "
else
Temperature=10000-V ' Below 0 C.
sign= "-"
EndIf
D_Number=Temperature/10 ' Place the value to display into D_NUMBER
DP=0 ' Disable the decimal point
Gosub Display ' Display the value
For Del=0 to 100 ' Pause 10ms
Pauseus 100 ' using smaller delays
Next
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=3 to 0 step -1 ' Loop for 4 digits (0-9999)
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
Enable ' Re-enable the interrupt
Next
' INTERRUPT HANDLER
' Multiplexes the 4-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
Digit3=0 ' Turn OFF the fourth LED
PortB=Disp_Patt ' Place the digit pattern on portC
If DP=1 then PortB.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
PortB=Disp_Patt ' Place the digit pattern on portC
If DP=2 then PortB.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
PortB=Disp_Patt ' Place the digit pattern on portC
If DP=3 then PortB.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
PortB=Disp_Patt ' Place the digit pattern on portC
If DP=3 then PortB.7=0 ' Check the value of DP and Turn ON the decimal point
Digit3=1 ' Turn ON the fourth LED
Endif
O_C=O_C+1 ' Increment the time share counter
If O_C>=4 then O_C=0 ' If it reaches 4 or over then clear it
T0IF=0 ' Reset TMR0 interrupt flag
Resume ' Exit the interrupt
Enable ' Allow more interrupts
Bookmarks