PDA

View Full Version : Thermo 7 segments - little problem



fratello
- 22nd January 2010, 12:33
Hello !
I intend to make one digital thermometer, this time using a 7 segments display. I use code from my previous thermometer and from this forum for interfacing PIC with display. Unfortunate on display I have only "0". I think I made some mistakes in variables statements, but I need little help....Thanks in advance for every reply.

mehmetOzdemir
- 22nd January 2010, 14:31
if you are using isis for simulation , it is hard to scanning displays.

it doesnt work properly when displays are scanning.

fratello
- 22nd January 2010, 15:35
Yes, I use ISIS... It's this a problem ?! I wrote another code, with the same results : "000" on display. Both (wrong) results are because of simulation ? Thanks for reply !

mehmetOzdemir
- 22nd January 2010, 17:50
i wrote some codes below it worked on isis.



SEGMENT_A VAR PORTB.3
SEGMENT_B VAR PORTB.7
SEGMENT_C VAR PORTB.0
SEGMENT_D VAR PORTA.3
SEGMENT_E VAR PORTA.2
SEGMENT_F VAR PORTB.2
SEGMENT_G VAR PORTB.1
DP VAR PORTB.6

BASAMAK_0 VAR PORTA.1
BASAMAK_1 VAR PORTA.7
BASAMAK_2 VAR PORTA.0
BASAMAK_3 VAR PORTA.6

DQ VAR PORTB.5



TEMP VAR BYTE
I VAR BYTE
SIGN VAR BIT




ISI VAR WORD ; TEMPERATURE REGISTER
COUNT_REMAIN VAR BYTE






MASK_0 VAR BYTE
MASK_1 VAR BYTE
MASK_2 VAR BYTE
MASK_3 VAR BYTE




CMCON = 7

OUTPUT SEGMENT_A
OUTPUT SEGMENT_B
OUTPUT SEGMENT_C
OUTPUT SEGMENT_D
OUTPUT SEGMENT_E
OUTPUT SEGMENT_F
OUTPUT SEGMENT_G
OUTPUT DP

OUTPUT BASAMAK_0
OUTPUT BASAMAK_1
OUTPUT BASAMAK_2
OUTPUT BASAMAK_3




SEGMENT_A = 0
SEGMENT_B = 0
SEGMENT_C = 0
SEGMENT_D = 0
SEGMENT_E = 0
SEGMENT_F = 0
SEGMENT_G = 0
DP = 0

BASAMAK_0 = 1 ; DISPLAYS 1. DIGIT
BASAMAK_1 = 1 ; DISPLAYS 2. DIGIT
BASAMAK_2 = 1 ; DISPLAYS 3. DIGIT
BASAMAK_3 = 1 ; DISPLAYS 4. DIGIT

MAIN :

OWOUT DQ ,1,[$CC,$44]

BEKLE :


GOSUB EKRAN_0

FOR I = 0 TO 4
GOSUB TARA
NEXT I

OWIN DQ ,4,[COUNT_REMAIN]

IF COUNT_REMAIN = 0 THEN
GOTO BEKLE
ENDIF

OWOUT DQ ,1,[$CC,$BE]
OWIN DQ ,0,[ISI.LOWBYTE , ISI.HIGHBYTE]

IF ISI.15 = 1 THEN
ISI = (65535 - ISI) + 1
SIGN = 1
ELSE
SIGN = 0
ENDIF
ISI = (ISI * 10)/16



GOTO MAIN



EKRAN_0 : ; TRANSFER THE REGISTERS TO DIPLAY

MASK_3 = ISI DIG 3
MASK_2 = ISI DIG 2

IF SIGN = 1 THEN
MASK_3 = " "
MASK_2 = "-"
ENDIF

MASK_1 = ISI DIG 1
MASK_0 = ISI DIG 0

RETURN




TARA : ; SCAN THE DISPLAYS

TEMP = MASK_3 : GOSUB TABLO
BASAMAK_3 = 0 : PAUSE 1 : BASAMAK_3 = 1

'************************************************* ***************
'************************************************* ***************

TEMP = MASK_2 : GOSUB TABLO
BASAMAK_2 = 0 : PAUSE 1 : BASAMAK_2 = 1

'************************************************* ***************
'************************************************* ***************

TEMP = MASK_1 : GOSUB TABLO
BASAMAK_1 = 0 : DP = 1 : PAUSE 1 : BASAMAK_1 = 1 : DP = 0

'************************************************* ***************
'************************************************* ***************

TEMP = MASK_0 : GOSUB TABLO
BASAMAK_0 = 0 : PAUSE 1 : BASAMAK_0 = 1



RETURN




TABLO : ; TABLE , CONVERTS THE DATAS TO 7 SEGMENT CODE

SELECT CASE TEMP

CASE 0
SEGMENT_A = 1
SEGMENT_B = 1
SEGMENT_C = 1
SEGMENT_D = 1
SEGMENT_E = 1
SEGMENT_F = 1
SEGMENT_G = 0

CASE 1
SEGMENT_A = 0
SEGMENT_B = 1
SEGMENT_C = 1
SEGMENT_D = 0
SEGMENT_E = 0
SEGMENT_F = 0
SEGMENT_G = 0

CASE 2
SEGMENT_A = 1
SEGMENT_B = 1
SEGMENT_C = 0
SEGMENT_D = 1
SEGMENT_E = 1
SEGMENT_F = 0
SEGMENT_G = 1

CASE 3
SEGMENT_A = 1
SEGMENT_B = 1
SEGMENT_C = 1
SEGMENT_D = 1
SEGMENT_E = 0
SEGMENT_F = 0
SEGMENT_G = 1

CASE 4
SEGMENT_A = 0
SEGMENT_B = 1
SEGMENT_C = 1
SEGMENT_D = 0
SEGMENT_E = 0
SEGMENT_F = 1
SEGMENT_G = 1

CASE 5
SEGMENT_A = 1
SEGMENT_B = 0
SEGMENT_C = 1
SEGMENT_D = 1
SEGMENT_E = 0
SEGMENT_F = 1
SEGMENT_G = 1

CASE 6
SEGMENT_A = 1
SEGMENT_B = 0
SEGMENT_C = 1
SEGMENT_D = 1
SEGMENT_E = 1
SEGMENT_F = 1
SEGMENT_G = 1

CASE 7
SEGMENT_A = 1
SEGMENT_B = 1
SEGMENT_C = 1
SEGMENT_D = 0
SEGMENT_E = 0
SEGMENT_F = 0
SEGMENT_G = 0

CASE 8
SEGMENT_A = 1
SEGMENT_B = 1
SEGMENT_C = 1
SEGMENT_D = 1
SEGMENT_E = 1
SEGMENT_F = 1
SEGMENT_G = 1

CASE 9
SEGMENT_A = 1
SEGMENT_B = 1
SEGMENT_C = 1
SEGMENT_D = 1
SEGMENT_E = 0
SEGMENT_F = 1
SEGMENT_G = 1

CASE "-"
SEGMENT_A = 0
SEGMENT_B = 0
SEGMENT_C = 0
SEGMENT_D = 0
SEGMENT_E = 0
SEGMENT_F = 0
SEGMENT_G = 1

CASE "h"
SEGMENT_A = 0
SEGMENT_B = 0
SEGMENT_C = 1
SEGMENT_D = 0
SEGMENT_E = 1
SEGMENT_F = 1
SEGMENT_G = 1

CASE "o"
SEGMENT_A = 0
SEGMENT_B = 0
SEGMENT_C = 1
SEGMENT_D = 1
SEGMENT_E = 1
SEGMENT_F = 0
SEGMENT_G = 1

CASE "b"
SEGMENT_A = 0
SEGMENT_B = 0
SEGMENT_C = 1
SEGMENT_D = 1
SEGMENT_E = 1
SEGMENT_F = 1
SEGMENT_G = 1

CASE " "
SEGMENT_A = 0
SEGMENT_B = 0
SEGMENT_C = 0
SEGMENT_D = 0
SEGMENT_E = 0
SEGMENT_F = 0
SEGMENT_G = 0

END SELECT

RETURN



some register names and label are written in turkish. i tried to comment them to english.

there is no transistors to drive diplays.

if your version is same with my isis , it will work.

all files in attachment.

