集温度与时间在液晶上的显示设计
程序调试的电路简单得很,没有用到74HC573,刚从硬盘里找到了这个设计,幸存已久。今朝终于得见天日,特此纪念一下过往的大学实验室生活!
本作品是基于现在的水银体温计测温时间长,难读或者读数不精确的现状下而研发的。我们知道去医院看病或自己在家中感冒发烧要测体温来查看。而此款体温计是数字显示,只要上过学就能读体温,相对于水银体温计,不会摔碎也不用担心如何处理。只要将探测头放入咯吱窝里,温度变化,一旦稳定便读出数值来,当低烧或者高烧出现时便会报警提示。除此之外,还有时间显示,此功能让电子体温计更加人性化。
此体温计是基于51单片机+18B20+lcd1602等必要的外围设备实现。
电子体温计体积小,易读,报警。老少儿童皆能使用。
本设计软硬件相结合并不只是用硬件实现。性能更加稳定。传感器+mcu+输出显示+输入控制+报警的设计。
并且此设计可以用于“家庭医生”的系统设计,比如可以加上测脉搏、观心跳、量血压等一体的系统设计。方便家人足不出户便可以知道自己的身体状况。
使用时只要将黄豆粒大的探测头代替水银体温计放到胳肢窝。然后观察示数变化,待稳定不再变化后便是体温数值。
本设计软硬件相结合并不只是用硬件实现。性能更加稳定。传感器+mcu+输出显示+输入控制+报警的设计。
此设计可以用于“家庭医生”的系统设计,比如可以加上测脉搏、观心跳、量血压等一体的系统设计。方便家人足不出户便可以知道自己的身体状况。
如果只是单独测量体温可以用更小的单片机来替换,小巧灵活,精美。
此设计完全可以投入市场,效益可观。
直接贴程序
#include
#include
#define uint unsigned int
#define uchar unsigned char
uchar code table1[]={"Cur Temp: . "};
uchar code table2[]={"Cur Tim: :00: "};
uint temp=0;
uint a,b;
uchar miao,shi,fen,s1num;
float ftemp=0;
sbit dq=P2^0;
sbit bee=P2^1;
sbit k1=P3^3;
sbit k2=P3^6;
sbit k3=P3^7;
sbit rs=P3^4;
sbit en=P3^5;
//***********经典的延时程序6us*****************//
void delay(uint t) //6 us
{
while(--t);
}
void delays(uint t)
{
uchar i;
while(t--)for(i=110;i>0;i--);
}
//关于lcd1602的系列chengxu***********//
void writecomm(uchar com)
{
rs=0;
P1=com;
en=0;
delay(5);
en=1;
delay(5);
en=0;
}
void writedat(uchar dat)
{
rs=1;
P1=dat;
en=0;
delays(5);
en=1;
delays(15);
en=0;
}
void lcd1602init()
{
en=0;
fen=0;
shi=0; //初始值 在这里设
miao=0;
s1num=0;
P2=0xff;
writecomm(0x38);
writecomm(0x0c);
writecomm(0x06);
writecomm(0x01);
}
////////*******温度的系列函数*********8//
bit ds18inti()
{
dq=1;_nop_();_nop_(); //延时2微妙
dq=0;
delay(85);//510us
dq=1;
delay(6); //15-60us
if(dq) //没应答
{
return 0;
}
while(dq); //等待变0则有应答
{
while(!dq); //等待应答信号完毕
}
return 1; //完毕?
}
void writeonebyte(uchar val)
{
uchar i;
for(i=8;i>0;i--)
{
dq=1;_nop_();_nop_(); //从高拉倒低
dq=0;_nop_();_nop_();_nop_();_nop_(); //5 us
dq=val&0x01; //最低位移出
delay(6); //66 us
val=val/2; //右移1位
}
dq=1;
delay(1);
}
//读数据时,数据以字节的最低有效位先从总线移出
uchar readonebyte()
{
uchar i;
uchar value=0;
for(i=8;i>0;i--)
{
dq=1;_nop_();_nop_();
value>>=1;
dq=0;_nop_();_nop_();_nop_();_nop_(); //4 us
dq=1;_nop_();_nop_();_nop_();_nop_();_nop_(); //4 us
if(dq)value|=0x80;
delay(6); //66 us
}
dq=1;
return(value);
}
//****************温度转换***//
get_temp(void)
{
uchar a=0;
uchar b=0;
ds18inti();
delay(200);
writeonebyte(0xcc); //跳过读序列号的操作
writeonebyte(0x44); //启动温度转换
delay(220); //出在这 难题
ds18inti();
writeonebyte(0xcc); //跳过读序列号的操作
writeonebyte(0xbe); //读取温度寄存器
a=readonebyte();//先读低8位
b=readonebyte();//在读高8位
temp=b*256+a;
return temp;
}
//***********蜂鸣函数***///
void beep()
{
bee=~bee;
delays(50);
}
//*******在液晶上显示温度函数***//
void wendu(uchar add,int dat) //int dat必须为整型 才能保证出现25.5以上的值
{
uchar shi,ge,shifen;
if(dat<0)
{
writecomm(0x80+9);
writedat(-);
dat=0-dat;
}
else
{
writecomm(0x80+9);
writedat(+);
}
// bai=(dat>>4)/100+0x30;
shi=(dat>>4)%100/10;
ge=(dat>>4)%10;
shifen=((dat&0x000f)*62.5 )/100+0x30;
writecomm(0x80+add);
// writedat(bai+0x30);
writedat(shi+0x30);
writedat(ge+0x30);
writecomm(0x80+13);
writedat(shifen);
}
//*******在液晶上显示时间函数***//
void sfm(uchar add,uchar dat) //写时分秒的子函数
{
uchar shi,ge;
ge=dat%10;
shi=dat/10;
writecomm(0x80+0x40+add) ;
writedat(0x30+shi) ;
writedat(0x30+ge) ;
}
//*******定时器0的初始化***********、//
void timerinti()
{
TMOD=0x01;
EA=1;
ET0=1;
TR0=1;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
}
//*********显示时间和温度的初始化函数**********8//
void displaytime()
{
uchar num;
writecomm(0x80);
for(num=0;num<16;num++)
{
writedat(table1[num]);
delays(5);
}
a=get_temp(); //yanhi
delays(40);
writecomm(0x80+14);
writedat(0xdf);
writecomm(0x80+15);
writedat(0x43);
delay(200);
writecomm(0x80+0x40);
for(num=0;num<16;num++)
{
writedat(table2[num]);
delays(5);
}
}
//********调用温度和报警函数************//
void displaywendu()
{
int dat;
uchar shi,ge;
delays(200);
a=get_temp();
wendu(10,a);
dat=get_temp();
shi=(dat>>4)%100/10;
ge=(dat>>4)%10;
if((shi<3)|(shi>3))beep();
}
//********键盘扫描程序***********8//
void keyscan()
{
if(k1==0)
{
delays(5);
if(k1==0)
{
s1num+=1;
while(!k1);
}
switch(s1num) //从头闪到尾 原因何在 只要有数据更新就会闪所以不能把
{ //所有的显示函数放大循环里
case 1:TR0=0;writecomm(0x80+0x40+14);writecomm(0x0f);break;
case 2:writecomm(0x80+0x40+11);break;
case 3:writecomm(0x80+0x40+8);break;
case 4:s1num=0;writecomm(0x0c);TR0=1;break;
default:break;
}
}
//.....*****...........//
if(s1num==1) //增加程序
{
if(k2==0)
{
delays(5);
if(k2==0)
{
while(!k2);
miao++;
if(miao==60)
miao=0;
sfm(14,miao);
}
}
}
if(s1num==2)
{
if(k2==0)
{
delays(5);
if(k2==0)
{
while(!k2);
fen++;
if(fen==60)
fen=0;
sfm(11,fen);
}
}
}
if(s1num==3)
{
if(k2==0)
{
delays(5);
if(k2==0)
{
while(!k2);
shi++;
if(shi==24)
shi=0;
sfm(8,shi);
}
}
}
//......................//减少程序
if(s1num==1)
{
if(k3==0)
{
delays(5);
if(k3==0)
{
while(!k3);
miao--;
if(miao==0)
miao=59;
sfm(14,miao);
}
}
}
if(s1num==2)
{
if(k3==0)
{
delays(5);
if(k3==0)
{
while(!k3);
fen--;
if(fen==0)
fen=59;
sfm(11,fen);
}
}
}
if(s1num==3)
{
if(k3==0)
{
delays(5);
if(k3==0)
{
while(!k2);
shi--;
if(shi==0)
shi=24;
sfm(8,shi);
}
}
}
}
void main()
{
lcd1602init();
ds18inti();
timerinti();
displaytime();
sfm(8,shi); // 初始显示00:00
sfm(11,fen);
sfm(14,miao);
while(1)
{
keyscan();
displaywendu();
}
}
void timer0()
液晶显示设 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)