Discussion in "8051 Discussion Forum" started by    Gastonio    Sep 9, 2010.
Thu Sep 09 2010, 09:30 pm
#1
Hello, could you please explain, how to display numbers (float) on LCD. I am trying to do DS18B20 project and I want to display temperature values on the LCD screen, I have couple of examples but I can't understand LCD routine to show digits. What should be the LCD C routine for numbers?


[ Edited Thu Sep 09 2010, 09:31 pm ]
Fri Sep 10 2010, 01:06 am
#2
hi Gastonio
http://www.8051projects.info/blogs/post/DS18B20-based-Temperature-controller-with-RTC.aspx
this help you in DS18B20 portion and if you want to learn lcd then a good tutorial is available on this site

here i am attaching some data but i do that on DS1820 nd lcd

// ds1820.h
//---------------------------------------
// Example read and write DS1820
// for AT89C51
//---------------------------------------
#include<reg51.h>


#ifndef _DS1820_H
#define _DS1820_H

extern void DelayMs(unsigned int count);
extern void DelayUs(int us);
extern bit ResetDS1820(void);
extern bit ReadBit(void);
extern void WriteBit(bit Dbit);
extern unsigned char ReadByte(void);
extern void WriteByte(char Dout);
extern void ReadTemp(unsigned char * buff);

#endif

// ds1820.c
//---------------------------------------
// DS1820 driver
//---------------------------------------
#include<AT89X51.H>


sbit DQ  =  P1^0;	// connect with DS1820 Data pin

//---------------------------------------
// Delay mS function
//---------------------------------------
void DelayMs(unsigned int count) 
{  // mSec Delay 11.0592 Mhz 
    unsigned int i;		       		// Keil v7.5a 
    while(count) {
        i = 115; 
		while(i>
0) i--;
        count--;
    }
}


//----------------------------------------
// DELAY at 11.0592MHz crystal.
// Calling the routine takes about 22us, and then
// each count takes another 17us.
// test with KEIL C51 V7.5
//----------------------------------------
void DelayUs(int us)
{
	int i;
	for (i=0; i<us; i++);
}

//----------------------------------------
// Reset DS1820
//----------------------------------------
bit ResetDS1820(void)
{
	bit presence;
	DQ = 0; 		//pull DQ line low
	DelayUs(29); 	// leave it low for about 490us
	DQ = 1; 		// allow line to return high
	DelayUs(3); 	// wait for presence 55 uS
	presence = DQ; 	// get presence signal
	DelayUs(25); 	// wait for end of timeslot 316 uS 
	return(presence); // presence signal returned
} 	// 0=presence, 1 = no part

//-----------------------------------------
// Read one bit from DS1820
//-----------------------------------------
bit ReadBit(void)
{
	unsigned char i=0;
	DQ = 0; 	// pull DQ low to start timeslot
	DQ=1;
	for (i=0; i<3; i++); // delay 17 us from start of timeslot
	return(DQ); // return value of DQ line
}

//-----------------------------------------
// Write one bit to DS1820
//-----------------------------------------
void WriteBit(bit Dbit)
{
	unsigned char i=0;	
    DQ=0;	
	DQ = Dbit ? 1:0;
	DelayUs(5); 			// delay about 39 uS
	DQ = 1;
}

//-----------------------------------------
// Read 1 byte from DS1820
//-----------------------------------------
unsigned char ReadByte(void)
{
	unsigned char i;
	unsigned char Din = 0;
	for (i=0;i<8;i++)
	{
		Din|=ReadBit()? 0x01<<i:Din;
		DelayUs(6); 
	}
	return(Din);
}

//-----------------------------------------
// Write 1 byte
//-----------------------------------------
void WriteByte(unsigned char Dout)
{
	unsigned char i;
	for (i=0; i<8; i++) // writes byte, one bit at a time
	{	    
		WriteBit((bit)(Dout & 0x1)); 		// write bit in temp into
		Dout = Dout >
>
 1;
	}
	DelayUs(5);
}

