Sunday, September 24, 2023

PIC16F84A DS18B20 1-Wire Temperature Sensor And Character LCD Using XC8

A simple 8-bit PIC16F84A micro-controller can do a lot of stuff as it has only 1kB of ROM, 68 bytes of RAM, 64 bytes of EEPROM two digital I/O port, one timer, etc. Some electronic engineer make an LC meter or a frequency meter with a dozen of components using this small embedded controller. Using the Assembly language is suitable for this micro-controller because it has a little RAM and SFR. Furthermore it has only 35 Assembly instructions to use.

PIC16F84A DS18B20 1-Wire Temperature Sensor And Character LCD Using XC8
Simulating Program At Start Up

In this example I use this micro-controller with a 16x2 character LCD, a DS18B20 digital thermometer, switches, relay, etc. It could be a temperature controlled DC or AC switch. We can use it control an AC fan on and off. However I could find an AC lamp in Proteus. So I replace with a DC/AC lamp.

PIC16F84A DS18B20 1-Wire Temperature Sensor And Character LCD Using XC8
PIC16F84A In P-DIP Package

I use a free version of XC8 v2.36 in MPLABX IDE v1.51 to make its firmware. It does not have restriction but without technical support and code optimization. It should be effective as the program that was written using Assembly language.

A preset temperature value is stored in EEPROM. It's adjustable. It's read once when the program start. Whenever we adjust the preset temperature it will change its value in EEPROM. The current value in program is also updated.

The main program loop continuously get the temperature data from DS18B20, check whether there's a switch pressing.

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

 

It requires 90.9% of program space, and 63.2% of data space. I added a Watch Dog Timer (WDT) reset to keep track of operation of program. Once it's halted ,the WDT will reset the software. 

PIC16F84A DS18B20 1-Wire Temperature Sensor And Character LCD Using XC8
Resource Usage Of PIC16F84A
If we need a larger multiplexing seven-segment display we can use this once. We can customize the size of color of the display.

PIC16F84A DS18B20 1-Wire Temperature Sensor And Character LCD Using XC8
Temperature Reaches The Preset Value, The Output Relay On

PIC16F84A DS18B20 1-Wire Temperature Sensor And Character LCD Using XC8
Press SW4 To Show EEPROM Preset Value

PIC16F84A DS18B20 1-Wire Temperature Sensor And Character LCD Using XC8
Press SW3 To Increase Its Preset Value

PIC16F84A DS18B20 1-Wire Temperature Sensor And Character LCD Using XC8
Press SW4 To Decrease Its Preset Value


This small project could be use in some areas. I don't have hardware experiment or PCB design for this project because my PIC16F84A was burned a long time ago. Click here to download source file for this project.

No comments:

Post a Comment

Search This Blog

Labels

25AA010A (1) 8051 (7) 93AA46B (1) ADC (30) Analog Comparator (1) Arduino (15) ARM (6) AT89C52 (7) ATMega32 (56) AVR (57) CCS PICC (28) DAC (1) DHT11 (2) Display (105) Distance Sensor (3) DS18B20 (3) dsPIC (2) dsPIC30F1010 (2) EEPROM (5) Environment Sensor (4) esp8266 (1) I2C (29) Input/Output (67) Interrupt (19) Keil (5) Keypad (10) LCD (47) Master/Slave (1) MAX7221 (1) MCP23017 (5) MCP23S17 (4) Meter (3) MikroC (2) Motor (15) MPLABX (71) Nokia 5110 LCD (3) OLED (2) One-Wire (6) Oscillator (8) PCB (6) PCD8544 (3) PCF8574 (5) PIC (107) PIC12F (2) PIC16F628A (2) PIC16F630 (1) PIC16F716 (3) PIC16F818 (10) PIC16F818/819 (2) PIC16F84A (15) PIC16F876A (1) PIC16F877A (9) PIC16F88 (1) PIC16F887 (60) PIC18 (19) PIC18F1220 (4) PIC18F2550 (3) PIC18F4550 (12) PWM (11) RTC (8) Sensor (10) SH1106 (1) Shift Register (11) Shift Registers (3) SPI (24) STM32 (6) STM32 Blue Pill (6) STM32CubeIDE (6) STM32F103C8T6 (6) SysTick (3) temperature sensor (11) Thermometer (21) Timer/Counter (31) TM1637 (2) UART (7) Ultrasonic (4) Voltmeter (7) WDT (1) XC16 (2) XC8 (94)