用LCD1602和DS18B20显示温度和时间C语言程序

用51单片机实现,时间部分用2个按钮实现对时间的调整是的,是作业... 用51单片机实现 ,时间部分用2个按钮实现对时间的调整
是的,是作业
展开
 我来答
mcsbear
2010-07-12 · TA获得超过172个赞
知道答主
回答量:146
采纳率:0%
帮助的人:50.5万
展开全部
您研究一下以下这个程序,然后就可以加上时间功能.多做一点就能多学一点.

开机时对DS18B20进行检测,如果DS18B20检测不正常,LCD1602显示:
DS18B20 ERROR
PLEASE CHECK
蜂鸣器报警。

DS18B20检测正常,LCD1602显示:
DS18B20 OK
TEMP: 100.8℃
如果温度值高位为0,将不显示出来。
你可以通过拔插DS18B20查看DS18B20的检测功能。

/* ME300B单片机开发系统演示程序 - DS18B20温度显示 */
/* LCD1602显示 */
/* 作者: gguoqing */
/*Copyright(C)伟纳电子 www.willar.com All Rights Reserved */
/*******************************************************************/

#include < reg51.h >
#include < intrins.h >

#define uchar unsigned char
#define uint unsigned int

sbit DQ = P3^3 ; //定义DS18B20端口DQ
sbit BEEP=P3^7 ; //蜂鸣器驱动线

bit presence ;

sbit LCD_RS = P2^0 ;
sbit LCD_RW = P2^1 ;
sbit LCD_EN = P2^2 ;

uchar code cdis1[ ] = {" DS18B20 OK "} ;
uchar code cdis2[ ] = {" TEMP: . C "} ;
uchar code cdis3[ ] = {" DS18B20 ERR0R "} ;
uchar code cdis4[ ] = {" PLEASE CHECK "} ;

unsigned char data temp_data[2] = {0x00,0x00} ;
unsigned char data display[5] = {0x00,0x00,0x00,0x00,0x00} ;
unsigned char code ditab[16] = {0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,
0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09} ;
void beep() ;
unsigned char code mytab[8] = {0x0C,0x12,0x12,0x0C,0x00,0x00,0x00,0x00} ;

#define delayNOP() ; {_nop_() ;_nop_() ;_nop_() ;_nop_() ;} ;

/*******************************************************************/
void delay1(int ms)
{
unsigned char y ;
while(ms--)
{
for(y = 0 ; y<250 ; y++)
{
_nop_() ;
_nop_() ;
_nop_() ;
_nop_() ;
}
}
}

/******************************************************************/
/*检查LCD忙状态 */
/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 */
/******************************************************************/
bit lcd_busy()
{
bit result ;
LCD_RS = 0 ;
LCD_RW = 1 ;
LCD_EN = 1 ;
delayNOP() ;
result = (bit)(P0&0x80) ;
LCD_EN = 0 ;
return(result) ;
}

/*写指令数据到LCD */
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 */
/*******************************************************************/
void lcd_wcmd(uchar cmd)
{
while(lcd_busy()) ;
LCD_RS = 0 ;
LCD_RW = 0 ;
LCD_EN = 0 ;
_nop_() ;
_nop_() ;
P0 = cmd ;
delayNOP() ;
LCD_EN = 1 ;
delayNOP() ;
LCD_EN = 0 ;
}

/*******************************************************************/
/*写显示数据到LCD */
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。 */
/*******************************************************************/
void lcd_wdat(uchar dat)
{
while(lcd_busy()) ;
LCD_RS = 1 ;
LCD_RW = 0 ;
LCD_EN = 0 ;
P0 = dat ;
delayNOP() ;
LCD_EN = 1 ;
delayNOP() ;
LCD_EN = 0 ;
}

/* LCD初始化设定 */
/*******************************************************************/
void lcd_init()
{
delay1(15) ;
lcd_wcmd(0x01) ; //清除LCD的显示内容
lcd_wcmd(0x38) ; //16*2显示,5*7点阵,8位数据
delay1(5) ;
lcd_wcmd(0x38) ;
delay1(5) ;
lcd_wcmd(0x38) ;
delay1(5) ;

lcd_wcmd(0x0c) ; //显示开,关光标
delay1(5) ;
lcd_wcmd(0x06) ; //移动光标
delay1(5) ;
lcd_wcmd(0x01) ; //清除LCD的显示内容
delay1(5) ;
}

