广西河池学院
广西高校重点实验室培训基地
系统控制与信息处理重点实验室
本篇博客来自河池学院:OpenWRT无线路由
写作时间:2020年8月13日9:00
睡眠监测器
在进行了短期的keil51单片机的学习之后,在基于学到知识下设计并制作了一个小项目——睡眠监控器。
- 项目简介
睡眠监控器使用过程无需手动操作,全程实现自动显示和监控警报,使用STC89C52RC主控芯片,外加DHT11温湿度传感器和超声波传感器以及DS1302时钟芯片实现主要功能。使用12864显示屏自动换页,页面切换睡眠时的温湿度、睡眠时长、前方安全距离。采用超声波传感器检测距离使蜂鸣器产生警报。
项目使用视频 - 项目思路与问题解决
首先为主函数代码——在主函数中调用了各种模块的.h,并写入了想要实现的功能,并添加了实现自动换页的“状态机”函数以及周期停留换页,由于所学的知识有限,以及对51单片机的应用不强,一开始在实现自动换页并且同时实现数据刷新时,遇到了很多的问题,比如:不能全部的循环换页,有些页面显示时间非常短,数据不能正常刷新,页面闪烁等,并且由最开始的使用延时函数条件语句进行换页,到使用for循环换页,到最后的自己在网上查询调试猜得出想要的效果,使用延时函数换页不能很好地实现各个页面的正常循环,并且页面闪烁,数据不正常,for循环的效果页面闪烁很快,其他也不理想,而使用screen_handle()函数以及周期循环换页可以实现稳定的界面。并写入了首页显示函数,以及需要调用的各个模块中的函数。
#include <dth11.h>
#include <12864x.h>
#include <DS1302.h>
#include <csb.h>
#include <intrins.h>
#define SHOW_SCR_1 1
#define SHOW_SCR_2 2
#define SHOW_SCR_3 3
void Rec_DHTIO();
void LED_Display();
void show12864_1();
//int csbProcess_F();
int state_machine;//状态机
void screen_handle()
{
static int state_old = 1;
if(state_old != state_machine)
{
clr_screen();
state_old = state_machine;
}
}
void show12864_4()
{
LCD_12864_display(1,1,"睡");
LCD_12864_display(1,2,"眠");
LCD_12864_display(1,3,"监");
LCD_12864_display(1,4,"控");
LCD_12864_display(1,5,"器");
LCD_12864_display(3,2,"周");
LCD_12864_display(3,3,"诗");
LCD_12864_display(3,4,"华");
LCD_12864_display(4,2,"王");
LCD_12864_display(4,3,"秋");
LCD_12864_display(4,4,"凤");
}
void main ()
{
LCD_12864_INIT(); //12864初始化
DS1302_Init(); //DS1302初始化
DS1302_Write_Time(); //初始化数据
show12864_4();
while(1)
{
static uint count = 0;//当数据第二次进来循环或者函数时,数据不变
baojin();
Rec_DHTIO();
if(count % 18 < 3)
{
state_machine = SHOW_SCR_1;
show12864_1();
}
if((count % 18 >= 3) && (count % 18 < 12))
{
state_machine = SHOW_SCR_2;
show12864_2();
}
if(count % 18 >= 12)
{
state_machine = SHOW_SCR_3;
show12864_3();
}
screen_handle();
delayms(50);
count ++;
}
while(1);
}
在主函数之外还有值得说一下的每一页的显示函数,如下类似的一共四个页面的显示函数。清屏函数不能放在显示函数中,因为在页面停留时,会出现不停地页面闪烁,因为你的页面在“擦了有写”,而使用“状态机”判断换页就相当于“边擦边写”,数据刷新,页面稳定。
void show12864_1()
{
Rec_DHTIO();
LCD_12864_display(1,0,lcd);
LCD_12864_display(3,1,lcd1);
LCD_12864_display(4,1,lcd2);
LCD_Display();
}
void show12864_3()
{
num=csbProcess_F();
display_int(3,4,num);
LCD_12864_display(1,1,"当");
LCD_12864_display(1,2,"前");
LCD_12864_display(1,3,"安");
LCD_12864_display(1,4,"全");
LCD_12864_display(1,5,"距");
LCD_12864_display(1,6,"离");
LCD_12864_display(1,7,":");
LCD_12864_display(3,5,"cm");
}
程序的主要特点就位这些,但是对于模块函数的了解也并不是很深入,能够学会运用也是不错的进步。
- 硬件问题
在最开始的项目设想中,是希望在12864上显示温湿度,并在数码管显示时钟,让蜂鸣器响与流水灯全亮实现报警的作用,但是由于使用的开发板中12864显示屏与流水灯和数码管串联使用,在使用显示屏的同时,数码管与流水灯会出现不可控的不同程度和位置的闪烁,便想到了在显示屏换页,其次便是蜂鸣器的调试花了许多时间,从开发板没有排针与芯片蜂鸣器不能使用,补焊排针补齐芯片,之后又发现开发板上的蜂鸣器有损坏,不能正常响亮,所以从新焊接了蜂鸣器,最后一个情况便是链接蜂鸣器引脚的冲突,在高位引脚上响声不受控制,某些引脚上与显示屏使用冲突也不可以,一部分引脚已被占用,最后在学长的调试下选择了P23,置低不响。在硬件问题解决后,由于换页和数据刷新的混乱,以至于蜂鸣器不能灵敏的报警,在后面和方面处理完成,硬件也正常工作。
报警代码:
void baojin()
{
uint distance;
distance = csbProcess_F(); //获取当前距离值
if(distance <100)
{
FENG = 1;
delayms(500);
FENG = 0;
}
else
{
FENG = 0;
}
}
- 最后的总结语录
一个完整的项目,需要程序与硬件的完美配合,就像大脑与肢体的神经传递与表达,需要一定路径,特定的器官,准确的语句。