找回密码
 立即注册

QQ登录

只需一步,快速开始

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

求助,一个入门级的温度报警器,仿真声光问题求助

[复制链接]
跳转到指定楼层
楼主
我先来说问题:现在设计一个温度报警器,我现在温度显示和调整温度方面已经设计的没有问题了,就是声光报警的问题
比如要求温度超过20度,灯闪烁,声音也断续发声,但是我这部分程序就是写不对,用中断写,结果试的时候发现完全没用,求帮助,这是怎么回事呢?
如何改正呢,谢谢各位!!

/**************************************************************************************
*                DS18B20温度传感器实验              *
实现现象: 具体接线操作请看视频。
   下载程序后,在温度传感器接口处,按照丝印方向插好温度传感器,数码管就会显示
   检测的温度值,
注意事项:                     
***************************************************************************************/
#include "reg52.h"    //此文件中定义了单片机的一些特殊功能寄存器
#include"temp.h"
typedef unsigned int u16;   //对数据类型进行声明定义
typedef unsigned char u8;
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
      sbit LED=P1^7;
  sbit BEEP=P2^7;
  bit flash=0;
bit setup=0;
int cn=0;
char num=0;
u8 DisplayData[8];
u8 code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
/*******************************************************************************
* 函 数 名         : delay
* 函数功能     : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)
{
while(i--);
}

/*******************************************************************************
* 函 数 名         : datapros()
* 函数功能     : 温度读取处理转换函数
* 输    入         : temp
* 输    出         : 无
*******************************************************************************/
void datapros(int temp)   
{
    float tp;  
if(temp< 0)    //当温度值为负数
   {
  DisplayData[0] = 0x40;    //   -
  //因为读取的温度是实际温度的补码,所以减1,再取反求出原码
  temp=temp-1;
  temp=~temp;
  tp=temp;
  temp=tp*0.0625*100+0.5;
  //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
  //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
  //算加上0.5,还是在小数点后面。

   }
  else
   {   
  DisplayData[0] = 0x00;
  tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
  //如果温度是正的那么,那么正数的原码就是补码它本身
  temp=tp*0.0625*100+0.5;
  //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
  //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
  //算加上0.5,还是在小数点后面。
}
DisplayData[1] = smgduan[temp / 10000];
DisplayData[2] = smgduan[temp % 10000 / 1000];
DisplayData[3] = smgduan[temp % 1000 / 100] | 0x80;
DisplayData[4] = smgduan[temp % 100 / 10];
DisplayData[5] = smgduan[100];
}

/*******************************************************************************
* 函数名         :DigDisplay()
* 函数功能   :数码管显示函数
* 输入           : 无
* 输出           : 无
*******************************************************************************/
void DigDisplay()
{
u8 i;
for(i=0;i<6;i++)
{
  switch(i)  //位选,选择点亮的数码管,
  {
   case(0):
    LSA=0;LSB=0;LSC=0; break;//显示第0位
   case(1):
    LSA=1;LSB=0;LSC=0; break;//显示第1位
   case(2):
    LSA=0;LSB=1;LSC=0; break;//显示第2位
   case(3):
    LSA=1;LSB=1;LSC=0; break;//显示第3位
   case(4):
    LSA=0;LSB=0;LSC=1; break;//显示第4位
   case(5):
    LSA=1;LSB=0;LSC=1; break;//显示第5位
  }
  P0=DisplayData[i];//发送数据
  delay(100); //间隔一段时间扫描
  P0=0x00;//消隐
}  
}
/*******************************************************************************
* 函 数 名       : main
* 函数功能   : 主函数
* 输    入       : 无
* 输    出      : 无
*******************************************************************************/
void main()
{    TMOD=0x01;
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
TR0=1;
ET0=1;
while(1)
{        
  datapros(Ds18b20ReadTemp());  //数据处理函数
  //datapros(0x0191);  //数据处理函数
  DigDisplay();//数码管显示函数
   
     
}  
}
   void TIMER0_ISR() interrupt 1
{
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
  cn++;
if(cn>499)
{
  flash=~flash;
  cn=0;
}   
            if(DisplayData[2]==0x5b)
      {
      if(flash==1)
      {
   
     BEEP=~BEEP;
     LED=~LED ;
     }
   
         
         }
         else
         {   
       BEEP=1;
             LED=1;
         }
         
     }  

     具体见附件