/* 设定显示位置 */
/*******************************************************************/
void lcd_pos(uchar pos)
{
lcd_wcmd(pos | 0x80) ; //数据指针=80+地址变量
}

/*自定义字符写入CGRAM */
/*******************************************************************/
void writetab()
{
unsigned char i ;
lcd_wcmd(0x40) ; //写CGRAM
for (i = 0 ; i< 8 ; i++)
lcd_wdat(mytab[ i ]) ;
}

/*us级延时函数 */
/*******************************************************************/

void Delay(unsigned int num)
{
while( --num ) ;
}

/*初始化ds1820 */
/*******************************************************************/
Init_DS18B20(void)
{
DQ = 1 ; //DQ复位
Delay(8) ; //稍做延时

DQ = 0 ; //单片机将DQ拉低
Delay(90) ; //精确延时 大于 480us

DQ = 1 ; //拉高总线
Delay(8) ;

presence = DQ ; //如果=0则初始化成功 =1则初始化失败
Delay(100) ;
DQ = 1 ;

return(presence) ; //返回信号,0=presence,1= no presence
}

/* 读一个字节 */
/*******************************************************************/
ReadOneChar(void)
{
unsigned char i = 0 ;
unsigned char dat = 0 ;

for (i = 8 ; i > 0 ; i--)
{
DQ = 0 ; // 给脉冲信号
dat >>= 1 ;
DQ = 1 ; // 给脉冲信号

if(DQ)
dat |= 0x80 ;
Delay(4) ;
}

return (dat) ;
}

/* 写一个字节 */
/*******************************************************************/
WriteOneChar(unsigned char dat)
{
unsigned char i = 0 ;
for (i = 8 ; i > 0 ; i--)
{
DQ = 0 ;
DQ = dat&0x01 ;
Delay(5) ;

DQ = 1 ;
dat>>=1 ;
}
}

/* 读取温度 */
/*******************************************************************/
Read_Temperature(void)
{
Init_DS18B20() ;

WriteOneChar(0xCC) ; // 跳过读序号列号的操作
WriteOneChar(0x44) ; // 启动温度转换

Init_DS18B20() ;
WriteOneChar(0xCC) ; //跳过读序号列号的操作
WriteOneChar(0xBE) ; //读取温度寄存器

temp_data[0] = ReadOneChar() ; //温度低8位
temp_data[1] = ReadOneChar() ; //温度高8位
}

/* 数据转换与温度显示 */
/*******************************************************************/
Disp_Temperature()
{
display[4]=temp_data[0]&0x0f ;
display[0]=ditab[display[4]]+0x30 ; //查表得小数位的值

display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4) ;
display[3]=display[4]/100+0x30 ;
display[1]=display[4]%100 ;
display[2]=display[1]/10+0x30 ;
display[1]=display[1]%10+0x30 ;

if(display[3]==0x30) //高位为0,不显示
{
display[3]=0x20 ;
if(display[2]==0x30) //次高位为0,不显示
display[2]=0x20 ;
}

lcd_pos(0x48) ;
lcd_wdat(display[3]) ; //百位数显示
lcd_pos(0x49) ;
lcd_wdat(display[2]) ; //十位数显示
lcd_pos(0x4a) ;
lcd_wdat(display[1]) ; //个位数显示
lcd_pos(0x4c) ;
lcd_wdat(display[0]) ; //小数位数显示
}

/*******************************************************************/
/* 蜂鸣器响一声 */
/*******************************************************************/
void beep()
{
unsigned char y ;
for (y=0 ;y<100 ;y++)
{
Delay(60) ;
BEEP=!BEEP ; //BEEP取反
}
BEEP=1 ; //关闭蜂鸣器
Delay(40000) ;
}

