项目概要
自制一款可以联网操作的呼叫器正向手机发送ID可以控制响起,反向温度过高进行报警,手机网页端可以通过MQTT协议和ESP8266模块通信,ESP8266再通过串口和51单片机进行通信。添加温度报警功能,C51单片机通过获取到温度利用串口和ESP8266通信,将温度数据传递到ESP8266模块上。ESP8266模块再通过HTTP请求向后台Java接口进行数据的上传,保存到数据库中,并且实现数据的实时显示。该项目,不是特别的完美可以有很多创新和改进的地方,但主要实现了ESP8266的MQTT、HTTP网络通信协议应用,还有串口通信的使用,大家可以当做例子进行学习。
C51部分模块的使用
OLED:第一行,进行本机的ID号显示,当前环境温度的显示,第二行显示当前所叫到号的ID。
震动马达/蜂鸣器:当叫号ID和本机ID相匹配的时候,震动马达和蜂鸣器响起。
DS18B20:温度模块对环境温度进行获取,实时的显示到OLED屏幕上,并经过串口发送到WIFi模块。
其他模块的选取如下表所示:
Proteus8.11仿真图
ID表示显示本机ID号,Te表示显示温度和U2即DS18B20的温度一致,现在是14度,则屏幕显示也为14度,CurrentID表示当前呼叫的ID号。左边按键从上至下功能依次是,控制复位按键(当震动马达和蜂鸣器响起的时候可以进行关闭)、设置加(对本机ID号进行加设置)、设置减(对本机ID号进行减设置)。D2震动马达利用红色LED进行仿真代替,ESP8266模块利用P3.0和P3.1进行RXD和TXD的交叉相连进行模拟。
KeilC代码
[这里对各个模块的头文件和驱动代码不做过多的讲解,想必大家也有基础,只对整个设计思路进行讲解。]
可以看下方代码的注释是否的清楚没有难度大的地方,重点为温度发送函数和数据ID接受函数为重点。
#include <reg51.h>
#include "oled.h"
#include "DELAY.h"
#include "DS18B20.h"
#define uchar unsigned char
uchar buf,RXData,RXStart,number;
uchar ID[4]={4,3,2,1};
uchar ReceiveId[4]={0,0,0,0};
sbit ctrlKey = P1^2; //控制复位按键
sbit addNumberKey = P1^5; //加按键
sbit deleteNumberKey = P1^7; //减按键
sbit motor = P0^0; //震动马达
sbit sounder = P0^1; //蜂鸣器
int RT; //温度存储变量
int i,j,k,f,f_ctrl; //一些变量
void config(); //初始化配置
void sendid(int i); //发送温度函数
void senddata(uchar buf); //字节发送函数
void init_serial(); //串口初始化函数
void receive(); //串口接受函数
void ControllerSlave(uchar buf);
void KeyControl(); //按键控制函数
//主函数
void main(){
config(); //变量及模块初始化
while(1){
DS18B20_Init(); //DS18B20温度传感器初始化
ds18b20_changetemp(); //获取改变后的温度
if(RT!=ds18b20_gettemp()/10){ //对温度进行存储,如果温度发送改变则发送当前温度
RT=ds18b20_gettemp()/10;
sendid(RT); //发送改变后的温度
}
KeyControl(); //按键控制函数
OLED_ShowString(0,0,"ID:",16); //显示本机ID号
OLED_ShowNum(24,0,ID[0],1,16); //ID4位数依次显示
OLED_ShowNum(32,0,ID[1],1,16);
OLED_ShowNum(40,0,ID[2],1,16);
OLED_ShowNum(48,0,ID[3],1,16);
OLED_ShowString(67,0,"Te:",16); //显示当前的温度
OLED_ShowNum(104,0,RT,2,16);
OLED_ShowChar(122,0,'C',16);
}
}
void config(){
P2=0x40; //本机ID号的初始化
k=j=0; //以下都是变量的初始化设置
i=1;
RXData=0;
RXStart=0;
motor=1;
sounder=0;
init_serial(); //串口初始化
OLED_Init(); //初始化OLED
OLED_ColorTurn(0); //0正常显示,1 反色显示
OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示
OLED_ShowString(0,2,"CurrentID:",16); //初始化显示当前所叫到号的ID默认为0000
OLED_ShowNum(88,2,ReceiveId[0],1,16);
OLED_ShowNum(96,2,ReceiveId[1],1,16);
OLED_ShowNum(104,2,ReceiveId[2],1,16);
OLED_ShowNum(112,2,ReceiveId[3],1,16);
}
void KeyControl(){
if(ctrlKey==0){
motor=1; //当控制按键按下时候蜂鸣器和震动模块关闭
sounder=0;
}
if(ID[k]!=9){ //当加的数据不等于9时候进行加操作
if(addNumberKey==0){ //当按下加操作按键时候
ID[k]++; //ID[k]里面的数据进行加操作
if(ID[k]==9){ //当ID[k]里面的数据等于9的时候
if(k!=3){ //k不等于3的时候
k++; //k进行加操作
}
}
}
}
if(ID[k]!=0){ //当减的数据不等于0的时候进行减操作
if(deleteNumberKey==0){ //当按下减操作的按键时候
ID[k]--; //ID[k]里面的数据进行减操作
if(ID[k]==0){ //ID[k]里面的数据不等于0的时候
if(k!=0){ //k不等于0的时候
k--; //k进行减操作
}
}
}
}
}
//温度发送函数
void sendid(int i){
senddata(0x30+i/10); //发送温度的十位
senddata(0x30+i%10); //发送温度的个位
senddata('$'); //发送结束标识符$
Delay(100);
}
//发送数据函数
void senddata(uchar buf)
{
/* 发送数据 */
TI = 0;
TB8 = 0; // 发送数据帧
SBUF =buf;
while(!TI);
TI = 0;
}
//串口初始化函数
void init_serial()
{
TMOD = 0x20; // 定时器T1使用工作方式2
TH1 = 250;
TL1 = 250;
TR1 = 1; // 开始计时
PCON = 0x80; // SMOD = 1
SCON = 0xd0; // 工作方式,9位数据位,波特率9600kbit/s,允许接收
ES = 1; //开串口中断
TR1 = 1; //启动定时器1
EA = 1; //中断 总开关
}
void receive() interrupt 4 //串口中断服务函数
{
ES = 0; //关闭串口中断
if(RI){ //再次判断,是否接收到数据(接收到数据后,RI会置1,需手动清0)
RXData = SBUF;
if(RXData == '*'){
RXStart=0; //关闭数据接收
j=0; //接受控制变量清零
number=0; //数据转换存储变量清零
OLED_Clear(); //屏幕清零
OLED_ShowString(0,2,"CurrentID:",16); //显示当前的呼叫ID
OLED_ShowNum(88,2,ReceiveId[0],1,16);
OLED_ShowNum(96,2,ReceiveId[1],1,16);
OLED_ShowNum(104,2,ReceiveId[2],1,16);
OLED_ShowNum(112,2,ReceiveId[3],1,16);
for(f=0;f<4;f++){ //进行4位逐个校验
if(ReceiveId[f]==ID[f]){
f_ctrl+=0; //相同时控制变量加0
}else{
f_ctrl+=1; //不同时控制变量加1
}
}
if(f_ctrl==0){ //当ID校验控制变量为0时候表示验证通过
motor=0; //马达震动
sounder=1; //蜂鸣器响起
}
f_ctrl=0; //ID校验控制变量清零
}
if(RXStart == 1){ //接受开启
if(j!=4){ //只支持接收4位数字
number=RXData-0x30; //将数据文本型转换为字符型
ReceiveId[j]=number; //存储数据
}
j++;
}
if(RXData == '$'){ //数据结束标志
RXStart=1; //数据接收开启标志
}
}
RI = 0; //清除接收标志位
ES = 1; //重新开启串口中断
}
小结
代码和文件比较多,如果想参考可以到评论区留言,我私发给你。文中有不清楚的地方也可以私信我,或者评论区留言。本文关注度高的话会更新中和下的内容,分享给大家,制作不易,请大家多多评论,多多点赞转发!!!