PIC16F628A + DS18B20 + 7 segment [MikroC]

Discussion in 'Programmer's Corner' started by ducu, Aug 20, 2010.

  1. ducu

    Thread Starter New Member

    Aug 18, 2010
    2
    0
    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:

    Code ( (Unknown Language)):
    1.  
    2. /*
    3. '*******************************************************************************
    4. ' Description:
    5.      The temperature most be displayed on the digits (7 segments) in this method (00,0C)
    6. ' Test configuration:
    7. '    MCU:                        PIC16F628A
    8. ' Configuration Word
    9. '    Oscillator:                 INTOSC:I/O on RA.6, I/O on RA.7
    10. '    Watchdog Timer:             OFF
    11. '    Power up Timer:             Disabled
    12. '    Master Clear Enable:        Enabled
    13. '    Browun Out Detect:          Enabled
    14. '    Low Voltage Program:        Disabled
    15. '    Data EE Read Protect:       Disabled
    16. '    Code Protect:               OFF
    17. '*******************************************************************************
    18. */
    19. //***********Declared mask*************/
    20. unsigned short mask(unsigned short num){
    21. switch (num) {
    22. case 0 : return 0x3F;
    23. case 1 : return 0x06;
    24. case 2 : return 0x5B;
    25. case 3 : return 0x4F;
    26. case 4 : return 0x66;
    27. case 5 : return 0x6D;
    28. case 6 : return 0x7D;
    29. case 7 : return 0x07;
    30. case 8 : return 0x7F;
    31. case 9 : return 0x6F;
    32. }
    33. }
    34. /*******Endless mask***********/
    35. unsigned short shifter, portb_index;
    36. unsigned short portb_array[4];
    37. unsigned char digit, J1, J2;
    38. unsigned int value;
    39. unsigned cc;
    40.  
    41. void interrupt()
    42. {
    43. PORTA = 0;                           // Turn off all 7seg. displays;
    44. PORTB = portb_array[portb_index];    // Bring appropriate value to PORTB;
    45. PORTA = shifter;                     // Turn on appropriate 7seg. display;
    46.  
    47. //move shifter to next digit;
    48. shifter <<= 1;
    49. if(shifter > 8u)
    50. shifter = 1;
    51.  
    52. //increment portb_index;
    53. portb_index ++ ;
    54. if (portb_index > 3u)
    55. portb_index = 0;                     //turn on 1st, turn off 2nd 7 seg.;
    56. TMR0 = 0;                            //reset TIMER0 value;
    57. INTCON = 0x20;                       //clear T0IF, Bit T0IF=0, T0IE=1;
    58. }
    59. void sensor(){
    60.            INTCON.GIE = 0;             //Disable interrupt;
    61.            Ow_Reset (PORTA, 4);        //one wire reset signal;
    62.            Ow_Write (PORTA, 4, 0xCC);  //Issue command to DS18B20;
    63.            Ow_Write (PORTA, 4, 0X44);  //Issue command to DS18B20;
    64.            INTCON.GIE = 1;             //Enable interrupt;
    65.            
    66.            Delay_ms(500);              //Wait for conversion complete;
    67.            
    68.            INTCON.GIE = 0;            
    69.            CC = Ow_Reset(PORTA ,4);
    70.            Ow_Write(PORTA, 4, 0XCC);   //Issue command to DS18B20;
    71.            Ow_Write(PORTA, 4, 0XBE);   //Issue command to DS18B20;
    72.            J1 = Ow_Read(PORTA ,4);     //Get result;
    73.            J2 = Ow_Read(PORTA ,4);     //Get result (assuming the temperature is positive);
    74.            INTCON.GIE = 1;             //Enable interrupt;
    75.            
    76.            if(J2 = 0xFF)
    77.            J1 = J1 | 0XFF;             //Complement of two;
    78.            J1 = J1 + 1;
    79.            
    80.            J2 = ((J1 & 0x01)* 5);      //Get decimal value;
    81.            J1 = J1 >> 1;               //From the 2byte variable;
    82.            value = ((J1*10) + J2);
    83. }
    84. void main()
    85. {
    86. CMCON |= 7;                          // Set AN pins to Digital I/O;
    87. OPTION_REG = 0x80;                   // Set timer TMR0;
    88. digit = 0;
    89. portb_index = 0;
    90. shifter = 1;
    91. TMR0 = 0;
    92. INTCON = 0xA0;                       // Disable interrupt PEIE,INTE,RBIE,T0IE
    93. PORTA = 0;                           // Turn off both displays
    94. TRISA = 0;                           // All port A pins are configured as outputs
    95. PORTB = 0;                           // Turn off all display segments
    96. TRISB = 0;                           // All port D pins are configured as outputs
    97.  
    98. do {
    99.         sensor();
    100.            
    101.            Delay_ms(500);
    102.  
    103.            //Prepare digits for display;
    104.            digit = value % 10u;            //extract ones digit;
    105.            portb_array[0] = mask(digit);    //and store it to PORTB array;
    106.            digit = (value / 10u) % 10u;    //extract tens digit;
    107.            portb_array[1] = mask(digit);    //and store it to PORTB array;
    108.            digit = (value / 100u) % 10u;   //extract hundreds digit;
    109.            portb_array[2] = mask(digit);    //and store it to PORTB array;
    110.            digit = value / 1000u;          //extract thousands digit;
    111.            portb_array[3] = mask(digit);    //and store it to PORTB array;
    112.  
    113.                      
    114.            }while(1);
    115. }
    116.  
    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: Aug 20, 2010
  2. tom66

    Senior Member

    May 9, 2009
    2,613
    213
    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.)
     
  3. ducu

    Thread Starter New Member

    Aug 18, 2010
    2
    0
    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
     
Loading...