顶一下还有知道的吗,之前楼层回复的不是很好,没有解决问题,请问谁能在看一下这个问题 |
你用数码管做动态显示 本身靠的是人眼的视觉暂留现象。单片机不停的处理动态显示 再处理其它任务时 必会影响动态显示的时间 导致数码管闪烁时间延迟。 你把其它程序放中断里 运行时间长的话 一样会影响主程序的动态显示时间。 如果你非要用数码管显示的话 可以用最小系统,C51的话用Small RTOS 。也可以用74H595驱动数码管就不是动态扫描了。 不影响主程序做其它事。 也可以用1602等液晶做显示都不会影响主程序做其它事。 如果你软件不想改变 那么你只有把闪烁的LED和蜂鸣器做成独立的硬件组件。 也就是一个LED组件通电就会每隔1秒闪一次,同时蜂鸣器用有源蜂鸣器,通电就响。断电就停的那种。 |
参与人数 1 | 黑币 +10 | 收起 理由 |
---|---|---|
![]() | + 10 | 很给力! |
还有人知道如何做吗,楼上说的不太对 |
en,声电控制需要很 |
QIANLILI 发表于 2018-4-7 15:38 您好,程序我看了,我一开始确实也没有用中断,就是在主函数里和你写的一样 但是目前来看你改的程序,发生报警的时候灯光和声音闪烁太快了啊,需要亮一下闪一下,0.5s这样间断的呀,但是你现在的这个实在是太快了,我一开始也是这样的问题,后来我就加delay函数,你看我是这么加的 BEEP=~BEEP; LED=~LED ; delay(5000);,在这里加了一个delay函数,但是不行啊,这样的话运行仿真的时候,屏幕就一直闪,数字也显示的不对了,这是怎么回事,怎么改才能达到目的呢? |
我把你的程序修改了一下。 取消了中断。 把温度判断程序直接放在主程序循环里。 仿真测试下来没问题。 另外 我发现你仿真里的单片机设定的晶振是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; } } } |
求帮助啊在线等 |
顶!! |