将DS18B20连接在51单片机上之后,通过按键k4发送温度数据到上位机
程序实现的功能:
按键k1、k2:ESP8266在STA模式下连接上位机
K3:发送数据
具体代码如下:
#include "reg52.h"
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
uchar aa[]={0,0,0,0,0}; //数组初始值
uint wd; //温度
sbit k1=P3^5; //定义P35口是k1
sbit k2=P3^4;
sbit k3=P3^3;
sbit k4=P3^2;
sbit led1=P1^0; //定义P10口是led1
sbit led2=P1^1;
sbit led3=P1^2;
sbit led4=P1^3;
sbit DQ=P2^0;
u8 dat;
void Init(void);//串口初始化函数
void Init_DS18B20(void);//DS18B20初始化
void Delay_ms(u16 n);//延时子函数
void Sent_ZF(u8 dat);//发送一个字节
void AT_Send_String(u8 *string);//发送字符串
void ESP8266_Init();//ESP8266初始化
void fasong();
void shuju();
void wendu();
void show();
void Init(void) //串口初始化函数
{
TMOD=0x20; //定时器工作方式2,8位自动重载(0010 0000)
TL1=0xfd; //装入初值
TH1=0xfd;
TR1=1; //启动定时器1
REN=1; //允许串行口接收数据
SM0=0; //工作方式1,10位异步收发
SM1=1;
EA=1; //打开全局中断控制
ES=1; //打开串行口中断
}
/*******************************************************************************
* 函 数 名 : delay
* 函数功能 : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void Delay_ms(u16 i) //串口通信延时函数
{
while(i--);
}
void delay(uint i) //DS18B20延时函数,延时5us
{
do
{
_nop_();
_nop_();
_nop_();
i--;
}
while(i);
}
void DS() //温度传感器的初始化
{
uchar x=0;
DQ=1; //首先先拉高电平,为复位做准备
delay(10); //延迟一下
DQ=0; //将电平拉低,延迟至少480us
delay(120); //一次为5us,此处延迟600us,足以等待存在脉冲
DQ=1; //复位信号给出后,将电平拉高,等待获取存在脉冲
delay(16); //延迟15~60us,此处延迟90us,足以给存在脉冲时间
x=DQ; //读取存在脉冲
delay(80); //读取存在脉冲,存在脉冲至少为60us到240us的低电平信号,这里给出400us
DQ=1;
}
uchar Read1b() //读取1个字节
{
uchar i=0;
uchar dat=0;
for(i=0;i<8;i++)
{
DQ=0; //数据线拉成低电平,表示读数据的开始
delay(1); //读数据时,需要低电平保持至少1us
DQ=1; //释放数据总线
dat>>=1; //一位一位的保存读取到的数据,所以需要移位处理
if(DQ) //读取数据的高电平
dat|=0x80; //与操作一下,得到我们需要的数据,读取数据需要在15us内读取,这样才能保证读取的数据是正确的
delay(11);
}
return(dat);
}
void Write1b(uchar dat) //写入1个字节
{
uchar i=0;
for(i=0;i<8;i++)
{
DQ=0;
_nop_();
DQ=dat&0x01;
delay(12);
DQ=1;
dat>>=1;
delay(5);
}
}
uint Get() //得到温度数据
{
uchar templ,temph,tt;
uint t;
DS(); //初始化
Write1b(0XCC); //因为我们是一个单片机和一个DS18B20连接,故在对ROM指令操作时,选择0xCC跳过ROM指令,不对ROM编码作出反应
Write1b(0x44); //RAM操作中的温度转换指令,将转换的温度存入RAM的1,2地址
DS(); //初始化
Write1b(0xcc); //同上
Write1b(0xbe); //从RAM中读取数据,从0地址读到9地址
templ=Read1b(); //从DS18B20中读取温度数据中低八位
temph=Read1b(); //从DS18B20中读取温度数据中的高八位,温度数据由16位数据组成
t=temph;
t<<=8;
t=t|templ;
tt=t*0.0625; /*真实温度的转换*/
return(tt);
}
void show(uint wd) //将得到的温度数据放到aa[]数组里
{
aa[0]=wd/10+'0';
aa[1]=wd%10+'0';
}
/*******************************************************************************
* 函 数 名 : keypros
* 函数功能 : 按键处理函数,判断按键K1是否按下
*******************************************************************************/
void keypros1() //按键1
{
if(k1==0) //检测按键K1是否按下
{
Delay_ms(1000); //消除抖动 一般大约10ms
if(k1==0) //再次判断按键是否按下
{
led1=~led1; //led状态取反
ESP8266_Init(); //8266初始化,设置为STA模式,连接WiFi
}
while(!k1); //检测按键是否松开
}
}
void keypros2() //按键2
{
if(k2==0) //检测按键K2是否按下
{
Delay_ms(1000); //消除抖动 一般大约10ms
if(k2==0) //再次判断按键是否按下
{
led2=~led2; //led状态取反
fasong(); //接入服务器
}
while(!k2); //检测按键是否松开
}
}
void keypros3() //按键3
{
if(k3==0) //检测按键K2是否按下
{
Delay_ms(1000); //消除抖动 一般大约10ms
if(k3==0) //再次判断按键是否按下
{
led3=~led3; //led状态取反
shuju(); //发送数据
}
while(!k3); //检测按键是否松开
}
}
void keypros4() //按键4
{
if(k4==0) //检测按键K2是否按下
{ show(Get());
Delay_ms(1000); //消除抖动 一般大约10ms
if(k4==0) //再次判断按键是否按下
{
led4=~led4; //led状态取反
wendu(); //发送温度数据
}
while(!k4); //检测按键是否松开
}
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
Init();
P1=0Xff;
while(1)
{
keypros1(); //按键处理函数1
keypros2();
keypros3();
keypros4();
}
}
void Sent_ZF(u8 dat) //发送一个字节
{
ES=0; //关闭串行口中断
TI=0; //关闭发送中断标志位
SBUF=dat;
while(!TI);
TI=0;
ES=1; //打开串行口中断
}
void AT_Send_String(u8 *string) //发送字符串
{
while(*string!='\0')
{
Sent_ZF(*string);
string++;
Delay_ms(1000);
}
}
void ESP8266_Init() //ESP8266初始化
{
AT_Send_String("AT+CWMODE=1\r\n"); //设置工作方式为STA模式
Delay_ms(1000000);
Delay_ms(1000000);
AT_Send_String("AT+RST\r\n"); //重启模块
Delay_ms(1000000);
Delay_ms(1000000);
AT_Send_String("AT+CIFSR\r\n"); //查看WiFi列表
Delay_ms(1000000);
Delay_ms(1000000);
AT_Send_String("AT+CWJAP=\"360WiFi-0F605E\",\"123456789\"\r\n"); //连接WiFi
Delay_ms(100000000);
Delay_ms(100000000);
}
void fasong()
{
AT_Send_String("AT+CIPMUX=0\r\n"); //设置为单连接模式,启动模块
Delay_ms(1000000);
Delay_ms(1000000);
AT_Send_String("AT+CIPSTART=\"TCP\",\"192.168.0.14\",8086\r\n"); //服务器的设置端口
Delay_ms(1000000);
Delay_ms(1000000);
AT_Send_String("AT+CIPMODE=1\r\n"); //开启透传
Delay_ms(1000000);
Delay_ms(1000000);
AT_Send_String("AT+CIPSEND\r\n"); //进入透传模式
Delay_ms(1000000);
Delay_ms(1000000);
AT_Send_String("OK"); //发送OK,连接成功
Delay_ms(1000000);
Delay_ms(1000000);
}
void shuju()
{
AT_Send_String("niuwentao\r\n"); //发送字符串
Delay_ms(1000000);
Delay_ms(1000000);
}
void wendu() //发送温度数据
{
AT_Send_String("{\"temp\":");
Delay_ms(1000);
AT_Send_String(aa);
Delay_ms(1000);
AT_Send_String("}");
Delay_ms(1000);
AT_Send_String("\r\n");
Delay_ms(1000);
}
void InterruptUART() interrupt 4 //控制小灯开关
{
RI=0; //清零
dat= SBUF; //收到的数据占存到SBUF中
{
if(dat=='o')
{
led4=0;
}
if(dat=='f')
{
led4=1;
}
}
}
|