/* DS18B20 OK 显示菜单 */
/*******************************************************************/
void Ok_Menu ()
{
uchar m ;
lcd_init() ; //初始化LCD

lcd_pos(0) ; //设置显示位置为第一行的第1个字符
m = 0 ;
while(cdis1[m] != '\0')
{ //显示字符
lcd_wdat(cdis1[m]) ;
m++ ;
}

lcd_pos(0x40) ; //设置显示位置为第二行第1个字符
m = 0 ;
while(cdis2[m] != '\0')
{
lcd_wdat(cdis2[m]) ; //显示字符
m++ ;
}

writetab() ; //自定义字符写入CGRAM
delay1(5) ;
lcd_pos(0x4d) ;
lcd_wdat(0x00) ; //显示自定义字符
}

/* DS18B20 ERROR 显示菜单 */
/*******************************************************************/
void Error_Menu ()
{
uchar m ;
lcd_init() ; //初始化LCD

lcd_pos(0) ; //设置显示位置为第一行的第1个字符
m = 0 ;
while(cdis3[m] != '\0')
{ //显示字符
lcd_wdat(cdis3[m]) ;
m++ ;
}

lcd_pos(0x40) ; //设置显示位置为第二行第1个字符
m = 0 ;
while(cdis4[m] != '\0')
{
lcd_wdat(cdis4[m]) ; //显示字符
m++ ;
}
}

