找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3928|回复: 8
打印 上一主题 下一主题
收起左侧

新人求教 做了一个显示时间和温度并且报警系统,但是程序有问题,求教

[复制链接]
跳转到指定楼层
楼主
ID:62717 发表于 2014-6-8 12:34 | 显示全部楼层 回帖奖励 |倒序浏览 |阅读模式
做了一个51的显示时间和实时温度并且附带报警系统。但是仿真的时候只有一开始能显示温度,然后改变时间和温度都无法实现,并且报警系统无法实现,求教大神。 压缩包里附带了程序和仿真图。
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:62717 发表于 2014-6-8 12:35 | 显示全部楼层
仿真图和C程序

Desktop.zip

21.68 KB, 下载次数: 39

仿真图+程序

回复

使用道具 举报

板凳
ID:62717 发表于 2014-6-8 12:49 | 显示全部楼层
/*
功能:温度采集显示和可调时钟显示,蜂鸣器报警,时钟用中断法实现
s1:选择要调节的时、分、秒位
s2:时、分、秒加一
s3:时、分、秒减一
*/
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar num,s1num,count;
uchar shi,fen,miao;
sbit rs=P2^0;
sbit e=P2^1;
sbit s1=P3^0;
sbit s2=P3^1;
sbit s3=P3^2; //按键定义
sbit DQ =P2^2; //定义通信端口
sbit beep=P1^0;
bit flag;
uchar code table1[]="Time: 00:00:00";
uchar code table2[]="Temperature: 'C";//1602初始化字符
void  alarm(uchar num);
void delay(uint z)//延时子函数
{
uint x,y;
for(x=z; x>0; x--)
   for(y=110;y>0;y--);
}
#include<1602.h>
#include<18b20.h>
#include<clock_set.h>
void main()
{
uchar temp;
init_1602();
while(1)
{ delay(500); //去除0秒和1秒之间显示间隔跟正常1秒间隔相差过大
   if(miao==0)   //每分钟进行温度采集一次
   {
    TR0=0;   //进入温度采集后,关闭定时器
    flag=1;   //flag=1,标志进入温度采集模式
    write_com(0x80+0x40+13);
    write_dat(0x30+1);     //消除不显示数字1
    temp=ReadTemperature();    //读取DS18B20的温度值
        alarm(temp);
    write_1602(12,temp);   //向1602中写入温度值
    TR0=1; //温度采集完成后,打开定时器
    delay(100);//等待miao不等零,跳出循环
   }
   flag=0; //flag=0,标志在时钟显示模式下
   keyscan(); //调用键盘扫描子程序,用以调整时间
}
}

void timer0() interrupt 1//定时器1的中断服务程序,并向1602中写时分秒显示时间
{
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
count++;
if (count==18)
{
   count=0;
   miao++;
   if(miao==60)
   {
    miao=0;
    fen++;
    if(fen==60)
    {
     fen=0;
     shi++;
     if(shi==24)
     {
      shi=0;
     }
     if(flag==0) //flag=0,标志在时钟显示模式下,然后才显示时间
     write_1602(6,shi);
    }
    if(flag==0)
    write_1602(9,fen);
   }
   if(flag==0)
   write_1602(12,miao);
}
}

void  alarm(uchar num)                                                  //报警
{
  if(40>=num)
     beep=1;                                                  //在温度允许范围,不报警         
  else
         beep=~beep;
  return(0);
}


回复

使用道具 举报

地板
ID:62717 发表于 2014-6-8 12:50 | 显示全部楼层
1602.h
void write_com(uchar com)//向1602液晶写命令函数
{
rs=0;
e=0;
P0=com;
delay(5);
e=1;
delay(5);
e=0;
}
void write_dat(uchar dat)//向1602液晶写入数据
{
rs=1;
e=0;
P0=dat;
delay(5);
e=1;
delay(5);
e=0;
}
void init_1602()//1602液晶的初始化
{
uchar i;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
TMOD=0x01;
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
EA=1;
ET0=1;
TR0=1;
write_com(0x80); //第一行字符的初始化
for(i=0;i<16;i++)
{
   write_dat(table2[i]);
   delay(5);
}
write_com(0x80+0x40); //第二行字符的初始化
for(i=0;i<14;i++)
   {
    write_dat(table1[i]);
    delay(5);
   }
}
void write_1602(uchar address,uchar temp_dat)//向指定的地址中写入时、分、秒数据
{
uchar gewei,shiwei;
if(flag==0)     //若在时钟显示模式下,向第二行写数据
{
   write_com(0x80+0x40+address);
}
   else
   {
    write_com(0x80+address); //若在温度采集显示模式下,向第一行写数据
   }
shiwei=temp_dat/10;
gewei=temp_dat%10;
write_dat(0x30+shiwei);   //根据1602字符库做相应转换
write_dat(0x30+gewei);
}
回复

