#include
#include
#define uint unsigned int
#define uchar unsigned char
sbit LCD_RS=P2^0;
sbit LCD_RW=P2^1;
sbit LCD_EN=P2^2;
sbit DQ=P3^4;
uchar Temp_Value[]={0x00,0x00};
uchar Temp=0;
uchar Display_Digit[]={0,0,0,0};
bit DS18B20_IS_OK=1;
uchar code df_tab[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};//decimal fraction
uchar code Display_LINE0[]={" Current Temp:"};
uchar Display_LINE1[]={" Temp: "};
void _delay_ms(unsigned int x)
{
unsigned char i;
while(x--)
{
for(i=0;i<125;i++);
}
}
void _delay_us(uint x)
{
while(--x);
}
bit LCD_Busy(void)//测忙
{
bit LCD_Status;//返回值变量
LCD_RS=0;//读取状态
LCD_RW=1;
LCD_EN=1;
_nop_();_nop_();_nop_();_nop_();
LCD_Status=(bit)(P0&0x80);
LCD_EN=0;
return LCD_Status;
}
void LCD_Write_Command(uchar cmd)//写指令
{
while(LCD_Busy());
LCD_RS=0;//
LCD_RW=0;
LCD_EN=0;
_nop_();_nop_();
P0=cmd;
_nop_();_nop_();_nop_();_nop_();
LCD_EN=1;
_nop_();_nop_();_nop_();_nop_();
LCD_EN=0;
}
void LCD_Write_Data(uchar dat)//写数据
{
while(LCD_Busy());//每次写数据操作之前均需要检测忙信号
LCD_RS=1;
LCD_RW=0;
LCD_EN=0;
P0=dat;
_nop_();_nop_();_nop_();_nop_();
LCD_EN=1;
_nop_();_nop_();_nop_();_nop_();
LCD_EN=0;
}
void Init_LCD(void)//液晶初始化
{
_delay_ms(15);//延时15MS
LCD_Write_Command(0x38);
_delay_ms(5);
LCD_Write_Command(0x38);
_delay_ms(5);
LCD_Write_Command(0x38);//以后每次写指令操作之前均需要检测忙信号
while(LCD_Busy());
_delay_ms(5);
LCD_Write_Command(0x01);//清屏
while(LCD_Busy());
_delay_ms(5);
LCD_Write_Command(0x38);//设置16*2显示,5*7点阵,8位数据接口
_delay_ms(5);
while(LCD_Busy());
LCD_Write_Command(0x0c);//开显示,不显示光标
_delay_ms(5);
while(LCD_Busy());
LCD_Write_Command(0x06);//当读或写一个字符后地址指针加一,且光标加一
}
void LCD_POS(uchar pos)//字符显示位置
{
LCD_Write_Command(0x80|pos);
}
void Show_String(uchar *str)//显示字符串
{
while(*str!='\0')
LCD_Write_Data(*str++);
}
/**************************************************/
/*函数功能:DS18B20初始化 */
/*入口参数:无 */
/*出口函数:status */
/**************************************************/
uchar DS18B20_Init(void)
{
uchar status;
DQ=1;
_delay_us(10);
DQ=0;
_delay_us(90);
DQ=1;
_delay_us(8);
status=DQ;
_delay_us(100);
DQ=1;
return status;
}
/**************************************************/
/*函数功能:从DS18B20读取一字节 */
/*入口参数:无 */
/*出口函数:dat(返回读取到数据) */
/**************************************************/
uchar Read_One_Byte(void)
{
uchar i,dat=0;
DQ=1;
_nop_();
for(i=8;i>0;i--)
{
DQ=0;
dat>>=1;
DQ=1;
_nop_();_nop_();
if(DQ)
dat|=0x80;
_delay_us(30);
DQ=1;
}
return dat;
}
/**************************************************/
/*函数功能:向DS18B20写一字节 */
/*入口参数:dat(把dat写入DS18B20) */
/*出口函数:无 */
/**************************************************/
void Write_One_Byte(uchar dat)
{
uchar i;
for(i=8;i>0;i--)
{
DQ=0;
DQ=dat&0x01;
_delay_us(5);
DQ=1;
dat>>=1;
}
}
/**************************************************/
/*函数功能:从DS18B20读取数据(数据) */
/*入口参数:无 */
/*出口函数:无 */
/**************************************************/
void Read_Temp(void)
{
if(DS18B20_Init()==1)
DS18B20_IS_OK=0;
else
{
Write_One_Byte(0xcc);
Write_One_Byte(0x44);
DS18B20_Init();
Write_One_Byte(0xcc);
Write_One_Byte(0xbe);
Temp_Value[0]=Read_One_Byte();
Temp_Value[1]=Read_One_Byte();
DS18B20_IS_OK=1;
}
}
/**************************************************/
/*函数功能:从DS18B20读取数据转换成ASCII码写入液晶 */
/*模块 */
/*入口参数:无 */
/*出口函数:无 */
/**************************************************/
void Display_Temperature(void)
{
uchar ng=0;
if((Temp_Value[1]&0xf8)==0xf8)
{
Temp_Value[1]=~Temp_Value[1];
Temp_Value[0]=~Temp_Value[0]+1;
if(Temp_Value[0]==0x00)
Temp_Value[1]++;
ng=1;
}
Display_Digit[0]=df_tab[Temp_Value[0]&0x0f];
Temp=((Temp_Value[0]&0xf0)>>4)|((Temp_Value[1]&0x07)<<4);
Display_Digit[3]=Temp/100;
Display_Digit[2]=Temp%100/10;
Display_Digit[1]=Temp%10;
Display_LINE1[13]=0x43;
Display_LINE1[12]=0xdf;
Display_LINE1[11]=Display_Digit[0]+'0';
Display_LINE1[10]='.';
Display_LINE1[9]=Display_Digit[1]+'0';
Display_LINE1[8]=Display_Digit[2]+'0';
Display_LINE1[7]=Display_Digit[3]+'0';
if(Display_Digit[3]==0)
Display_LINE1[7]=' ';
if(Display_Digit[2]==0&&Display_Digit[3]==0)
Display_LINE1[8]=' ';
if(ng)
{
if(Display_LINE1[8]==' ')
Display_LINE1[8]='-';
else if(Display_LINE1[7]==' ')
Display_LINE1[7]='-';
else
Display_LINE1[6]='-';
}
LCD_POS(0);
Show_String(Display_LINE0);
LCD_POS(0x40);
Show_String(Display_LINE1);
}
void main(void)
{
Init_LCD();
Read_Temp();
_delay_ms(1000);
while(1)
{
Read_Temp();
if(DS18B20_IS_OK)
Display_Temperature();
_delay_ms(200);
}
}
上面是DS18B20的驱动程序是LCD1602液晶显示,单片机是直接读取DS18B20的DQ脚的数据的!
单片机通过I/O口可以直接与DS18B20直接相连,DS18B20为单总线器件,需要在单片机中编写好器件的初始化,读写程序等,如果在单总线上挂接多只传感器,还要有DS18B20的ROM读写程序和ROM搜索程序等。
无需模数转换,内部已经转换好了的。直接可以显示,非常方便