728x90

728x90

Saturday, September 23, 2023

PIC16F84A DS18B20 1-Wire Temperature Reading And Multiplexing Display Example Using XC8

Device Overview

The DS18B20 is a digital thermometer that able to convert the temperature from -55 to +125 degree Celsius. The controller communicates with this temperature sensor using a 1-Wire bus. So this device requires only three wires including GND, VCC, and data line. Furthermore it can use data line to power  the device eliminating the VCC. 

PIC16F84A DS18B20 1-Wire Temperature Reading And Multiplexing Display Example Using XC8
DS18B20 Pin Configuration


PIC16F84A DS18B20 1-Wire Temperature Reading And Multiplexing Display Example Using XC8
DS18B20 In TO-92 Package

 A TO-92 package is a typical package for hardware experiment.

PIC16F84A DS18B20 1-Wire Temperature Reading And Multiplexing Display Example Using XC8
A Typical Connection Between Microprocessor And DS18B20
 
PIC16F84A DS18B20 1-Wire Temperature Reading And Multiplexing Display Example Using XC8
Using Multiple Devices Over A 1-Wire Bus
It has its own 64-bit ROM unique ID allowing the controller interface to multiple DS18B20 devices over a 1-Wire bus.  

PIC16F84A DS18B20 1-Wire Temperature Reading And Multiplexing Display Example Using XC8
DS18B20 64-Bit ROM Area

 

If there is only one DS18B20 over a 1-Wire bus, it just need to skip ROM search. The controller just need issue a skip ROM, convert, and read scratch pad command. 

PIC16F84A DS18B20 1-Wire Temperature Reading And Multiplexing Display Example Using XC8
DS18B20 Memory Map
PIC16F84A DS18B20 1-Wire Temperature Reading And Multiplexing Display Example Using XC8
DS18B20 Temperature Data Format

Scratchpad contains 9 bytes of data. Converted temperature consists of two bytes, BYTE 0 and BYTE 1 of device's scratch-pad. It contains sign, decimal temperature data, and fraction in degree Celsius.

To interface with this 1-Wire device, the micro-controller have to prepare a correct timing for its I/O as follow.

PIC16F84A DS18B20 1-Wire Temperature Reading And Multiplexing Display Example Using XC8
DS18B20 Initialization Timing

 
PIC16F84A DS18B20 1-Wire Temperature Reading And Multiplexing Display Example Using XC8
DS18B20 Read/Write Time Slot
This device has two command categories, ROM Commands and Function Commands. ROM commands are not use as the micro-controller just need to get the temperature from a single thermometer on 1-wire bus. 

DS18B20 ROM Commands

  1. Search ROM [F0h]
  2. Read ROM [33h]
  3. Match ROM [55h]
  4. Skip ROM [CCh]
  5. Alarm Search [ECh]

DS18B20 Function Commands

  1. Convert Temperature [44h]
  2. Write Scratchpad [4Eh]
  3. Read Scracthpad [BEh]
  4. Copy Scratchpad [48h]
  5. Recall EEPROM [B8h]
  6. Read Power Supply [B4h]
For full explanation for these command please read the device's data sheet.

XC8 Programming

I use the MPLABX IDE 1.51 with XC8 v2.36 C compiler for PIC micro-controller. I need to write about five C functions to interact with this device. These C functions I followed an application note published by ANALOG DEVICES, "Interfacing the DS18X20/DS1822 1-Wire® Temperature Sensor in a Microcontroller Environment". This example use the 8051 micro-controller.

PIC16F84A DS18B20 1-Wire Temperature Reading And Multiplexing Display Example Using XC8
Simulating Program In Proteus

PIC16F84A DS18B20 1-Wire Temperature Reading And Multiplexing Display Example Using XC8
Multiplexing Seven-Segment Display

 
PIC16F84A DS18B20 1-Wire Temperature Reading And Multiplexing Display Example Using XC8
PIC16F84A In P-DIP Package From Microchip Website


