PIC16F628A + DS18B20 + 7 segment [MikroC]

Thread Starter

ducu

Joined Aug 18, 2010
2
Hello people,
After I set up the LCD temperature display, I want to show temperature on the digits (7 segments) in this method (00,0C) with 0,1 degree Celsius rezolution . I am using the MCU P16F628A, temperature sensor DS18B20 and 4 digit (7 segment) with common cathode.
Language used is MikroC.
Now, I have made some research and I create this code:

Rich (BB code):
/*
'*******************************************************************************
' Description:
     The temperature most be displayed on the digits (7 segments) in this method (00,0C)
' Test configuration:
'    MCU:                        PIC16F628A
' Configuration Word
'    Oscillator:                 INTOSC:I/O on RA.6, I/O on RA.7
'    Watchdog Timer:             OFF
'    Power up Timer:             Disabled
'    Master Clear Enable:        Enabled
'    Browun Out Detect:          Enabled
'    Low Voltage Program:        Disabled
'    Data EE Read Protect:       Disabled
'    Code Protect:               OFF
'*******************************************************************************
*/
//***********Declared mask*************/
unsigned short mask(unsigned short num){
switch (num) {
case 0 : return 0x3F;
case 1 : return 0x06;
case 2 : return 0x5B;
case 3 : return 0x4F;
case 4 : return 0x66;
case 5 : return 0x6D;
case 6 : return 0x7D;
case 7 : return 0x07;
case 8 : return 0x7F;
case 9 : return 0x6F;
}
}
/*******Endless mask***********/
unsigned short shifter, portb_index;
unsigned short portb_array[4];
unsigned char digit, J1, J2;
unsigned int value;
unsigned cc;

void interrupt()
{
PORTA = 0;                           // Turn off all 7seg. displays;
PORTB = portb_array[portb_index];    // Bring appropriate value to PORTB;
PORTA = shifter;                     // Turn on appropriate 7seg. display;

//move shifter to next digit;
shifter <<= 1;
if(shifter > 8u)
shifter = 1;

//increment portb_index;
portb_index ++ ;
if (portb_index > 3u)
portb_index = 0;                     //turn on 1st, turn off 2nd 7 seg.;
TMR0 = 0;                            //reset TIMER0 value;
INTCON = 0x20;                       //clear T0IF, Bit T0IF=0, T0IE=1;
}
void sensor(){
           INTCON.GIE = 0;             //Disable interrupt;
           Ow_Reset (PORTA, 4);        //one wire reset signal;
           Ow_Write (PORTA, 4, 0xCC);  //Issue command to DS18B20;
           Ow_Write (PORTA, 4, 0X44);  //Issue command to DS18B20;
           INTCON.GIE = 1;             //Enable interrupt;
           
           Delay_ms(500);              //Wait for conversion complete;
           
           INTCON.GIE = 0;             
           CC = Ow_Reset(PORTA ,4);
           Ow_Write(PORTA, 4, 0XCC);   //Issue command to DS18B20;
           Ow_Write(PORTA, 4, 0XBE);   //Issue command to DS18B20;
           J1 = Ow_Read(PORTA ,4);     //Get result;
           J2 = Ow_Read(PORTA ,4);     //Get result (assuming the temperature is positive);
           INTCON.GIE = 1;             //Enable interrupt;
           
           if(J2 = 0xFF)
           J1 = J1 | 0XFF;             //Complement of two;
           J1 = J1 + 1;
           
           J2 = ((J1 & 0x01)* 5);      //Get decimal value;
           J1 = J1 >> 1;               //From the 2byte variable;
           value = ((J1*10) + J2);
}
void main()
{
CMCON |= 7;                          // Set AN pins to Digital I/O;
OPTION_REG = 0x80;                   // Set timer TMR0;
digit = 0;
portb_index = 0;
shifter = 1;
TMR0 = 0;
INTCON = 0xA0;                       // Disable interrupt PEIE,INTE,RBIE,T0IE
PORTA = 0;                           // Turn off both displays
TRISA = 0;                           // All port A pins are configured as outputs
PORTB = 0;                           // Turn off all display segments
TRISB = 0;                           // All port D pins are configured as outputs

do {
        sensor();
           
           Delay_ms(500);

           //Prepare digits for display;
           digit = value % 10u;            //extract ones digit;
           portb_array[0] = mask(digit);    //and store it to PORTB array;
           digit = (value / 10u) % 10u;    //extract tens digit;
           portb_array[1] = mask(digit);    //and store it to PORTB array;
           digit = (value / 100u) % 10u;   //extract hundreds digit;
           portb_array[2] = mask(digit);    //and store it to PORTB array;
           digit = value / 1000u;          //extract thousands digit;
           portb_array[3] = mask(digit);    //and store it to PORTB array;

                     
           }while(1);
}
Currently the 4 digits are displaying "0000" and it can be observed the multiplexing.
Does anyone have any idea to fix this problem?

Kind Regards,
ducu
 
Last edited:

tom66

Joined May 9, 2009
2,595
What happens if you force the value to a specific value?

Also, I'm not sure what J1 = J1 | 0xFF is supposed to do. It will effectively set all the bits in J1. You might as well do J1 = 0xFF. If you wanted to complement it, you need J1 = ~J1 or J1 = J1 ^ 0xFF (either works.)
 

Thread Starter

ducu

Joined Aug 18, 2010
2
Hello tom66,
The Symbol "|" represents an OR gate (specified in mikroc book).
If i force to a specific value, that value is displayed on digits, but also have to do this line commented: //value = ((J1*10) + J2);
I changed the line: J1 = J1 | 0xFF with this: J1 = J1 ^ 0xFF or J1 = ~J1, and the four digits varies between 0000 and 0260.
I think the issue begin when transform in decimal value.


Kind Regards,
ducu
 
Top