fratello
- 22nd January 2010, 18:11
Thank You verry much for support ! ...My ISIS is Release 7.4 SP3, and Your code (copy/paste/compiling, because the zip file is empty !) DON'T WORK !!!
Verry strange :( ... PIC and statements are the same ?

mehmetOzdemir
- 22nd January 2010, 18:17
i refreshed the zip file download again.

fratello
- 22nd January 2010, 18:42
:) You use CC, I use AC... Yes, of course that Your code works ! Great ! I will try now the "live" schematic ! Wish me luck !
Thank You, again ! All the best !

fratello
- 22nd January 2010, 20:46
...a little problem : don't display value under -9.9 'C ! For -10.0 'C the display show - 0,0 'C. Now, in my town, outside is -12'C !!! (brrrrrrr...)

mehmetOzdemir
- 22nd January 2010, 21:18
ok. i understood the problem . we will shift the "-" string 1 step left.

change the "ekran_0" label with below ;



ekran_0 : ; transfer the registers to diplay

mask_3 = isi dig 3

if sign = 1 then
mask_3 = "-"
endif

mask_2 = isi dig 2
mask_1 = isi dig 1
mask_0 = isi dig 0

return

fratello
- 16th February 2010, 17:57
I made the thermometer, using the code from Mr.Mehmet - Thanks ! I use common cathode LED display. But..., with the schematic from Mr.Mehmet , the display have flicker...It' one good ideea to use transistors for cathodes, like in picture ? It's correct ? (In ISIS dont work ! :( ) It's this one solution for "flicker free" ? Thanks in advance for reply !

fratello
- 4th May 2010, 19:02
I re-write the code posted by Mehmet (Thanks !) , because I intend to use interrupts. On ISIS work ...fine (little flicker ?!) . But...I wonder if the code it's right. I re-re-read MCSE help about using interrupts...and, of course, any advice it's wellcome. Thanks in advance !
'************************************************* ********
'* *
'* Termometru 7 segmente *
'* cu intreruperi *
'* *
'************************************************* ********
@ DEVICE pic16F628A, intOSC_osc_noclkout, WDT_OFF, PWRT_ON, MCLR_OFF, LVP_OFF, CPD_OFF, PROTECT_OFF

DEFINE NO_CLRWDT 1
DEFINE OSC 4

TRISA= %11110000 ' RA0..3=Outputs RA4...7=Input
TRISB= %00000000 ' RB0..RB7=Outputs
CMCON=7 ' Disable comparators


SEGMENT_A VAR PORTB.0
SEGMENT_B VAR PORTB.1
SEGMENT_C VAR PORTB.2
SEGMENT_D VAR PORTB.3
SEGMENT_E VAR PORTB.4
SEGMENT_F VAR PORTB.5
SEGMENT_G VAR PORTB.6
DP VAR PORTB.7

CATOD_0 VAR PORTA.0
CATOD_1 VAR PORTA.1
CATOD_2 VAR PORTA.2
CATOD_3 VAR PORTA.3

DQ VAR PORTA.4


OPTION_REG = %10000000


Temp var byte
DS18B20_12bit CON %01111111 ' 750ms, 0.0625°C
Temperature Var Word
TempC Var Word
I Var Byte
Sign Var Bit
Count_remain var Byte
Float Var Word
V Var Word ' Var. for display
Twist Var Bit
Dummy Var Byte
Busy var BIT ' Busy Status-Bit

DIGIT_0 VAR BYTE
DIGIT_1 VAR BYTE
DIGIT_2 VAR BYTE
DIGIT_3 VAR BYTE

OUTPUT SEGMENT_A
OUTPUT SEGMENT_B
OUTPUT SEGMENT_C
OUTPUT SEGMENT_D
OUTPUT SEGMENT_E
OUTPUT SEGMENT_F
OUTPUT SEGMENT_G
OUTPUT DP
OUTPUT CATOD_0
OUTPUT CATOD_1
OUTPUT CATOD_2
OUTPUT CATOD_3

SEGMENT_A = 0
SEGMENT_B = 0
SEGMENT_C = 0
SEGMENT_D = 0
SEGMENT_E = 0
SEGMENT_F = 0
SEGMENT_G = 0
DP = 0

CATOD_0 = 1 ; DISPLAYS 1. DIGIT
CATOD_1 = 1 ; DISPLAYS 2. DIGIT
CATOD_2 = 1 ; DISPLAYS 3. DIGIT
CATOD_3 = 1 ; DISPLAYS 4. DIGIT

'================================================= ===========
ON INTERRUPT GOTO ISR
INTCON = %10100000

'================================================= ===========
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

Pause 500

W1:
OWIN DQ,4,[busy] ' Check for still busy converting
IF busy = 0 THEN W1 ' Still busy? then loop

'================================================= ===========
MAIN :
OWOUT DQ ,1,[$CC,$44]
OWOUT DQ ,1,[$CC,$BE]
OWIN DQ ,2,[Temperature.LOWBYTE , Temperature.HIGHBYTE]

Convert_Temp:
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

GoSub Sign_temp

Temperature = Temperature/10

GOSUB AFISARE

FOR I = 0 TO 4
GOSUB SCANNING
NEXT I

GOTO MAIN
'================================================= ===========

' SUBROUTINES:
'================================================= ===========

Sign_temp:
If V >= 10000 then ' Above 0 C.
Temperature=V-10000
sign = " "
Else
Temperature=10000-V ' Below 0 C.
sign= "-"
EndIf
Return

'================================================= ===========
AFISARE : ' transfer the registers to diplay

IF TEMPERATURE DIG 3 = 0 THEN
DIGIT_3 = " "
ELSE
DIGIT_3 = TEMPERATURE dig 3
ENDIF

IF sign = 1 THEN
DIGIT_3 = "-"
ENDIF


IF TEMPERATURE DIG 2 = 0 THEN
DIGIT_2 = " "
ELSE
DIGIT_2 = TEMPERATURE dig 2
ENDIF

DIGIT_1 = TEMPERATURE dig 1
DIGIT_0 = TEMPERATURE dig 0
Return




DISABLE
ISR:
'================================================= ===========
SCANNING : ' SCAN THE DISPLAYS

TEMP = DIGIT_3 : GOSUB TABLO
CATOD_3 = 0 : PAUSE 1 : CATOD_3 = 1

TEMP = DIGIT_2 : GOSUB TABLO
CATOD_2 = 0 : PAUSE 1 : CATOD_2 = 1

TEMP = DIGIT_1 : GOSUB TABLO
CATOD_1 = 0 : DP = 1 : PAUSE 1 : CATOD_1 = 1 : DP = 0

TEMP = DIGIT_0 : GOSUB TABLO
CATOD_0 = 0 : PAUSE 1 : CATOD_0 = 1

Return

'================================================= ===========


TABLO : ' TABLE , CONVERTS THE DATAS TO 7 SEGMENT CODE
SELECT CASE TEMP
CASE 0
SEGMENT_A = 1
SEGMENT_B = 1
SEGMENT_C = 1
SEGMENT_D = 1
SEGMENT_E = 1
SEGMENT_F = 1
SEGMENT_G = 0

CASE 1
SEGMENT_A = 0
SEGMENT_B = 1
SEGMENT_C = 1
SEGMENT_D = 0
SEGMENT_E = 0
SEGMENT_F = 0
SEGMENT_G = 0

CASE 2
SEGMENT_A = 1
SEGMENT_B = 1
SEGMENT_C = 0
SEGMENT_D = 1
SEGMENT_E = 1
SEGMENT_F = 0
SEGMENT_G = 1

CASE 3
SEGMENT_A = 1
SEGMENT_B = 1
SEGMENT_C = 1
SEGMENT_D = 1
SEGMENT_E = 0
SEGMENT_F = 0
SEGMENT_G = 1

CASE 4
SEGMENT_A = 0
SEGMENT_B = 1
SEGMENT_C = 1
SEGMENT_D = 0
SEGMENT_E = 0
SEGMENT_F = 1
SEGMENT_G = 1

CASE 5
SEGMENT_A = 1
SEGMENT_B = 0
SEGMENT_C = 1
SEGMENT_D = 1
SEGMENT_E = 0
SEGMENT_F = 1
SEGMENT_G = 1

CASE 6
SEGMENT_A = 1
SEGMENT_B = 0
SEGMENT_C = 1
SEGMENT_D = 1
SEGMENT_E = 1
SEGMENT_F = 1
SEGMENT_G = 1

CASE 7
SEGMENT_A = 1
SEGMENT_B = 1
SEGMENT_C = 1
SEGMENT_D = 0
SEGMENT_E = 0
SEGMENT_F = 0
SEGMENT_G = 0

CASE 8
SEGMENT_A = 1
SEGMENT_B = 1
SEGMENT_C = 1
SEGMENT_D = 1
SEGMENT_E = 1
SEGMENT_F = 1
SEGMENT_G = 1

CASE 9
SEGMENT_A = 1
SEGMENT_B = 1
SEGMENT_C = 1
SEGMENT_D = 1
SEGMENT_E = 0
SEGMENT_F = 1
SEGMENT_G = 1

CASE "-"
SEGMENT_A = 0
SEGMENT_B = 0
SEGMENT_C = 0
SEGMENT_D = 0
SEGMENT_E = 0
SEGMENT_F = 0
SEGMENT_G = 1

CASE "h"
SEGMENT_A = 0
SEGMENT_B = 0
SEGMENT_C = 1
SEGMENT_D = 0
SEGMENT_E = 1
SEGMENT_F = 1
SEGMENT_G = 1

CASE "o"
SEGMENT_A = 0
SEGMENT_B = 0
SEGMENT_C = 1
SEGMENT_D = 1
SEGMENT_E = 1
SEGMENT_F = 0
SEGMENT_G = 1

CASE "b"
SEGMENT_A = 0
SEGMENT_B = 0
SEGMENT_C = 1
SEGMENT_D = 1
SEGMENT_E = 1
SEGMENT_F = 1
SEGMENT_G = 1

CASE " "
SEGMENT_A = 0
SEGMENT_B = 0
SEGMENT_C = 0
SEGMENT_D = 0
SEGMENT_E = 0
SEGMENT_F = 0
SEGMENT_G = 0

END SELECT
RETURN

INTCON.2=0
RESUME
ENABLE

'================================================= ===========
END
PS: Remove .txt extension from attachament, for using in iSIS.

zorbzz
- 10th May 2010, 02:31
To mehmetOzdemir

Hi I have downloaded and ran isis.zip files and it worked fine for me but when I compile the pic basic file in the isis.zip file and re simulate it in isis it only displays as per the attatched image.
Any ideas? is the pic basic file ok?
I am only learning this system so I am confused as to why it works perfect with original files but yet I cant compile it from my picbasic system.
This is what I get when I compile the files in the zip myself.

mehmetOzdemir
- 10th May 2010, 08:30
I used MPASM when i compiled it. Try to use MPASM or add your config settings to the top of your code.

fratello
- 10th May 2010, 10:10
Try to add this :

@ DEVICE pic16F628A, intOSC_osc_noclkout, WDT_OFF, PWRT_ON, MCLR_OFF, LVP_OFF, CPD_OFF, PROTECT_OFF

DEFINE NO_CLRWDT 1
DEFINE OSC 4
TRISA ..... (0 = OUTPUT ; 1 = INPUT)
TRISB ..... ( ID.)

and don't forget to tell ISIS that your PIC work at 4 Mhz.

zorbzz
- 10th May 2010, 12:14
Ok thanks alot i'll try that.






Try to add this :

@ DEVICE pic16F628A, intOSC_osc_noclkout, WDT_OFF, PWRT_ON, MCLR_OFF, LVP_OFF, CPD_OFF, PROTECT_OFF

DEFINE NO_CLRWDT 1
DEFINE OSC 4
TRISA ..... (0 = OUTPUT ; 1 = INPUT)
TRISB ..... ( ID.)

and don't forget to tell ISIS that your PIC work at 4 Mhz.

zorbzz
- 12th May 2010, 02:28
Thanks again it works perfect now.





Ok thanks alot i'll try that.

fratello
- 2nd June 2010, 15:56
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 !

' ************************************************** ***********
' * 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

fratello
- 3rd June 2010, 07:27
' Process the fourth display
If O_C=3 then ' If it is our turn then
Digit2=0 ' Turn OFF the third LED
If sign="-" then
PortB=%00111111
PortB.7=0
else
PortB=Disp_Patt ' Place the digit pattern on portC
endif
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

fratello
- 22nd April 2011, 07:38
My final code, using for thermometer with two DS18B20. Works fine !

; CATOD / ANOD COMUN
; merge foarte bine !!!
; VARIANTA 2 SENZORI !!!
; by Niculescu Dan, APRIL 2011
;
;
'================================================= =====================================
;
; .oooO
; ( ) Oooo.
; \ ( ( )
; \_) ) /
; (_/
;

@ DEVICE pic16F628A, intOSC_osc_noclkout, WDT_OFF, PWRT_ON

DEFINE OSC 4
CMCON = 7
VRCON = 0
INTCON = 0

COMMON_0 VAR PORTA.0
COMMON_1 VAR PORTA.1
COMMON_2 VAR PORTA.2
COMMON_3 VAR PORTA.3
DQ VAR PORTA.4
DQ2 VAR PORTA.6
DP VAR PORTB.7

Temp Var Byte : Temp2 Var Byte
Temperature Var Word : Temperature2 Var Word
TempC Var Word : TempC2 Var Word
I Var Byte : I2 Var Byte
Sign Var Word : Sign2 Var Word
Float Var Word : Float2 Var Word
V Var Word : V2 Var Word
Dummy Var Byte : Dummy2 Var Byte
Busy Var Bit : Busy2 Var Bit
Delay Var Word
Valoare VAR Word
Semn Var Word

DIGIT_0 VAR BYTE
DIGIT_1 VAR BYTE
DIGIT_2 VAR BYTE
DIGIT_3 VAR BYTE

DS18B20_12bit CON %01111111 ' 750ms, 0.0625°C
DS18B20_12bit2 CON %01111111 ' 750ms, 0.0625°C

TrisB=%00000000 ' Make PortB outputs
TrisA=%11110000
PortA=0:PortB=0 ' Clear PortB and PortA

'================================================= =====================================
' Init Sensor 1
OWOUT DQ, 1, [$CC, $4E, 0, 0, DS18B20_12bit]
OWOut DQ, 1, [$CC, $48] ' Start temperature conversion
OWOut DQ, 1, [$CC, $B8]
OWOut DQ, 1, [$CC, $BE]
Pause 50
OWIn DQ, 2, [temperature.byte0, temperature.byte1]

' Init Sensor 2
OWOUT DQ2, 1, [$CC, $4E, 0, 0, DS18B20_12bit2]
OWOut DQ2, 1, [$CC, $48] ' Start temperature conversion
OWOut DQ2, 1, [$CC, $B8]
OWOut DQ2, 1, [$CC, $BE]
Pause 50
OWIn DQ2, 2, [temperature2.byte0, temperature2.byte1]

Pause 100
'================================================= =====================================
Main :
If portA.7= 1 then
valoare=temperature
semn=sign
Endif
If portA.7= 0 then
valoare=temperature2
semn=sign2
Endif

Part1:
' Start temp.conv.Sensor1
OWOut DQ, 1, [$CC, $44]
OWOut DQ, 1, [$CC, $BE]
OWIn DQ, 2, [temperature.byte0, temperature.byte1]

If Temperature.15 then
Temperature= ~Temperature +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 Sign=1 then
V= 10000 - Temperature
else
V= 10000 + Temperature
EndIf

If V >= 10000 then
Temperature=V-10000
sign = " "
else
Temperature=10000-V
sign = "-"
EndIf

Temperature=Temperature/10
'===================================== end part one
Part2 :
' Start temp.conv.Sensor1
OWOut DQ2, 1, [$CC, $44]
OWOut DQ2, 1, [$CC, $BE]
OWIn DQ2, 2, [temperature2.byte0, temperature2.byte1]

If Temperature2.15 then
Temperature2= ~Temperature2 +1
Sign2 = 1
Endif

Dummy2 = 625 * Temperature2
TempC2 = DIV32 10
TempC2 = (Temperature2 & $7FF) >> 4
Float2 = ((Temperature2.Lowbyte & $0F ) * 25 )>>2
Temperature2 = TempC2*100 + Float2

If Sign2=1 then
V2= 10000 - Temperature2
else
V2= 10000 + Temperature2
EndIf

If V2 >= 10000 then
Temperature2=V2-10000
sign2 = " "
else
Temperature2=10000-V2
sign2 = "-"
EndIf

Temperature2=Temperature2/10

'===================================== end part two
Gosub Selectie
Gosub Display ' B for Common CATOD;without B for Common ANOD

Goto Main

'================================================= =====================================
Selectie :

IF semn ="-" then
DIGIT_3="-"
else
DIGIT_3=" "
ENDIF

IF valoare DIG 2 = 0 THEN
DIGIT_2 = " "
ELSE
DIGIT_2 = valoare dig 2
ENDIF

DIGIT_1 = valoare dig 1
DIGIT_0 = valoare dig 0

RETURN
'================================================= =====================================
Display: ' For Common ANOD
for i=0 to 3

TEMP = DIGIT_3 : gosub segments
COMMON_3 = 1 :gosub DelayBetweenEachDigit : COMMON_3 = 0

TEMP = DIGIT_2 : GOSUB segments
COMMON_2 = 1 :gosub DelayBetweenEachDigit : COMMON_2 = 0

TEMP = DIGIT_1 : GOSUB segments
COMMON_1 = 1 :DP = 0 : gosub DelayBetweenEachDigit : COMMON_1 = 0 : DP = 1

TEMP = DIGIT_0 : GOSUB segments
COMMON_0 = 1 :gosub DelayBetweenEachDigit : COMMON_0 = 0
next i
RETURN
'================================================= =====================================
Displayb: ' For Common CATOD
for i=0 to 3
TEMP = DIGIT_3 : gosub segmentsB
COMMON_3 = 0 :gosub DelayBetweenEachDigit : COMMON_3 = 1

TEMP = DIGIT_2 : GOSUB segmentsB
COMMON_2 = 0 : gosub DelayBetweenEachDigit : COMMON_2 = 1

TEMP = DIGIT_1 : GOSUB segmentsB
COMMON_1 = 0 : DP = 1 : gosub DelayBetweenEachDigit : COMMON_1 = 1 : DP = 0

TEMP = DIGIT_0 : GOSUB segmentsB
COMMON_0 = 0 : gosub DelayBetweenEachDigit : COMMON_0 = 1
next i
RETURN
'================================================= =====================================
segments: ; CONVERTS DATES TO 7 SEGMENT CODE for Common ANOD

SELECT CASE TEMP
CASE 0 : PortB=%11000000 ; 0=ON ; 1=OFF
CASE 1 : PortB=%11111001
CASE 2 : PortB=%10100100
CASE 3 : PortB=%10110000
CASE 4 : PortB=%10011001
CASE 5 : PortB=%10010010
CASE 6 : PortB=%10000010
CASE 7 : PortB=%11111000
CASE 8 : PortB=%10000000
CASE 9 : PortB=%10010000
CASE "-" : PortB=%10111111
CASE " " : PortB=%11111111
END SELECT
RETURN

'================================================= =====================================
segmentsB: ; CONVERTS DATES TO 7 SEGMENT CODE for Common CATOD

SELECT CASE TEMP
CASE 0 : PortB=%00111111 ; 1=ON ; 0=OFF
CASE 1 : PortB=%00000110
CASE 2 : PortB=%01011011
CASE 3 : PortB=%01001111
CASE 4 : PortB=%01100110
CASE 5 : PortB=%01101101
CASE 6 : PortB=%01111101
CASE 7 : PortB=%00000111
CASE 8 : PortB=%01111111
CASE 9 : PortB=%01101111
CASE "-" : PortB=%01000000
CASE " " : PortB=%00000000
END SELECT
RETURN
'================================================= =====================================
DelayBetweenEachDigit:

' DelayBetweenEachDigit
' ---------------------
' Produce delay of about 3 mSec
' Fine tuned with MPLAB StopWatch to get MainLoop = 1 sec
For delay=1 to 5
@ nop
next DELAY
@ nop
@ nop
@ nop
@ nop
@ nop
@ nop
@ nop
return
'================================================= =====================================
END ' of story !!!

fratello
- 25th April 2011, 17:53
I try to use Mr.Darrel "DT_INTS-14.bas" to make another variant of my termometer using 4x7 segments LED, like this :

@ __config _INTOSC_OSC_NOCLKOUT & _WDT_ON & _MCLRE_ON

DEFINE OSC 4
CMCON = 7
VRCON = 0
INTCON = 0
DQ VAR PORTA.4
CLEAR

SEGDEF VAR BYTE[3]
Value VAR WORD
Idx VAR BYTE
Temp VAR BYTE
digitloop VAR BYTE
Blanking VAR BIT

Temperature Var Word
TempC Var Word
I Var Byte
Sign Var Word
Float Var Word
V Var Word
Dummy Var Byte
Busy Var Bit


DS18B20_12bit CON %01111111 ' 750ms, 0.0625°C

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


INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _DISP, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

TRISA = 0
TRISB = 0

@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts
T1CON = $1

' Init Sensor 1
OWOUT DQ, 1, [$CC, $4E, 0, 0, DS18B20_12bit]
OWOut DQ, 1, [$CC, $48] ' Start temperature conversion
OWOut DQ, 1, [$CC, $B8]
OWOut DQ, 1, [$CC, $BE]
Pause 50
OWIn DQ, 2, [temperature.byte0, temperature.byte1]

Main:
' Start temp.conv.Sensor1
OWOut DQ, 1, [$CC, $44]
OWOut DQ, 1, [$CC, $BE]
OWIn DQ, 2, [temperature.byte0, temperature.byte1]

If Temperature.15 then
Temperature= ~Temperature +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 Sign=1 then
V= 10000 - Temperature
else
V= 10000 + Temperature
EndIf

If V >= 10000 then
Temperature=V-10000
sign = " "
else
Temperature=10000-V
sign = "-"
EndIf

FOR Value = 0 TO 9999
GOSUB SetDisp
PAUSE 500
NEXT Value
GOTO Main

'---[Set 7-seg patterns to WORD value]------------------------------------------
SetDisp:
Blanking = 1
FOR Idx = 3 to 0 STEP -1
Temp = Value DIG Idx
IF (Blanking AND Temp != 0) OR Idx = 0 THEN Blanking = 0
IF Blanking THEN
Temp = 0
ELSE
LookUp Temp,[132,175,193,137,170,152,144,143,128,136,210,251],Temp
ENDIF
SEGDEF(Idx) = Temp
NEXT Idx
RETURN


'---[TMR1 - interrupt handler]--------------------------------------------------
DISP:
T1CON.0 = 0 ; stop timer
TMR1H = %11111100
TMR1L = %00011111
T1CON.0 = 1 ; restart timer

PORTA = %1111 ; turn off all digits to prevent ghosting
PORTB = SEGDEF(digitloop) ; put segment pattern to pin
PORTA = ~(DCD digitloop) ; turn on the digit

digitloop = digitloop + 1
IF digitloop = 4 then digitloop = 0
@ INT_RETURN
...but where I must put the value of temperature ?! Any advice, please ? Thanks !

fratello
- 27th April 2011, 18:33
I try something like this

FOR x = 0 TO 9999
value=temperature
GOSUB SetDisp
PAUSE 500
NEXT x
GOTO Main
but without results :( ... Any thought ?

fratello
- 19th June 2013, 11:19
I try to revive this topic ...
I found here (http://vnnik71.narod.ru/termo_ds18b20.html) schematic and hex file (even source code...) for an thermometer... It works absolutely great ! NO FLICKERING despite the absence of external quartz/HS oscillator !
How is made ?! I have no ideea ...
BUT ... in PBP this can be done ?!? I gave up to many LED display projects, because of this issue - annoying flickering ...
Know somebody a GOOD method to get a stable, sharp display ? Thanks in advance !

AvionicsMaster1
- 20th June 2013, 14:37
Although I can't open the sight I have a few questions. What is it you're trying to do? Improve upon project posted here or start from scratch?

What is the range of temperature you want to display?

What displays do you want to use? If flickering is a problem you could use a faster update rate but the display will only be as good as the quality of the display. I agree 7 segment LEDs are a dime a dozen but some are better than others. Although if you want large displays you may not be able to update them but will need to turn them on the whole time using FETs or transistors.

What is it ultimately you'd like to see from this project?

fratello
- 20th June 2013, 14:49
Thanks for reply !
So ... using as hardware - 16F628A @ 4 MHz and LED display KW4-311AVA, I built one termometer, using DS18B20, with different variants of software (presented in this topic). All my variants have this issue - display flickering, more or less, but present.
The hardware from the link posted above use same hardware, 16F628 @ 4 Mhz and same display. BUT ... no flickering ! The display look sharp and bright.
So ... I intend to build an termometer, using same hardware, but flicker-free ! And, despite searching this forum, I could not find any convenient version to apply.
This is why I asked for help ! Thanks in advance !

fratello
- 23rd June 2013, 17:50
Tried a "variation" of code from post #20 :

; Termo LED 7 seg
'================================================= =====================================

@ DEVICE pic16F628A, intOSC_osc_noclkout, WDT_OFF, PWRT_ON, MCLR_OFF, LVP_OFF, CPD_OFF


INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts

DEFINE OSC 4
CMCON = 7
VRCON = 0
INTCON = 0


Common_4 VAR PORTA.1
Common_3 VAR PORTA.0
Common_2 VAR PORTA.7
Common_1 VAR PORTA.6
DQ VAR PORTA.4
DP VAR PORTB.2

Temp Var Byte
Temperature Var Word
TempC Var Word
I Var Byte
Sign Var Word
Float Var Word
V Var Word
Dummy Var Byte
Busy Var Bit
DIGIT_0 VAR BYTE
DIGIT_1 VAR BYTE
DIGIT_2 VAR BYTE
DIGIT_3 VAR BYTE
digit Var BYTE

DS18B20_12bit CON %01111111 ' 750ms, 0.0625°C



Data @0,20,215,76,69,135,37,36,87,4,5,255


PortA=%00000100
TrisA=%00111000
PortB=%11111111
TrisB=%00000000

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _DISP, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts
T1CON = $1

' Init Sensor 1
OWOUT DQ, 1, [$CC, $4E, 0, 0, DS18B20_12bit]
OWOut DQ, 1, [$CC, $48] ' Start temperature conversion
OWOut DQ, 1, [$CC, $B8]
OWOut DQ, 1, [$CC, $BE]
Pause 50
OWIn DQ, 2, [temperature.byte0, temperature.byte1]

Main:
' Start temp.conv.Sensor1
OWOut DQ, 1, [$CC, $44]
OWOut DQ, 1, [$CC, $BE]
OWIn DQ, 2, [temperature.byte0, temperature.byte1]

If Temperature.15 then
Temperature= ~Temperature +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 Sign=1 then
V= 10000 - Temperature
else
V= 10000 + Temperature
EndIf

If V >= 10000 then
Temperature=V-10000
sign = " "
else
Temperature=10000-V
sign = "-"
EndIf

Temperature=Temperature/10

Gosub Selectie

Goto Main

'================================================= =====================================
Selectie :

If sign = "-" then
PortB = %11101111
else
PortB = %11111111
endif

IF Temperature DIG 2 = 0 THEN
digit = " "
else
digit = Temperature dig 2
ENDIF
read digit, DIGIT_2

digit = Temperature dig 1
read digit, DIGIT_1

digit = Temperature dig 0
read digit, DIGIT_0
Return
'================================================= =====================================
Disp:
T1CON.0 = 0 ; stop timer
TMR1H = %11111100
TMR1L = %00011111
T1CON.0 = 1 ; restart timer

Common_1 = 1 : PAUSE 1 : Common_1 = 0

PortB = DIGIT_2
Common_2 = 1 : PAUSE 1 : Common_2 = 0

PortB = DIGIT_1
Common_3 = 1 : DP = 0 : PAUSE 1 : Common_3 = 0 : DP = 1

PortB = DIGIT_0
Common_4 = 1 : PAUSE 1 : Common_4 = 0

@ INT_RETURN


...but I have some errors :

ERROR Line 95: Syntax error. (ReEnterPBP.bas)
ERROR Line 128: Redefiniton of LABEL Vars_Saved. (ReEnterPBP.bas)
ERROR Line 128: Syntax error. (ReEnterPBP.bas)
Advices ?! Thanks !

Darrel Taylor
- 23rd June 2013, 21:54
DT_INTS only works with the MPASM assembler.
Your device statement indicates you are trying to use the old PM assembler.

But I can say that 1-Wire and ASM Interrupts don't get along very well.
1-Wire has very strict timing requirements. And ASM Interrupts have a tendancy to disturb that timing.

1-Wire commands take enough time that if you stop the interrupts to do a software OWOUT/IN ... it will cause blinking.

The only way I can see to scan LED's at a constant rate, and do 1-Wire I/O at the same time ... is to do the 1-Wire communications by Interrupts too.
Sorry, don't have sample code.

fratello
- 24th June 2013, 07:56
Ok, I understand ...Thank You so much for advice ! I will try to figure out how doing 1-Wire by interrupts ...Regards !

Darrel Taylor
- 24th June 2013, 18:53
There's an example of reading the DS18B20 without using OWOUT/IN here ...
http://support.melabs.com/content/389-TEMPX.pbp

It doesn't use timer interrupts. It uses pauses instead.
But it should give a good idea on how to read the sensor.

fratello
- 24th June 2013, 20:24
Many thanks ! Now I wait for account validation ... for see the example. Thanks again !

fratello
- 29th June 2013, 11:26
I'm stuck ...at red lines bellow ...

; Termo 7 seg
'================================================= =====================================

@ DEVICE pic16F628A, intOSC_osc_noclkout, WDT_OFF, PWRT_ON, MCLR_OFF, LVP_OFF, CPD_OFF

DEFINE OSC 4
CMCON = 7
VRCON = 0
INTCON = 0


Common_4 VAR PORTA.0
Common_3 VAR PORTA.1
Common_2 VAR PORTA.2
Common_1 VAR PORTA.3
DP VAR PORTB.7

Temp Var byte
Temperature Var Word
TempC Var Word
I Var Byte
Sign Var Word
Float Var Word
V Var Word
Dummy Var Byte
Busy Var Bit
DIGIT_0 VAR BYTE
DIGIT_1 VAR BYTE
DIGIT_2 VAR BYTE
DIGIT_3 VAR BYTE
digit Var BYTE


DQ VAR PORTA.4
DQ_DIR var TRISA.4
command var byte
pis var byte

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

INTCON = %00100000
OPTION_REG = %10000000
ON INTERRUPT GOTO ISR
INTCON = %10100000


'================================================= =====================================

Gosub init1820 ' Init the DS1820
command = $cc ' Issue Skip ROM command
Gosub write1820

command = $44 ' Start temperature conversion
Gosub write1820
Pause 2000 ' Wait 2 seconds for conversion to complete
Gosub init1820 ' Do another init

command = $cc ' Issue Skip ROM command
Gosub write1820

MAIN :
command = $be ' Read the temperature
Gosub write1820
Gosub read1820

temperature = ??????
sign = ????

Gosub Selectie
Goto Main

'================================================= =====================================
Selectie :
IF sign ="-" then
DIGIT_3="-"
else
DIGIT_3=" "
ENDIF

IF TEMPERATURE DIG 2 = 0 THEN
DIGIT_2 = " "
ELSE
DIGIT_2 = TEMPERATURE dig 2
ENDIF

DIGIT_1 = TEMPERATURE dig 1
DIGIT_0 = TEMPERATURE dig 0

RETURN

'================================================= =====================================
DISABLE
ISR:

for i=0 to 4
TEMP = DIGIT_3 : gosub segments
COMMON_1 = 1 : PAUSE 1 : COMMON_1 = 0


TEMP = DIGIT_2 : GOSUB segments
COMMON_2 = 1 : PAUSE 1 : COMMON_2 = 0

TEMP = DIGIT_1 : GOSUB segments
COMMON_3 = 1 : DP = 0 : PAUSE 1 : COMMON_3 = 0 : DP = 1

TEMP = DIGIT_0 : GOSUB segments
COMMON_4 = 1 : PAUSE 1 : COMMON_4 = 0
next i

segments: ; CONVERTS DATES TO 7 SEGMENT CODE for Common ANOD

SELECT CASE TEMP
CASE 0 : PortB=%11000000 ; 0=ON ; 1=OFF
CASE 1 : PortB=%11111001
CASE 2 : PortB=%10100100
CASE 3 : PortB=%10110000
CASE 4 : PortB=%10011001
CASE 5 : PortB=%10010010
CASE 6 : PortB=%10000010
CASE 7 : PortB=%11111000
CASE 8 : PortB=%10000000
CASE 9 : PortB=%10010000
CASE "-" : PortB=%10111111
CASE " " : PortB=%11111111
END SELECT
return

INTCON.2=0
RESUME
ENABLE
'================================================= =====================================
' Initialize DS1820 and check for presence
init1820:
Low DQ ' Set the data pin low to init
Pauseus 500 ' Wait > 480us
DQ_DIR = 1 ' Release data pin (set to input for high)

Pauseus 100 ' Wait > 60us
If DQ = 1 Then
Pause 500
Goto main ' Try again
Endif
Pauseus 400 ' Wait for end of presence pulse
Return

' Write "command" byte to the DS1820
write1820:
For pis = 1 To 8 ' 8 bits to a byte
If command.0 = 0 Then
Gosub write0 ' Write a 0 bit
Else
Gosub write1 ' Write a 1 bit
Endif
command = command >> 1 ' Shift to next bit
Next pis
Return

' Write a 0 bit to the DS1820
write0:
Low DQ
Pauseus 60 ' Low for > 60us for 0
DQ_DIR = 1 ' Release data pin (set to input for high)
Return

' Write a 1 bit to the DS1820
write1:
Low DQ ' Low for < 15us for 1
@ nop ' Delay 1us at 4MHz
DQ_DIR = 1 ' Release data pin (set to input for high)
Pauseus 60 ' Use up rest of time slot
Return

' Read temperature from the DS1820
read1820:
For pis = 1 To 16 ' 16 bits to a word
temperature = temperature >> 1 ' Shift down bits
Gosub readbit ' Get the bit to the top of temp
Next pis
Return

' Read a bit from the DS1820
readbit:
temperature.15 = 1 ' Preset read bit to 1
Low DQ ' Start the time slot
@ nop ' Delay 1us at 4MHz
DQ_DIR = 1 ' Release data pin (set to input for high)
If DQ = 0 Then
temperature.15 = 0 ' Set bit to 0
Endif
Pauseus 60 ' Wait out rest of time slot
Return

end
I have no ideea how to find the value of temperature :( ...

Demon
- 30th June 2013, 14:57
I can't figure SIGN yet, but TEMPERATURE is set in READ1820 one bit at a time.

Robert

fratello
- 30th June 2013, 15:17
Thanks for reply !
...I know that, but on display I have only "0" ...so I think I need to ...re-define temperature ?!?

Demon
- 30th June 2013, 17:13
I still have no clue how the sign is set, but you GOTO MAIN from within INIT1820; not a good thing, messes up the stack.

Robert

Demon
- 30th June 2013, 17:18
If Temperature.15 then
Temperature= ~Temperature +1
Sign = 1
Endif


Don't you need something like this at bottom of READ1820?

Robert

fratello
- 30th June 2013, 18:11
No matter what temperature I set to DS18B20 ; the display show always "0,1".

fratello
- 2nd July 2013, 09:18
It's beyond on my understanding and mental capabilities :( ...

; Termometru 7 segmente
'================================================= =====================================

;@ DEVICE pic16F628A, intOSC_osc_noclkout, WDT_OFF, PWRT_ON, MCLR_OFF, LVP_OFF, CPD_OFF

DEFINE OSC 4
CMCON = 7
VRCON = 0
INTCON = 0


Common_4 VAR PORTA.0
Common_3 VAR PORTA.1
Common_2 VAR PORTA.2
Common_1 VAR PORTA.3
DP VAR PORTB.7

Temp Var byte
Temperature Var Word
TempC Var Word
I Var Byte
Sign Var Word
Float Var Word
V Var Word
Dummy Var Byte
Busy Var Bit
DIGIT_0 VAR BYTE
DIGIT_1 VAR BYTE
DIGIT_2 VAR BYTE
DIGIT_3 VAR BYTE
digit Var BYTE


DQ VAR PORTA.4
DQ_DIR var TRISA.4
command var byte
pis var byte

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

INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _show, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

T1CON = $31 ; Prescaler=8, TMR1ON
@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts




'================================================= =====================================
Gosub init1820 ' Init the DS1820

command = $cc ' Issue Skip ROM command
Gosub write1820

command = $44 ' Start temperature conversion
Gosub write1820


Gosub init1820 ' Do another init

command = $cc ' Issue Skip ROM command
Gosub write1820

MainLOOP:
command = $be ' Read the temperature
Gosub write1820
Gosub read1820

TEMPERATURE = ((tempERATURE>> 1)*100)+((TEMPERATURE.0*5)*10)
Gosub Selectie
Goto MainLOOP

'================================================= =====================================
Selectie :
IF sign ="-" then
DIGIT_3="-"
else
DIGIT_3=" "
ENDIF

IF TEMPERATURE DIG 2 = 0 THEN
DIGIT_2 = " "
ELSE
DIGIT_2 = TEMPERATURE dig 2
ENDIF

DIGIT_1 = TEMPERATURE dig 1
DIGIT_0 = TEMPERATURE dig 0

RETURN

'================================================= =====================================
show:
for i=0 to 4
TEMP = DIGIT_3 : gosub segments
COMMON_1 = 1 : PAUSE 1 : COMMON_1 = 0


TEMP = DIGIT_2 : GOSUB segments
COMMON_2 = 1 : PAUSE 1 : COMMON_2 = 0

TEMP = DIGIT_1 : GOSUB segments
COMMON_3 = 1 : DP = 0 : PAUSE 1 : COMMON_3 = 0 : DP = 1

TEMP = DIGIT_0 : GOSUB segments
COMMON_4 = 1 : PAUSE 1 : COMMON_4 = 0
next i

segments: ; CONVERTS DATES TO 7 SEGMENT CODE for Common ANOD

SELECT CASE TEMP
CASE 0 : PortB=%11000000 ; 0=ON ; 1=OFF
CASE 1 : PortB=%11111001
CASE 2 : PortB=%10100100
CASE 3 : PortB=%10110000
CASE 4 : PortB=%10011001
CASE 5 : PortB=%10010010
CASE 6 : PortB=%10000010
CASE 7 : PortB=%11111000
CASE 8 : PortB=%10000000
CASE 9 : PortB=%10010000
CASE "-" : PortB=%10111111
CASE " " : PortB=%11111111
END SELECT
return
@ INT_RETURN
'================================================= =====================================
' Initialize DS1820 and check for presence
init1820:
Low DQ ' Set the data pin low to init
Pauseus 500 ' Wait > 480us
DQ_DIR = 1 ' Release data pin (set to input for high)

Pauseus 100 ' Wait > 60us
If DQ = 1 Then
Pause 500
Goto mainLOOP ' Try again
Endif
Pauseus 400 ' Wait for end of presence pulse
Return

' Write "command" byte to the DS1820
write1820:
For pis = 1 To 8 ' 8 bits to a byte
If command.0 = 0 Then
Gosub write0 ' Write a 0 bit
Else
Gosub write1 ' Write a 1 bit
Endif
command = command >> 1 ' Shift to next bit
Next pis
Return

' Write a 0 bit to the DS1820
write0:
Low DQ
Pauseus 60 ' Low for > 60us for 0
DQ_DIR = 1 ' Release data pin (set to input for high)
Return

' Write a 1 bit to the DS1820
write1:
Low DQ ' Low for < 15us for 1
@ nop ' Delay 1us at 4MHz
DQ_DIR = 1 ' Release data pin (set to input for high)
Pauseus 60 ' Use up rest of time slot
Return

' Read temperature from the DS1820
read1820:
For pis = 1 To 16 ' 16 bits to a word
temperature = temperature >> 1 ' Shift down bits
Gosub readbit ' Get the bit to the top of temp
Next pis
If Temperature.15 then
Temperature= ~Temperature +1
Sign = 1
Endif
Return

' Read a bit from the DS1820
readbit:
temperature.15 = 1 ' Preset read bit to 1
Low DQ ' Start the time slot
@ nop ' Delay 1us at 4MHz
DQ_DIR = 1 ' Release data pin (set to input for high)
If DQ = 0 Then
temperature.15 = 0 ' Set bit to 0
Endif
Pauseus 60 ' Wait out rest of time slot
Return

end


ERROR Line 23: Redefinition of VAR. (DT_INTS-14.bas) ?!?
Can not be done a simple termometer with LED display ?

Demon
- 2nd July 2013, 13:14
Check the include, you used the same variable.

Robert

fratello
- 2nd July 2013, 13:50
Found it :
"wsave VAR BYTE $20 SYSTEM ' location for W if in bank0
;wsave VAR BYTE $70 SYSTEM ' alternate save location for W "
...
But now I have nothing on display ?!

Demon
- 2nd July 2013, 20:34
I can only suggest to post all your most recent code. Maybe a senior can spot something.

Robert

fratello
- 3rd July 2013, 09:48
OK, I will follow Your advice ...
This is the last attempt, not-working (just "000" on display). Already feel like I came out of patience with this problem :( .

' Pulse counter - attempt to converted for LED display termometer
' =============
'
' File name : Count_Display.bas
' Company : Mister E
' Programmer : Steve Monfette
' Date : 27/12/2004
' Device : PIC16F628A
'
'
' This program display to 3 x 7 segments dislay the result of
' pulses count on PORTA.4 pin/sec.
'
' Hardware connection :
' ---------------------
' 1. 3 X 7 segments display on PORTB<7:0>
' 2. 3 X PNP transistor on PORTA<3:0> to drive common anode
' of each 7 segments display
'
'
' Programming mode and PIC define
' -------------------------------
'
;@ __config _HS_OSC & _WDT_ON & _PWRTE_ON & _LVP_OFF
CMCON=7 ' ADDED FOR PIC16F628A
DEFINE OSC 20 ' use 20 MHZ oscillator


' I/O Definition
' --------------
'
TRISA = %11111000 ' PORTA : <2:0> outputs to common Anode of 7 segment
' 1. PORTA.0 More significant
' 2. PORTA.2 Less significant
' : PORTA.4 input for signal
'
TRISB = 0 ' PORTB connected to 7 segments
' B0 : segment a
' B1 : segment b
' B2 : segment c
' B3 : segment d
' B4 : segment e
' B5 : segment f
' B6 : segment g
' B7 : segment decimal dot


' Internal EEPROM definition
' --------------------------
'
data @0,192,249,164,176,153,146,130,248,128,144 ' table to convert
' numbers to 7 segments
' pattern output when
' drive invert



' Interrupt and register definition
' ---------------------------------

OPTION_REG = %1111000 ' TMR0 clock source : RA4/T0CKI
' increment on low to high transition
' Prescaler assign to WDT
' WDT rate 1:1
'
INTCON = %10100000 ' Enable global interrupt
' Disable EE write interrupt
' Enable TMR0 overflow interrupt


' Variable definition
' -------------------
'
DisplayPort var PORTB ' Port for 7 Segments
;ClockInput var PORTA.4 ' Input pin for signal
_7Seg1 con 14 ' enable more significant 7 segment display
_7Seg2 con 13 ' enable mid significant 7 segment display
_7Seg3 con 11 ' enable less significant 7 segment display
Digit_1 var byte ' Hundreds digit
Digit_2 var byte ' Tenth digit
Digit_3 var byte ' Unit digit
ToBeDisplay var word ' Result of count to be send to 7 segment display
Display var byte ' Temp variable
DisplayLoop var byte '
Delay var word ' Variable for Delay loop
OverFlowVar var word '
Thousands var bit ' Flag for count >= 1000 & < 10 000
TenThousands var bit ' Flag for count >= 10 000

;===========================================
Temp Var byte
Temperature Var Word
TempC Var Word
I Var Byte
Sign Var Word
DQ VAR PORTA.4
DQ_DIR var TRISA.4
command var byte
pis var byte
;============================================
' Variable and software initialisation
' ------------------------------------
'
tobedisplay = 0 ' set initial value of count
TMR0 = 0 ' reset prescaller
On interrupt GoTo SetVarToBeDisplay


Gosub init1820 ' Init the DS1820

command = $cc ' Issue Skip ROM command
Gosub write1820

command = $44 ' Start temperature conversion
Gosub write1820


Gosub init1820 ' Do another init

command = $cc ' Issue Skip ROM command
Gosub write1820

MainLoop:
command = $be ' Read the temperature
Gosub write1820
Gosub read1820

' MainLoop
' ---------
'
' 1. display the result of the count on RA4 pin
' 2. refresh display
' 3. reset Timer0
' 4. reload prescaler.
'
' Duration of the procedure : 1 sec
' fine tuned by DelayBetweenEachDisplay Sub
'
' Looping 1 sec and get results of the pulse count in
' TMR0 + OverFlowVar
'
DisplayRefresh:
'
' Testing amount of count
' -----------------------
'
' Get the result of count and place decimal point flag
' on the according 7 segments
'
'If tobedisplay>= 1000 Then
'tobedisplay = tobedisplay / 10
'Else
' tenthousands = 0
' thousands = 1
'EndIf

'
' convert digit to 7 segment output pattern
' -----------------------------------------
display=ToBeDisplay dig 2 ' Read hundreds digit
read display, digit_1 ' Convert hundreds
if thousands==1 then digit_1=digit_1 & $7F ' enable decimal dot
' by clearing PORTB.7

display=ToBeDisplay dig 1 ' Read tenths digit
read display, digit_2 ' Convert tens
if tenthousands==1 then digit_2=digit_2 & $7F ' enable decimal dot '
' by clearing PORTB.7

display=ToBeDisplay dig 0 ' Read units digit
read display, digit_3 ' Convert units
'
'
' Send digit to 7 segments
' ------------------------
For displayloop = 0 To 111 ' loop for about 1 sec

' display hundreds
' ----------------
PORTA=_7seg1 ' enable hundreds 7 segment
displayport = digit_1 ' display
GoSub DelayBetweenEachDigit

' display tenth
' -------------
PORTA=_7seg2 ' enable tenth 7 segment
displayport = digit_2 ' display
GoSub DelayBetweenEachDigit

' display units
' -------------
PORTA=_7seg3 ' enable unit 7 segment
displayport = digit_3 ' display
GoSub DelayBetweenEachDigit

Next

ToBeDisplay = Temperature
TMR0 = 0 ' reset prescaller
GoTo DisplayRefresh


DelayBetweenEachDigit:

' DelayBetweenEachDigit
' ---------------------
' Produce delay of about 3 mSec
'
' Fine tuned with MPLAB StopWatch to get MainLoop = 1 sec
'
For delay = 1 To 307
@ nop
Next
@ nop
@ nop
@ nop
@ nop
@ nop
@ nop
@ nop
Return


disable
SetVarToBeDisplay:
'
' SetVarToBeDisplay
' -----------------
' interrupt routine of TMR0 overflow
'
' Reset prescaller
' Reset overflow flag
'
Temperature = ((tempERATURE>> 1)*100)+((TEMPERATURE.0*5)*10)
INTCON.2 = 0 ' clear overflow flag
TMR0 = 0 ' reload TMR0
Resume
enable

'================================================= =====================================
' Initialize DS1820 and check for presence
init1820:
Low DQ ' Set the data pin low to init
Pauseus 500 ' Wait > 480us
DQ_DIR = 1 ' Release data pin (set to input for high)

Pauseus 100 ' Wait > 60us
If DQ = 1 Then
Pause 500
Goto mainLOOP ' Try again
Endif
Pauseus 400 ' Wait for end of presence pulse
Return

' Write "command" byte to the DS1820
write1820:
For pis = 1 To 8 ' 8 bits to a byte
If command.0 = 0 Then
Gosub write0 ' Write a 0 bit
Else
Gosub write1 ' Write a 1 bit
Endif
command = command >> 1 ' Shift to next bit
Next pis
Return

' Write a 0 bit to the DS1820
write0:
Low DQ
Pauseus 60 ' Low for > 60us for 0
DQ_DIR = 1 ' Release data pin (set to input for high)
Return

' Write a 1 bit to the DS1820
write1:
Low DQ ' Low for < 15us for 1
@ nop ' Delay 1us at 4MHz
DQ_DIR = 1 ' Release data pin (set to input for high)
Pauseus 60 ' Use up rest of time slot
Return

' Read temperature from the DS1820
read1820:
For pis = 1 To 16 ' 16 bits to a word
temperature = temperature >> 1 ' Shift down bits
Gosub readbit ' Get the bit to the top of temp
Next pis
If Temperature.15 then
Temperature= ~Temperature +1
Sign = 1
Endif
Return

' Read a bit from the DS1820
readbit:
temperature.15 = 1 ' Preset read bit to 1
Low DQ ' Start the time slot
@ nop ' Delay 1us at 4MHz
DQ_DIR = 1 ' Release data pin (set to input for high)
If DQ = 0 Then
temperature.15 = 0 ' Set bit to 0
Endif
Pauseus 60 ' Wait out rest of time slot
Return
;=================================================
END

Demon
- 3rd July 2013, 18:33
What if you comment the DS1820 logic, set temperature and sign to -20 and test only the display logic?

Robert

AvionicsMaster1
- 5th July 2013, 16:41
Near the top of the program you set up a config line but it's commented out. I think for that chip to need to set the HS osc since you're using a 20Meg unit.

Do you also need to set the CONFIG register to set for oscillator speed and type?

I'm looking over the data sheet but have to catch it in fits and starts. More questions later.

fratello
- 5th July 2013, 17:45
Thanks for advice ....
Indeed I commented this : ";@ __config _HS_OSC & _WDT_ON & _PWRTE_ON & _LVP_OFF"
But in Proteus I set the freq to 20 MHz.
If I write "temperature=123", the display show "12.3" ; so, it's work ...but the reading of sensor not work / or the temperature is wrong calculated ...

Demon
- 5th July 2013, 18:01
So the LCD logic works, that's a start.

Are you doing this only in proteus?

Robert

fratello
- 5th July 2013, 18:07
No, I have builded the hardware too ...
Note : the code for temperature sensor is for DS1820 ; I use DS18B20 - maybe this is the problem ?!

Archangel
- 6th July 2013, 00:14
Hello Fratello,
your code


PORTA=_7seg1 ' enable hundreds 7 segment
displayport = digit_1 ' display
GoSub DelayBetweenEachDigit

Best I remember and for reasons I don't you cannot assign a port value just that way. Something about BLA = bla being a T/F comparason rather than assignment, don't remember just fuzzy . . . I believe PORTA=_7seg1 is a comparason operator and putting ! or ~ ahead of it converts it to a "Bitwise" operation
Try this


PORTA=~_7seg1 ' enable hundreds 7 segment
displayport = digit_1 ' display
GoSub DelayBetweenEachDigit
and if that inverts your display then use 2 nots
PORTA=~~_7seg1 ' enable hundreds 7 segment
displayport = digit_1 ' display
GoSub DelayBetweenEachDigit



As I have not really studied your code I may have misread where your port display is, in any event use not or 2 nots before that port assignment.

AvionicsMaster1
- 6th July 2013, 04:13
A couple of other things I question:Please bear in mind I'm not a real programmer just a poor hacker!

You say you set a rate in Protues but don't you have to have those configs to set the chip up to work at that speed even in Proteus?

Once you go through the mainloop you never go back to it. I don't see a line in your code where you have goto mainloop anywhere.

On the write1820 sub, and some others, you write either a 0 or a1 then shift if right 1 digit. Won't that constantly shift in a zero? And in same sub there are 8 bits to a byte but I think they shouldstart at 0 not 1. I don't really understand how that works so if I'm wrong I'll look up the 1820 and get schooled up.

AvionicsMaster1
- 6th July 2013, 04:15
A couple of other things I question:Please bear in mind I'm not a real programmer just a poor hacker!

You say you set a rate in Protues but don't you have to have those configs to set the chip up to work at that speed even in Proteus?

Once you go through the mainloop you never go back to it. I don't see a line in your code where you have goto mainloop anywhere.

On the write1820 sub, and some others, you write either a 0 or a1 then shift if right 1 digit. Won't that constantly shift in a zero? And in same sub there are 8 bits to a byte but I think they shouldstart at 0 not 1. I don't really understand how that works so if I'm wrong I'll look up the 1820 and get schooled up.

fratello
- 6th July 2013, 16:50
Thank you all for support !
1. The code (last version, from previous page) work fine - at least show a clear, flicker-free suite of "0" , if I comment all references to temperature ...
The "copyright code" belong to Mr.Monfette (' File name : Count_Display.bas ' Company : Mister E ' Programmer : Steve Monfette) so it's a WORKING code for LED display. Me, I just attempted to adapt to my project - reading DS18B20 sensor !
2.If I write in code this line "temperature=123" (instead "calculated" value of temperature), the display show "12.3" ; so, it's work ...but the reading of sensor not work / or the temperature is wrong calculated ...
3.Indeed, the return in loop was to "DisplayRefresh:", not to "Mainloop:". I've changed that, but not results !
...

fratello
- 27th July 2013, 07:31
Me, again ...
I have some good results ! I used example from "EXPERIMENTING WITH THE PICBASIC PRO COMPILER", by Les.Johnson.

Main code :

' Program Thermo-LED, mod. of DISP_TST.BAS
' ************************************************** ***********
' * 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 *
' ************************************************** ***********
'
' Demonstrate the use of the 7-segment display multiplexing include files.
'
' Upon the programs start a TMR0 interrupt is automatically started
' using the compilers ON INTERRUPT command
' To display a value on the leds,
' Place the value to display into the variable D_NUMBER
' and the decimal point location into the variable DP.
' A value of 0 in DP will disable the decimal point
' ************************************************** *********************
@ DEVICE pic16F628A, intOSC_osc_noclkout, WDT_OFF, PWRT_ON, MCLR_OFF, LVP_OFF, CPD_OFF, PROTECT_OFF
Include "Modedefs.Bas"
Include "d:\PBP\3CC_DAN.Inc" ' Load the 3-digit display multiplexor, modified for my hw

' ** Setup the Crystal Frequency, in mHz **

Define OSC 4 ' Set Xtal Frequency

CMCON=7 ' Disable comparators

TRISB = %00000000 ' Set segment pins to output
TRISA = $F0 ' Set digit pins to output

Temp Var Byte
Temperature Var Word
TempC Var Word
I Var Byte
Float Var Word
V Var Word
Dummy Var Byte
n Var Byte
value Var Word
DQ VAR PORTA.4
' ** Declare the Variables **

Counter Var Word ' General purpose counter
Del Var Word ' General purpose delay loop variable


DS18B20_12bit CON %01111111 ' 750ms, 0.0625°C

Init_sensor:
OWOUT DQ, 1, [$CC, $4E, 0, 0, DS18B20_12bit]
OWOut DQ, 1, [$CC, $48]
OWOut DQ, 1, [$CC, $B8]
OWOut DQ, 1, [$CC, $BE]
Pause 50
OWIn DQ, 2, [temperature.byte0, temperature.byte1]

' ** 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
Sign = 1
Endif

Dummy = 625 * Temperature
TempC = DIV32 10
TempC = (Temperature & $7FF) >> 4
Float = ((Temperature.Lowbyte & $0F ) * 25 )>>2
Temperature = TempC*100 + Float

If Sign=1 then
V= 10000 - Temperature
else
V= 10000 + Temperature
EndIf

If V >= 10000 then
Temperature=V-10000
sign = 0
else
Temperature=10000-V
sign = 1
EndIf

value=temperature/10

D_Number=value ' Place the value to display into D_NUMBER
DP=2 ' Enable the decimal point
Gosub Display ' Display the value
For Del=0 to 8000 ' Pause 10ms
Pauseus 100 ' using smaller delays
Next


Inf: Goto Main ' Do it forever

and the include file :

' Program 3CC.DISP.INC
' ************************************************** ***********
' * 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 (Cathode) seven segment display multiplexer Include file
' Displays the contents of the variable D_NUMBER on THREE common anode (cathode) displays
' using a TMR0 interrupt every 6.5ms (assuming a 20mHz oscillator)
' ************************************************** *********************

' ** Declare the Variables **
LEDS Var Byte ' The amount of LEDs in the display
O_C Var Byte ' Used by the interrupt for time sharing
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[3] ' 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
sign var word
' ** 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-0
PS2 Var OPTION_REG.2 ' Prescaler division bit-0
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=0 '0 ' Set the prescaler
PS1=1 '1 ' to increment TMR0
PS2=0 '0 ' every 128th instruction cycle ' settings for 4 MHz oscillator
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
PortA=0:PortB=0 ' Clear PortA and PortB
O_C=0 ' Clear the time share variable

Goto Over_MULTIPLEXER ' Jump over the subroutines

' 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..3). where 1 is the farthest right LED,
' and 0 disables the decimal point.
Display:
For LEDS=2 to 0 step -1 ' Loop for 3 digits (0-999)
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 ; not used in my program
If D_Number<100 and LEDS=2 then Num[LEDS]=10 ' Zero Suppression for the Third digit
Enable ' Re-enable the interrupt
Next
Return

' INTERRUPT HANDLER
' Multiplexes the 4-digits
'
Disable ' Disable all interupts during the interrupt handler
Mult_Int:
' Lookup Num[O_C],[63,6,91,79,102,109,124,7,127,103,0],Disp_Patt ' Decode the segments for the LED
Lookup Num[O_C],[192,249,164,176,153,146,130,248,128,144,255],Disp_Patt
' Process the first display (farthest right)
If O_C=0 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=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
if sign = 1 then portb.6 = 0
Digit2=1 ' Turn ON the third LED
Endif

O_C=O_C+1 ' Increment the time share counter
If O_C>=3 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

Over_MULTIPLEXER:


I have now a sharp display (sharper by decreasing this value : For Del=0 to 8000 ) with a verry, verry little flicker, almost imperceptible ! It is by far the best option until now !