In this example I use a simple 8-bit micro-controller PIC16F84A to get the temperature from this device. The output device is a simple 4-digit common cathode multiplexing display. For the first conversion time, the thermometer yield 85 degree Celsius but I skip this data.

  1.  
  2. #include<xc.h>
  3.  
  4.  
  5. // PIC16F84A Configuration Bit Settings
  6.  
  7. // CONFIG
  8. #pragma config FOSC = XT // Oscillator Selection bits (XT oscillator)
  9. #pragma config WDTE = OFF // Watchdog Timer (WDT disabled)
  10. #pragma config PWRTE = OFF // Power-up Timer Enable bit (Power-up Timer is disabled)
  11. #pragma config CP = OFF // Code Protection bit (Code protection disabled)
  12.  
  13.  
  14. #define _XTAL_FREQ 4000000
  15.  
  16. #define DQ RA4
  17. #define DQ_DIR TRISA4
  18.  
  19. unsigned char ow_reset(void){
  20. unsigned char presence;
  21. DQ_DIR=0;
  22. DQ=0;
  23. __delay_us(480);
  24. DQ=1;
  25. __delay_us(70);
  26. DQ_DIR=1;
  27. presence=DQ;
  28. __delay_us(425);
  29. return presence;
  30. }
  31.  
  32. unsigned char readBit(void){
  33. DQ_DIR=0;
  34. DQ=0;
  35. DQ_DIR=1;
  36. __delay_us(15);
  37. return DQ;
  38. }
  39.  
  40. void writeBit(char bitVal){
  41. DQ_DIR=0;
  42. DQ=0;
  43. if(bitVal==1) DQ=1;
  44. __delay_us(104);
  45. DQ=1;
  46. }
  47.  
  48. unsigned char readByte(void){
  49. unsigned char i;
  50. unsigned char value=0;
  51. for(i=0;i<8;i++){
  52. if(readBit()) value|=0x01<<i;
  53. __delay_us(96);
  54. }
  55. return value;
  56. }
  57.  
  58. void writeByte(char val){
  59. unsigned char i;
  60. unsigned char temp;
  61. for(i=0;i<8;i++){
  62. temp=val>>i;
  63. temp&=0x01;
  64. writeBit(temp);
  65. }
  66. __delay_us(104);
  67. }
  68.  
  69.  
  70. void main(void){
  71. unsigned char LSB,MSB;
  72. unsigned char get[9];
  73. unsigned int temp;
  74. //unsigned char ssd[16]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
  75. unsigned char ssd[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
  76. PORTB=0x00;
  77. TRISB=0x00;
  78. PORTA=0x00;
  79. TRISA=0x00;
  80. ow_reset();
  81. writeByte(0xCC);
  82. writeByte(0x44);
  83. __delay_us(104);
  84. ow_reset();
  85. writeByte(0xCC);
  86. writeByte(0xBE);
  87. for(int i=0;i<9;i++) get[i]=readByte();
  88.  
  89. __delay_ms(800);
  90. while(1){
  91. ow_reset();
  92. writeByte(0xCC);
  93. writeByte(0x44);
  94. __delay_us(104);
  95. ow_reset();
  96. writeByte(0xCC);
  97. writeByte(0xBE);
  98. for(int i=0;i<9;i++) get[i]=readByte();
  99. MSB=get[1];
  100. LSB=get[0];
  101. temp=(MSB<<8)+LSB;
  102. temp>>=4;
  103. LSB=0x0F&LSB;
  104. if(LSB^0x08) LSB=0;
  105. else LSB=5;
  106. //temp&=0x00FF;
  107. //PORTB=temp;
  108. __delay_ms(10);
  109.  
  110. PORTA=0x00;
  111. PORTB=ssd[temp/100];
  112. if(temp/100) RA0=1;
  113. __delay_ms(5);
  114.  
  115. PORTA=0x00;
  116. PORTB=ssd[(temp%100)/10];
  117. RA1=1;
  118. __delay_ms(5);
  119.  
  120. PORTA=0x00;
  121. PORTB=ssd[temp%10]|0x80;
  122. RA2=1;
  123. __delay_ms(5);
  124.  
  125. PORTA=0x00;
  126. PORTB=ssd[LSB];
  127. RA3=1;
  128. __delay_ms(5);
  129.  
  130. }
  131. }
  132.  

This program uses half of device program space and about 80% of device data space. Click here to download its source file.

PIC16F84A DS18B20 1-Wire Temperature Reading And Multiplexing Display Example Using XC8
RAM ROM Usage In PIC16F84A

CCS PICC provide a touch sensor library similar to the DS18B20. MikroC also has a 1-Wire library for its supported devices. Arduino has a lot of libraries for various type of sensors including this device.


No comments:

Post a Comment

320x50

Search This Blog

tyro-728x90