luanktd
Newbie level 5
- Joined
- Apr 13, 2012
- Messages
- 9
- Helped
- 0
- Reputation
- 0
- Reaction score
- 0
- Trophy points
- 1,281
- Activity points
- 1,328
this is my code, it's working very good.
Code:
//===============================================
// Written by: Luanktd
// DS18b20 with Pic 16F887, Display led 7 segments
////////////////////////////////////////////////////////////
#include <htc.h>
__CONFIG(FOSC_HS & WDTE_OFF & PWRTE_ON & MCLRE_ON & CP_OFF & BOREN_OFF
& IESO_OFF & FCMEN_OFF & LVP_OFF & DEBUG_OFF); //1st config. Word
__CONFIG(BOR4V_BOR21V); //2st config.
#define _XTAL_FREQ 8000000
#define uch unsigned char //
# define DQ RE2 //define 18B20 data PORT
# define DQ_DIR TRISE2 //define 18B20 D PORT direct register
# define DQ_HIGH() DQ_DIR =1 //set data PORT INPUT
# define DQ_LOW() DQ = 0; DQ_DIR = 0 //set data PORT OUTPUT
unsigned char TLV=0 ; //temperature high byte
unsigned char THV=0; //temperature low byte
unsigned char TZ=0; //temperature integer after convert
unsigned char TX=0; //temperature decimal after convert
unsigned int wd; //temperature BCD code after convert
unsigned char tram;
unsigned char chuc;
unsigned char donvi;
unsigned char le;
unsigned char table[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
//the display code of 0-9
//------------------------------------------------
//delay function
//display function
// each count take 12us;
void delay (int uSeconds)
{
int s;
for (s=0; s<uSeconds; s++);
}
void display()
{
TRISA=0X00; //set A PORT all OUTPUT
PORTD=0xC6; //display degrees symbol
PORTA=0x1f;
delay(250);
PORTD=0x9C; //display "C" symbol
PORTA=0x2f;
delay(250);
PORTD=table[le];
PORTA=0x37;
delay(250);
PORTD=table[donvi]&0x7F;
PORTA=0x3b;
delay(250);
PORTD=table[chuc];
PORTA=0x3d;
delay(250);
PORTD=table[tram];
if(PORTD==0xC0) PORTA=0xFF; else PORTA=0x3e;
delay(250);
}
//------------------------------------------------
//system initialize function
void init()
{
OPTION_REG = 0x00; // dung prescaler cho timer0 voi ti le la 1:2
ANSEL = 0; // Configure AN pins as digital I/O
ANSELH = 0;
ADCON1=0X07; //set A PORT general data PORT
TRISA=0X00; //set A PORT direct OUTPUT
TRISD=0X00; //set D PORT direct OUTPUT
TRISE=0x00;
}
//-----------------------------------------------
//reset DS18B20 function
reset(void)
{
char presence=1;
while(presence)
{
DQ_LOW() ; //MAIN MCU PULL LOW
delay(41); //delay 503us
DQ_HIGH(); //release general line and wait for resistance pull high general line and keep 15~60us
delay(5); //delay 70us
if(DQ==1) presence=1; // not receive responsion signal,continue reset
else presence=0; //receive responsion signal
delay(40); //delay 430us
}
}
//-----------------------------------------------
//write 18b20 one byte function
void write_byte(uch val)
{
uch i;
uch temp;
for(i=8;i>0;i--)
{
temp=val&0x01; //shift the lowest bit
DQ_LOW();
NOP();
NOP();
NOP();
NOP();
NOP(); //pull high to low,produce write time
if(temp==1) DQ_HIGH(); //if write 1,pull high
delay(5); //delay 63us
DQ_HIGH();
NOP();
NOP();
val=val>>1; //right shift a bit
}
}
//------------------------------------------------
//18b20 read a byte function
uch read_byte(void)
{
uch i;
uch value=0; //read temperature
static bit j;
for(i=8;i>0;i--)
{
value>>=1;
DQ_LOW();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP(); //6us
DQ_HIGH(); // pull high
NOP();
NOP();
NOP();
NOP();
NOP(); //4us
j=DQ;
if(j) value|=0x80;
delay(5); //63us
}
return(value);
}
//-------------------------------------------------
//start temperature convert function
void get_temp()
{
int i;
DQ_HIGH();
reset(); //reset,wait for 18b20 responsion
write_byte(0XCC); //ignore ROM matching
write_byte(0X44); //send temperature convert command
for(i=20;i>0;i--)
{
NOP();
// display(); //call some display function,insure the time of convert temperature
}
reset(); //reset again,wait for 18b20 responsion
write_byte(0XCC); //ignore ROM matching
write_byte(0XBE); //send read temperature command
TLV=read_byte(); //read temperature low byte
THV=read_byte(); //read temperature high byte
DQ_HIGH(); //release general line
TZ=((TLV>>4)|(THV<<4));// & 0X3f; //temperature integer
TX=TLV<<4; //temperature decimal
// if(TZ>100) TZ/100; //not display hundred bit
donvi=TZ%10; //integer Entries bit
chuc=(TZ%100)/10; //integer ten bit
tram = TZ/100;
wd=0;
if (TX & 0x80) wd=wd+5000;
if (TX & 0x40) wd=wd+2500;
if (TX & 0x20) wd=wd+1250;
if (TX & 0x10) wd=wd+625; //hereinbefore four instructions are turn decimal into BCD code
le=wd/1000; //ten cent bit
NOP();
}
//--------------------------------------------------
//main function
void main()
{
init(); //call system initialize function
while(1)
{
get_temp(); //call temperature convert function
display(); //call display function
}
}