0%IRYDG2D)U4576FKMH~RT9.png (155.04 KB, 下载次数: 29)

0%IRYDG2D)U4576FKMH~RT9.png

实验24:DS18B20温度传感器.zip

97.55 KB, 下载次数: 8

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:289777 发表于 2018-4-7 15:13 | 只看该作者
顶!!
回复

使用道具 举报

板凳
ID:289777 发表于 2018-4-7 15:14 | 只看该作者
求帮助啊在线等
回复

使用道具 举报

地板
ID:160834 发表于 2018-4-7 15:38 | 只看该作者
我把你的程序修改了一下。 取消了中断。 把温度判断程序直接放在主程序循环里。 仿真测试下来没问题。
另外 我发现你仿真里的单片机设定的晶振是6MHZ的  如果你实际用的晶振是11.0592或12MHZ的  DS18B20的温度传感器的传输延时要相应改一下
否则会读不出DS18B20的温度值。 这个你在仿真时就可以看出来。

/**************************************************************************************
*                DS18B20温度传感器实验              *
实现现象: 具体接线操作请看视频。
下载程序后,在温度传感器接口处,按照丝印方向插好温度传感器,数码管就会显示
检测的温度值,
注意事项:                     
***************************************************************************************/
#include "reg52.h"    //此文件中定义了单片机的一些特殊功能寄存器
#include"temp.h"
typedef unsigned int u16;   //对数据类型进行声明定义
typedef unsigned char u8;
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit LED=P1^7;
sbit BEEP=P2^7;
bit flash=0;
bit setup=0;
int cn=0;
char num=0;
u8 DisplayData[8];
u8 code smgduan[10]=
{
    0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f
}
;
/*******************************************************************************
* 函 数 名         : delay
* 函数功能     : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)
{
    while(i--);
}

/*******************************************************************************
* 函 数 名         : datapros()
* 函数功能     : 温度读取处理转换函数
* 输    入         : temp
* 输    出         : 无
*******************************************************************************/
void datapros(int temp)   
{
    float tp;  
    if(temp< 0)    //当温度值为负数
    {
        DisplayData[0] = 0x40;    //   -
        //因为读取的温度是实际温度的补码,所以减1,再取反求出原码
        temp=temp-1;
        temp=~temp;
        tp=temp;
        temp=tp*0.0625*100+0.5;
        //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
        //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
        //算加上0.5,还是在小数点后面。
        
    }
    else
    {   
        DisplayData[0] = 0x00;
        tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
        //如果温度是正的那么,那么正数的原码就是补码它本身
        temp=tp*0.0625*100+0.5;
        //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
        //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
        //算加上0.5,还是在小数点后面。
    }
  
    DisplayData[1] = smgduan[temp / 10000];
    DisplayData[2] = smgduan[temp % 10000 / 1000];
    DisplayData[3] = smgduan[temp % 1000 / 100] | 0x80;
    DisplayData[4] = smgduan[temp % 100 / 10];
    DisplayData[5] = smgduan[100];
}