/* 主函数 */
/************************************/
void main()
{
Ok_Menu () ;

do
{
Read_Temperature() ;
Disp_Temperature() ;
}
while(!presence) ;

Error_Menu () ;

do
{
Init_DS18B20() ;
beep() ;
}
while(presence) ;
}
意法半导体(中国)投资有限公司
2023-06-12 广告
STM32F103是一款高性能的嵌入式芯片,由意法半导体(STMicroelectronics)公司生产。它是STM32系列芯片之一,具有紧凑、低功耗、高性能等特点,被广泛应用于嵌入式系统中。STM32F103的主要特点包括:1. 集成了A... 点击进入详情页
本回答由意法半导体(中国)投资有限公司提供
蔺冰柯螺
2013-05-03 · TA获得超过3813个赞
知道大有可为答主
回答量:3125
采纳率:25%
帮助的人:158万
展开全部
您研究一下以下这个程序,然后就可以加上时间功能.多做一点就能多学一点.
开机时对DS18B20进行检测,如果DS18B20检测不正常,LCD1602显示:
DS18B20
ERROR
PLEASE
CHECK
蜂鸣器报警。
DS18B20检测正常,LCD1602显示:
DS18B20
OK
TEMP:
100.8℃
如果温度值高位为0,将不显示出来。
你可以通过拔插DS18B20查看DS18B20的检测功能。
/*
ME300B单片机开发系统演示程序
-
DS18B20温度显示
*/
/*
LCD1602显示
*/
/*
作者:
gguoqing
*/
/*Copyright(C)伟纳电子
www.willar.com
All
Rights
Reserved
*/
/*******************************************************************/
#include
<
reg51.h
>
#include
<
intrins.h
>
#define
uchar
unsigned
char
#define
uint
unsigned
int
sbit
DQ
=
P3^3
;
//定义DS18B20端口DQ
sbit
BEEP=P3^7
;
//蜂鸣器驱动线
bit
presence
;
sbit
LCD_RS
=
P2^0
;
sbit
LCD_RW
=
P2^1
;
sbit
LCD_EN
=
P2^2
;
uchar
code
cdis1[
]
=
{"
DS18B20
OK
"}
;
uchar
code
cdis2[
]
=
{"
TEMP:
.
C
"}
;
uchar
code
cdis3[
]
=
{"
DS18B20
ERR0R
"}
;
uchar
code
cdis4[
]
=
{"
PLEASE
CHECK
"}
;
unsigned
char
data
temp_data[2]
=
{0x00,0x00}
;
unsigned
char
data
display[5]
=
{0x00,0x00,0x00,0x00,0x00}
;
unsigned
char
code
ditab[16]
=
{0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,
0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09}
;
void
beep()
;
unsigned
char
code
mytab[8]
=
{0x0C,0x12,0x12,0x0C,0x00,0x00,0x00,0x00}
;
#define
delayNOP()
;
{_nop_()
;_nop_()
;_nop_()
;_nop_()
;}
;
/*******************************************************************/
void
delay1(int
ms)
{
unsigned
char
y
;
while(ms--)
{
for(y
=
0
;
y<250
;
y++)
{
_nop_()
;
_nop_()
;
_nop_()
;
_nop_()
;
}
}
}
/******************************************************************/
/*检查LCD忙状态
*/
/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。
*/
/******************************************************************/
bit
lcd_busy()
{
bit
result
;
LCD_RS
=
0
;
LCD_RW
=
1
;
LCD_EN
=
1
;
delayNOP()
;
result
=
(bit)(P0&0x80)
;
LCD_EN
=
0
;
return(result)
;
}
/*写指令数据到LCD
*/
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。
*/
/*******************************************************************/
void
lcd_wcmd(uchar
cmd)
{
while(lcd_busy())
;
LCD_RS
=
0
;
LCD_RW
=
0
;
LCD_EN
=
0
;
_nop_()
;
_nop_()
;
P0
=
cmd
;
delayNOP()
;
LCD_EN
=
1
;
delayNOP()
;
LCD_EN
=
0
;
}
/*******************************************************************/
/*写显示数据到LCD
*/
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。
*/
/*******************************************************************/
void
lcd_wdat(uchar
dat)
{
while(lcd_busy())
;
LCD_RS
=
1
;
LCD_RW
=
0
;
LCD_EN
=
0
;
P0
=
dat
;
delayNOP()
;
LCD_EN
=
1
;
delayNOP()
;
LCD_EN
=
0
;
}
/*
LCD初始化设定
*/
/*******************************************************************/
void
lcd_init()
{
delay1(15)
;
lcd_wcmd(0x01)
;
//清除LCD的显示内容
lcd_wcmd(0x38)
;
//16*2显示,5*7点阵,8位数据
delay1(5)
;
lcd_wcmd(0x38)
;
delay1(5)
;
lcd_wcmd(0x38)
;
delay1(5)
;
lcd_wcmd(0x0c)
;
//显示开,关光标
delay1(5)
;
lcd_wcmd(0x06)
;
//移动光标
delay1(5)
;
lcd_wcmd(0x01)
;
//清除LCD的显示内容
delay1(5)
;
}
/*
设定显示位置
*/
/*******************************************************************/
void
lcd_pos(uchar
pos)
{
lcd_wcmd(pos
|
0x80)
;
//数据指针=80+地址变量
}
/*自定义字符写入CGRAM
*/
/*******************************************************************/
void
writetab()
{
unsigned
char
i
;
lcd_wcmd(0x40)
;
//写CGRAM
for
(i
=
0
;
i<
8
;
i++)
lcd_wdat(mytab[
i
])
;
}
/*us级延时函数
*/
/*******************************************************************/
void
Delay(unsigned
int
num)
{
while(
--num
)
;
}
/*初始化ds1820
*/
/*******************************************************************/
Init_DS18B20(void)
{
DQ
=
1
;
//DQ复位
Delay(8)
;
//稍做延时
DQ
=
0
;
//单片机将DQ拉低
Delay(90)
;
//精确延时
大于
480us
DQ
=
1
;
//拉高总线
Delay(8)
;
presence
=
DQ
;
//如果=0则初始化成功
=1则初始化失败
Delay(100)
;
DQ
=
1
;
return(presence)
;
//返回信号,0=presence,1=
no
presence
}
/*
读一个字节
*/
/*******************************************************************/
ReadOneChar(void)
{
unsigned
char
i
=
0
;
unsigned
char
dat
=
0
;
for
(i
=
8
;
i
>
0
;
i--)
{
DQ
=
0
;
//
给脉冲信号
dat
>>=
1
;
DQ
=
1
;
//
给脉冲信号
if(DQ)
dat
|=
0x80
;
Delay(4)
;
}
return
(dat)
;
}
/*
写一个字节
*/
/*******************************************************************/
WriteOneChar(unsigned
char
dat)
{
unsigned
char
i
=
0
;
for
(i
=
8
;
i
>
0
;
i--)
{
DQ
=
0
;
DQ
=
dat&0x01
;
Delay(5)
;
DQ
=
1
;
dat>>=1
;
}
}
/*
读取温度
*/
/*******************************************************************/
Read_Temperature(void)
{
Init_DS18B20()
;
WriteOneChar(0xCC)
;
//
跳过读序号列号的操作
WriteOneChar(0x44)
;
//
启动温度转换
Init_DS18B20()
;
WriteOneChar(0xCC)
;
//跳过读序号列号的操作
WriteOneChar(0xBE)
;
//读取温度寄存器
temp_data[0]
=
ReadOneChar()
;
//温度低8位
temp_data[1]
=
ReadOneChar()
;
//温度高8位
}
/*
数据转换与温度显示
*/
/*******************************************************************/
Disp_Temperature()
{
display[4]=temp_data[0]&0x0f
;
display[0]=ditab[display[4]]+0x30
;
//查表得小数位的值
display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4)
;
display[3]=display[4]/100+0x30
;
display[1]=display[4]%100
;
display[2]=display[1]/10+0x30
;
display[1]=display[1]%10+0x30
;
if(display[3]==0x30)
//高位为0,不显示
{
display[3]=0x20
;
if(display[2]==0x30)
//次高位为0,不显示
display[2]=0x20
;
}
lcd_pos(0x48)
;
lcd_wdat(display[3])
;
//百位数显示
lcd_pos(0x49)
;
lcd_wdat(display[2])
;
//十位数显示
lcd_pos(0x4a)
;
lcd_wdat(display[1])
;
//个位数显示
lcd_pos(0x4c)
;
lcd_wdat(display[0])
;
//小数位数显示
}
/*******************************************************************/
/*
蜂鸣器响一声
*/
/*******************************************************************/
void
beep()
{
unsigned
char
y
;
for
(y=0
;y<100
;y++)
{
Delay(60)
;
BEEP=!BEEP
;
//BEEP取反
}
BEEP=1
;
//关闭蜂鸣器
Delay(40000)
;
}
/*
DS18B20
OK
显示菜单
*/
/*******************************************************************/
void
Ok_Menu
()
{
uchar
m
;
lcd_init()
;
//初始化LCD
lcd_pos(0)
;
//设置显示位置为第一行的第1个字符
m
=
0
;
while(cdis1[m]
!=
'\0')
{
//显示字符
lcd_wdat(cdis1[m])
;
m++
;
}
lcd_pos(0x40)
;
//设置显示位置为第二行第1个字符
m
=
0
;
while(cdis2[m]
!=
'\0')
{
lcd_wdat(cdis2[m])
;
//显示字符
m++
;
}
writetab()
;
//自定义字符写入CGRAM
delay1(5)
;
lcd_pos(0x4d)
;
lcd_wdat(0x00)
;
//显示自定义字符
}
/*
DS18B20
ERROR
显示菜单
*/
/*******************************************************************/
void
Error_Menu
()
{
uchar
m
;
lcd_init()
;
//初始化LCD
lcd_pos(0)
;
//设置显示位置为第一行的第1个字符
m
=
0
;
while(cdis3[m]
!=
'\0')
{
//显示字符
lcd_wdat(cdis3[m])
;
m++
;
}
lcd_pos(0x40)
;
//设置显示位置为第二行第1个字符
m
=
0
;
while(cdis4[m]
!=
'\0')
{
lcd_wdat(cdis4[m])
;
//显示字符
m++
;
}
}
/*
主函数
*/
/************************************/
void
main()
{
Ok_Menu
()
;
do
{
Read_Temperature()
;
Disp_Temperature()
;
}
while(!presence)
;
Error_Menu
()
;
do
{
Init_DS18B20()
;
beep()
;
}
while(presence)
;
}
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
elidis
2010-07-08 · TA获得超过100个赞
知道答主
回答量:232
采纳率:0%
帮助的人:60.1万
展开全部
作业?
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 1条折叠回答
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式