//-----------------------------------------
// Read temperature
//-----------------------------------------
void ReadTemp(unsigned char * buff)
{
	unsigned char n;
	
	EA=0;	// disable all interrupt
	ResetDS1820();
    WriteByte(0xcc);  // skip ROM
    WriteByte(0x44);  // perform temperature conversion
    while (ReadByte()==0xff); // wait for conversion complete	
    ResetDS1820();
    WriteByte(0xcc);  // skip ROM
    WriteByte(0xbe);  // read the result
    
    for (n=0; n<9; n++)     // read 9 bytes but, use only one byte
    {
       buff[n]=ReadByte();  // read DS1820
    }
	EA=1;
}

// lcd.h
#ifndef __LCD_H__
#define __LCD_H__

#include<AT89X51.H>


#define lcd_port P2
#define rs P3_7
#define rw P3_5
#define en P3_6
#define flag P2_7

void wrt_cmd(unsigned char);
void wrt_data(unsigned char);
void wrt_string(unsigned char*);
void LCD_INI(void);
void busy(void);
void hex2lcd(unsigned char);

#endif

// lcd.c
#include "lcd.h"

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** Cheacking the busy flag of LCD
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

void busy()
{				  
	flag=1;
	rs=0;
	rw=1;
	while(flag!=0)
	{
		en=0;
		en=1;
	}
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** Writing command to LCD ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

void wrt_cmd(unsigned char val_lcd)
{
	busy();
	lcd_port=val_lcd;
	rs=0;
	rw=0;
	en=1;
	en=0;
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** Writing data on LCD ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

void wrt_data(unsigned char dat)
{
	busy();
	lcd_port=dat;
	rs=1;
	rw=0;
	en=1;
	en=0;
}

void wrt_string(unsigned char *string)
{
	while(*string)
		wrt_data(*string++);
}

void LCD_INI(void)
{
	wrt_cmd(0X38);
	wrt_cmd(0X0C);
	wrt_cmd(0X01);
	wrt_cmd(0X06);
}

//main
#include "LCD.H"
#include "DS1820.H"
#include<reg51.h>


void DS1820 (void);

void main (void)
{
LCD_INI();
wrt_cmd(0x80);
wrt_string(T= );
while(1)
{
DS1820();

}

}

void DS1820 (void)
{
unsigned char tp,tpd,msb,nsb,lsb;
		ReadTemp(&MyTemp[0]);
 		if(MyTemp[1]==0xff)
		{
		wrt_cmd(0xc4);
		wrt_data("-");
		MyTemp[0]=~MyTemp[0];
		MyTemp[0]++;
		}
		else
		{
		wrt_cmd(0xc4);
		wrt_data(" ");
		}
		tp  = MyTemp[0] >
>
 1;
		tpd = (MyTemp[0] &1) ? 5:0;
		if(tp<10)
		{
		wrt_data(" ");
		wrt_data(" ");
		wrt_data(0x30 + tp);
		}
		else
		{
		if(tp<100)
		{
		lsb=tp%10;
		nsb=(tp/10)%10;
		msb=(tp/10)/10;
		if (msb!=0)
		wrt_data(0x30 +msb);
		else 	data_in(" ");
		if (nsb!=0)
		wrt_data(0x30 +nsb);
		else data_in(" ");
		wrt_data(0x30 +lsb);
		}
		else
		{
		lsb=tp%10;
		nsb=(tp/10)%10;
		msb=(tp/10)/10;
		wrt_data(0x30 +msb);
		wrt_data(0x30 + nsb);
		wrt_data(0x30 + lsb);
		}
		}
		wrt_data(".");
		wrt_data(0x30+tpd);
		data_in("C");
		wrt_data(0xdf);

}


[ Edited Fri Sep 10 2010, 01:34 am ]
 Gastonioabdul991 like this.
Tags DS1820 interfacing with 8051DS1820 one wire temperature sensorone wire 8051
Fri Sep 10 2010, 01:40 am
#3
Thank you very much, I know how to configure LCD and know how to show strings, however I don't know how to convert hex to dec on C, to be able to show values of temperature on LCD screen. I still can't figure out how the DS18B20 is programmed.
Fri Sep 10 2010, 02:05 am
#4
you can make use of sprintf function for hex to decimal conversion.

if you want to display 123.45 (a float with 2 decimal precision)

float test = 123.45;
unsigned int test1;
char buffer[10];

test1 = test * 100; //now float is converted to integer

sprintf(buffer, "%d.%02d", test1/100, test1%100);

//buffer will now have 123.45
 Gastonio like this.
Fri Sep 10 2010, 02:10 am
#5
Thank you for the help, I will try that. If I understood right, the value of temperature from 18B20 is 16bit? So I have to extract LSB and MSB and then convert those values to DEC and only then send them to LCD screen.


[ Edited Fri Sep 10 2010, 02:10 am ]
Fri Sep 10 2010, 02:20 am
#6
put then together in a 16 bit integer, convert to ascii using sprintf, then display.

// combine 2 8bit values to make single 16bit varaible
bit16 = MSB;
bit16 = (bit16 << 8) | LSB;
 Gastonio like this.
Sat Sep 11 2010, 01:50 am
#7
Hi, I figured out how to count temperature and wanted to display it on the hyper-terminal, however I am getting this error: "temp" undefined identifier. Maybe I should write void main (float temp) ? I work with asm, however 18B20 programming looked tricky on asm, I have little experience with C, so it is harder to solve problems and It would be kind if you helped.

#define uchar unsigned char
#define uint unsigned int
#include<intrins.h>
#include<reg52.h>
#include<math.h>
#include<stdio.h>

sbit ds=P3^7;

void delay_750us()
{
uint i=57;
while(i--)_nop_();
}

void delay_70us()
{
uchar i=9;
while(i--);
}

void delay_30us()
{
uchar i=3;
while(i--);
}
void delay_500us()
{
uint i=39;
while(i--)_nop_();
}
void delay_15us()
{
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
}
void ds18b20_reset()
{
uchar flag=1,i=0;
ds=1;
_nop_();
_nop_();
while(flag&&i<200)
{
ds=0;
delay_750us();
ds=1;
delay_70us();
if(ds==0)
{
flag=0;
}
else
flag=1;
delay_500us();
ds=1;
i++;
}
}

void ds18b20_write(uchar byte)
{
char i;
bit b;
ds=1;
_nop_();
_nop_();
for(i=0;i<8;i++)
{
b=byte&0x01;
byte=byte>>1;
if(b==0)
{
ds=0;
delay_15us();
ds=0;
}
else
{
ds=0;
delay_15us();
ds=1;
}
delay_15us();
delay_15us();
delay_15us();
ds=1;
}
}

uchar ds18b20_read()
{
uchar bb;
char i;
for(i=0;i<8;i++)
{
bb=bb>>1;
ds=1;
_nop_();
_nop_();
ds=0;
_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();
ds=1;
_nop_();_nop_();_nop_();_nop_();
if(ds==1)
bb=0x80|bb;
delay_30us();
}
return bb;
}

float get_temp()
{
uchar tmp1,tmp2;
float temp;
uint tmp;
bit flag;
ds18b20_reset();
ds18b20_write(0xcc);
ds18b20_write(0x44);
ds18b20_reset();
ds18b20_write(0xcc);
ds18b20_write(0xbe);
tmp1=ds18b20_read();
tmp2=ds18b20_read();
tmp=tmp2*256;
tmp=tmp+tmp1;
flag=tmp&&0xf800;
if(flag==0)
{
temp=(~tmp+1)*0.0625;
temp=temp*-1;
}
else
temp=tmp*0.0625;
return temp;
}
void sercon(void)
{
SCON = 0x50;
TMOD |= 0x20;
TH1 = 0xFD;
TR1 = 1;
TI = 1;
}

void main()
{
uint cnt = 0;

sercon();

do
{
get_temp();

printf("TemperatuerResult: %d\r\n",temp);
cnt = 10000;
for(;cnt > 0;cnt--)
{};
}while(1);
}
Sat Sep 11 2010, 02:07 am
#8
It would help to have the line number where the error was found.
I'm assuming the problem is line
printf("TemperatuerResult: %d\r\n",temp);

temp is declared in "get_temp()" and does not exist outside of "get_temp()"
Declare temp globally (at the top of the file) or try this.
Note it should be %f not %d.

void main()
{
float temp;
uint cnt = 0;
sercon();
do
{
temp=get_temp();

printf("TemperatuerResult: %f\r\n",temp);
cnt = 10000;
for(;cnt >
 0;cnt--)
{};
}while(1);
} 






[ Edited Sat Sep 11 2010, 02:13 am ]
 Gastonio like this.
Sat Sep 11 2010, 02:22 am
#9
Thank you very much, the solution you provided works well, tested it on MCU.
Sun Sep 12 2010, 10:22 pm
#10
Hi again, I made minor modifications to my code, the temperature value is displayed, however it is blinking because the temperature value is always refreshed. How to make the temperature value not to blink on LCD? I guess long delay after writing string won't make any good.

DS18B20 code:
#include<intrins.h>
#include<reg51.h>
#include<math.h>
#include<stdio.h>
#include<1602.h>

sbit ds=P3^7;

// call delay - 24us and each count 16us.
void DS_delay(int useconds)
{
int s;
for (s=0; s<useconds;s++);
}

unsigned char ds18b20_reset(void)
{
unsigned char presence;
ds = 0; //pull DQ line low
DS_delay(29); // leave it low for 480us
ds = 1; // allow line to return high
DS_delay(3); // wait for presence
presence = ds; // get presence signal
DS_delay(25); // wait for end of timeslot
return(presence); // presence signal returned
} // 0=presence, 1 = no part

void ds18b20_write(unsigned char byte)
{
char i;
bit b;
unsigned char c;
ds=1;
_nop_();
for(i=0;i<8;i++)
{
b=byte&0x01;
byte=byte>>1;
if(b==0)
{
ds=0;
for (c=0; c<3; c++); //15us
ds=0;
}
else
{
ds=0;
for (c=0; c<3; c++);
ds=1;
}
DS_delay(2); //45us
ds=1;
}
}

unsigned char ds18b20_read()
{
unsigned char bb;
char i;
for(i=0;i<8;i++)
{
bb=bb>>1;
ds=1;
_nop_();
ds=0;
_nop_();
ds=1;
_nop_();
if(ds==1)
bb=0x80|bb;
DS_delay(1); //30us
}
return bb;
}

float get_temp()
{
unsigned char LSB_temp, MSB_temp;
float temp;
unsigned int tmp;
bit flag;
ds18b20_reset();
ds18b20_write(0xcc);
ds18b20_write(0x44);
ds18b20_reset();
ds18b20_write(0xcc);
ds18b20_write(0xbe);
LSB_temp=ds18b20_read();
MSB_temp=ds18b20_read();
tmp=MSB_temp*256;
tmp=tmp+LSB_temp;
flag=tmp&&0xf800;
if(flag==0)
{
temp=(~tmp+1)*0.0625;
temp=temp*-1;
}
else
temp=tmp*0.0625;
return temp;
}

void main()
{
float temp;
unsigned int temp1;
unsigned char buffer[10];
unsigned int j;

while(1)
{
init();
temp = get_temp();
temp1 = temp * 100;
sprintf(buffer, "%d.%02d", temp1/100, temp1%100);
writedat(0x80);
sendstring(buffer);
for(j=0; j<10000; j++);
}
}

LCD code:

#include<REG51.h>

sbit RS = P2^6;
sbit RW = P2^5;
sbit E = P2^7;

void init(void);
void writeCmd( unsigned char a );
void writedat(unsigned char b );
void Delay(void);
void sendstring(unsigned char *b);

void init()
{
writeCmd(0x01);
writeCmd(0x38);
writeCmd(0x0C);
writeCmd(0x06);
}

void writeCmd(unsigned char a)
{
RS = 0;
P0 = a;
RW = 0;
E = 1;
Delay();
E = 0;
}

void writedat(unsigned char b)
{
RS = 1;
P0 = b;
RW = 0;
E = 1;
Delay();
E = 0;
}

void Delay()
{
unsigned char j,k;
for (j=0; j<255; j++)
for (k=0; k<5; k++);
}

void sendstring(unsigned char *c)
{
while(*c) //till string ends
writedat(*c++); //send characters one by one
}

Get Social

Information

Powered by e107 Forum System

Downloads

Comments

Michailqfh
Fri Mar 29 2024, 01:53 am
Bobbyerilar
Thu Mar 28 2024, 08:08 am
pb58
Thu Mar 28 2024, 05:54 am
Clarazkafup
Thu Mar 28 2024, 02:24 am
Walterkic
Thu Mar 28 2024, 01:19 am
Davidusawn
Wed Mar 27 2024, 08:30 pm
Richardsop
Tue Mar 26 2024, 10:33 pm
Stevencog
Tue Mar 26 2024, 04:26 pm