/*******************************************************************************
* 函数名         :DigDisplay()
* 函数功能   :数码管显示函数
* 输入           : 无
* 输出           : 无
*******************************************************************************/
void DigDisplay()
{
    u8 i;
    for(i=0;i<6;i++)
    {
        switch(i)  //位选,选择点亮的数码管,
        {
            case(0):
            LSA=0;LSB=0;LSC=0; break;//显示第0位
            case(1):
            LSA=1;LSB=0;LSC=0; break;//显示第1位
            case(2):
            LSA=0;LSB=1;LSC=0; break;//显示第2位
            case(3):
            LSA=1;LSB=1;LSC=0; break;//显示第3位
            case(4):
            LSA=0;LSB=0;LSC=1; break;//显示第4位
            case(5):
            LSA=1;LSB=0;LSC=1; break;//显示第5位
        }
        P0=DisplayData[ i];//发送数据
        delay(100); //间隔一段时间扫描
        P0=0x00;//消隐
    }  
}
/*******************************************************************************
* 函 数 名       : main
* 函数功能   : 主函数
* 输    入       : 无
* 输    出      : 无
*******************************************************************************/
void main()
{
   
    while(1)
    {        
        datapros(Ds18b20ReadTemp());  //数据处理函数
        DigDisplay();//数码管显示函数
   
     if(DisplayData[2]==0x5b)   
       //你这种写法这里只能判断20度到29度  30度到39 需要写成 if(DisplayData[2]==0x5b || DisplayData[2]==0x4f)  依次类推
       //最好改成判断未转码的数值。也就是TEMP值。 视你具体要求判断的温度范围。

       {
          BEEP=~BEEP;
          LED=~LED ;
        }
        else
        {   
           BEEP=1;
           LED=1;
        }
    }  
}


评分

参与人数 1黑币 +70 收起 理由
admin + 70 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

5#
ID:289777 发表于 2018-4-7 16:01 | 只看该作者
QIANLILI 发表于 2018-4-7 15:38
我把你的程序修改了一下。 取消了中断。 把温度判断程序直接放在主程序循环里。 仿真测试下来没问题。
另 ...

您好,程序我看了,我一开始确实也没有用中断,就是在主函数里和你写的一样
但是目前来看你改的程序,发生报警的时候灯光和声音闪烁太快了啊,需要亮一下闪一下,0.5s这样间断的呀,但是你现在的这个实在是太快了,我一开始也是这样的问题,后来我就加delay函数,你看我是这么加的

          BEEP=~BEEP;
          LED=~LED ;
                  delay(5000);,在这里加了一个delay函数,但是不行啊,这样的话运行仿真的时候,屏幕就一直闪,数字也显示的不对了,这是怎么回事,怎么改才能达到目的呢?
回复

使用道具 举报

6#
ID:303207 发表于 2018-4-7 16:22 | 只看该作者
en,声电控制需要很
回复

使用道具 举报

7#
ID:289777 发表于 2018-4-7 19:16 | 只看该作者
还有人知道如何做吗,楼上说的不太对
回复

使用道具 举报

8#
ID:160834 发表于 2018-4-7 21:57 | 只看该作者
你用数码管做动态显示  本身靠的是人眼的视觉暂留现象。单片机不停的处理动态显示 再处理其它任务时 必会影响动态显示的时间  导致数码管闪烁时间延迟。 你把其它程序放中断里 运行时间长的话 一样会影响主程序的动态显示时间。 如果你非要用数码管显示的话  可以用最小系统,C51的话用Small RTOS  。也可以用74H595驱动数码管就不是动态扫描了。 不影响主程序做其它事。 也可以用1602等液晶做显示都不会影响主程序做其它事。
如果你软件不想改变  那么你只有把闪烁的LED和蜂鸣器做成独立的硬件组件。 也就是一个LED组件通电就会每隔1秒闪一次,同时蜂鸣器用有源蜂鸣器,通电就响。断电就停的那种。

评分

参与人数 1黑币 +10 收起 理由
danpianji3501 + 10 很给力!

查看全部评分

回复

使用道具 举报

9#
ID:289777 发表于 2018-4-8 11:01 | 只看该作者
顶一下还有知道的吗,之前楼层回复的不是很好,没有解决问题,请问谁能在看一下这个问题
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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