使用道具 举报

5#
ID:62717 发表于 2014-6-8 12:50 | 显示全部楼层
18b20.h
void delay_18b20( int i)//延时子函数
{
     while(i--);
}
//初始化DS18B20子函数
Init_DS18B20(void)
{
unsigned char x=0 ;
DQ = 1;    //DQ复位
delay_18b20(8); //稍做延时
DQ = 0;    //单片机将DQ拉低
delay_18b20(80); //精确延时 大于 480us
DQ = 1;    //拉高总线
delay_18b20(14);
x=DQ;      //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay_18b20(20);
}
//读一个字节
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_18b20(4);
}
return(dat);
}
//写一个字节
WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
   DQ = 0;
   DQ = dat&0x01;
   delay_18b20(5);
   DQ = 1;
   dat>>=1;
}
delay_18b20(4);
}
//读取温度值
ReadTemperature(void)
{
uchar a,b,t;
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
delay(850);   //等待温度转换结束,不能过短,否则第一次显示不出实际温度,会显示85
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
a=ReadOneChar();   //读取温度值低位
b=ReadOneChar();   //读取温度值高位
a=a>>4;            //低位右移4位,舍弃小数部分
t=b<<4;            //高位左移4位,舍弃符号位
t=t|a;            
return(t);
}
回复

使用道具 举报

6#
ID:62717 发表于 2014-6-8 12:51 | 显示全部楼层
clock_set.h
void keyscan()//键盘扫描程序
{
if(s1==0)//s1键扫描
{
   delay(5);
   if(s1==0)
   {
    TR0=0;
    s1num++;
    while(!s1);//等待键的释放
    switch(s1num)//根据s1的按键次数做相应的处理
    {
     case 1:
      write_com(0x80+0x40+12);
      write_com(0x0f); break;//按键一次,调整光标的形状及位置
     case 2:
      write_com(0x80+0x40+9); break;
     case 3:
      write_com(0x80+0x40+6); break;
     case 4:
      s1num=0;
      write_com(0x0c);
      TR0=1;break;
    }
   }
}
if(s1num)//在s1有被按下的情况下做相应的处理
{
   if(s2==0)//s2按键检测,按下s2键后相应的时、分、秒加1操作
   {
    delay(5);
    if(s2==0)
    {
    while(!s2);//松手检测
     switch(s1num)
     {
      case 1:miao++;
         if(miao==60) miao=0;
         write_1602(12,miao);
         write_com(0x80+0x40+12);break;
      case 2:fen++;
         if(fen==60) fen=0;
         write_1602(9,fen);
         write_com(0x80+0x40+9);break;
      case 3:shi++;
         if(shi==24) shi=0;
         write_1602(6,shi);
         write_com(0x80+0x40+6);break;
      case 4:break;
     }
//     delay(500);//把松手检测部分去除后,按下后时间一直增加
    }
   }
   if(s3==0)//s3按键检测,按下s3键后相应的时、分、秒减1操作
   {
    delay(5);
    if(s3==0)
    {
     while(!s3);//松手检测
     switch(s1num)
     {
     case 1:miao--;
        if(miao==-1) miao=59;
        write_1602(12,miao);
        write_com(0x80+0x40+12);break;
     case 2:fen--;
        if(fen==-1) fen=59;
        write_1602(9,fen);
        write_com(0x80+0x40+9);break;
     case 3:shi--;
        if(shi==-1) shi=23;
        write_1602(6,shi);
        write_com(0x80+0x40+6);break;
     case 4:break;
     }
    // delay(500);//把松手检测部分去除后,按下后时间一直减小
    }
   }
}
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表