使用DS18B20,ESP8266,实现WIFI传输温度,底层部分代码。其中WIFI是作为服务器,上位机作为客户端。
单片机源程序如下:
- /***********************
- 程序名:wifi_3.c
- 功能:单片机与手机通信,实现温度信息的传输
- 编程人: baxlumen
- ************************/
- #include "reg52.h"
- #include<intrins.h>
- #define uint unsigned int
- #define uchar unsigned char
- #define ulong unsigned long
- typedef unsigned int u16;
- typedef unsigned char u8;
- sbit DSPORT=P3^7;
- sbit moto=P1^1;
- sbit CLK = P3^6; //时钟
- sbit DIN = P3^4; //输入
- sbit CS = P3^5; //片选
- #define LCD1602_DATAPINS P0
- sbit LCD1602_E=P2^7;
- sbit LCD1602_RW=P2^5;
- sbit LCD1602_RS=P2^6;
- u16 sun; //光照
- int temp;
- int sdata; //温度
- int xiaoshu1;
- int xiaoshu2;
- float tp;
- uchar DisplayData[]={0,0,0,0,0,0,0,0};
- /*****************
- 定义程序中所需要的延时
- ********************/
- void Delay1ms(uint y)
- {
- uint x;
- for( ; y>0; y--)
- {
- for(x=110; x>0; x--);
- }
- }
- void delay(u16 i)
- {
- while(i--);
- }
- void delay1ms()
- {
- unsigned char i;
- for(i=124;i>0;i--); //延时124*8+10=1002us
- }
- /*******************************************************************************
- * 函 数 名 : Lcd1602_Delay1ms
- * 函数功能 : 延时函数,延时1ms
- * 输 入 : c
- * 输 出 : 无
- * 说 名 : 该函数是在12MHZ晶振下,12分频单片机的延时。
- *******************************************************************************/
- void Lcd1602_Delay1ms(uint c) //误差 0us
- {
- uchar a,b;
- for (; c>0; c--)
- {
- for (b=199;b>0;b--)
- {
- for(a=1;a>0;a--);
- }
- }
- }
- /****************
- 初始化DS18B20
- ****************/
- uchar Ds18b20Init()
- {
- uchar i;
- DSPORT = 0; //将总线拉低480us~960us
- i = 70;
- while(i--);//延时642us
- DSPORT = 1; //然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低
- i = 0;
- while(DSPORT) //等待DS18B20拉低总线
- {
- Delay1ms(1);
- i++;
- if(i>5)//等待>5MS
- {
- return 0;//初始化失败
- }
-
- }
- return 1;//初始化成功
- }
- void Ds18b20WriteByte(uchar dat)//写入数据
- {
- uint i, j;
- for(j=0; j<8; j++)
- {
- DSPORT = 0; //每写入一位数据之前先把总线拉低1us
- i++;
- DSPORT = dat & 0x01; //然后写入一个数据,从最低位开始
- i=6;
- while(i--); //延时68us,持续时间最少60us
- DSPORT = 1; //然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值
- dat >>= 1;
- }
- }
- uchar Ds18b20ReadByte() //读数据
- {
- uchar byte, bi;
- uint i, j;
- for(j=8; j>0; j--)
- {
- DSPORT = 0;//先将总线拉低1us
- i++;
- DSPORT = 1;//然后释放总线
- i++;
- i++;//延时6us等待数据稳定
- bi = DSPORT; //读取数据,从最低位开始读取
- byte = (byte >> 1) | (bi << 7);
- i = 4; //读取完之后等待48us再接着读取下一个数
- while(i--);
- }
- return byte;
- }
- void Ds18b20ChangTemp() //设置DS18B20
- {
- Ds18b20Init();
- Delay1ms(1);
- Ds18b20WriteByte(0xcc); //跳过ROM操作命令
- Ds18b20WriteByte(0x44); //温度转换命令
- //Delay1ms(100); //等待转换成功,而如果你是一直刷着的话,就不用这个延时了
-
- }
- void Ds18b20ReadTempCom() //读取温度数据
- {
- Ds18b20Init();
- Delay1ms(1);
- Ds18b20WriteByte(0xcc); //跳过ROM操作命令
- Ds18b20WriteByte(0xbe); //发送读取温度命令
- }
- void Ds18b20ReadTemp() //将温度数据转化为十进制
- {
-
- uchar tmh, tml,tem,tem2,tem3;
- Ds18b20ChangTemp(); //先写入转换命令
- Ds18b20ReadTempCom(); //然后等待转换完后发送读取温度命令
- tml = Ds18b20ReadByte(); //读取温度值共16位,先读低字节
- tmh = Ds18b20ReadByte(); //再读高字节
- sdata = tml/16+tmh*16;
- if(sdata>29)
- //直流电机,当温度数值超过30度时启动
- {
- moto=1;
- Delay1ms(3000);
- moto=0;
- }
- tem=tml/16+tmh*16;
- xiaoshu1 = (tml&0x0f)*10/16; //小数第一位
- xiaoshu2 = (tml&0x0f)*100/16%10;//小数第二位
- tem2=(tml&0x0f)*10/16;
- tem3=(tml&0x0f)*100/16%10;
-
- DisplayData[0] = sdata/10;
- DisplayData[1] = sdata%10;
- DisplayData[2] = '.';
- DisplayData[3] =xiaoshu1;
- DisplayData[4] =xiaoshu2;
-
- }
- /********************
- 串口通信初始化
- *********************/
- void UsartInit()
- {
- SCON=0X50; //设置为工作方式1
- TMOD=0X20; //设置计数器工作方式2
- PCON=0X80; //波特率加倍
- TH1=0XF3; //计数器初始值设置,注意波特率是4800的
- TL1=0XF3;
- ES=1; //打开接收中断
- EA=1; //打开总中断
- TR1=1; //打开计数器
- }
- void send(uchar *p) //串口发送
- {
- while(*p != '\0')
- {
- SBUF = *p;
- while(!TI);
- TI = 0; //如果发送完毕,硬件会置位TI
- p++; //TI清零
- }
- }
- void zhuanhuan(int i)
- {
- switch(i){ //温度数据的十位
- case 1:
- send("1");
- break;
- case 2:
- send("2");
- break;
- case 3:
- send("3");
- break;
- case 4:
- send("4");
- break;
- case 5:
- send("3");
- break;
- case 6:
- send("6");
- break;
- case 7:
- send("7");
- break;
- case 8:
- send("8");
- break;
- case 9:
- send("9");
- break;
- case 0:
- send("0");
- break;
- }
- }
- void zhuan2(int i)
- {
- switch(i){ //温度数据的十位
- case 1:
- send("1\r\n");
- break;
- case 2:
- send("2\r\n");
- break;
- case 3:
- send("3\r\n");
- break;
- case 4:
- send("4\r\n");
- break;
- case 5:
- send("5\r\n");
- break;
- case 6:
- send("6\r\n");
- break;
- case 7:
- send("7\r\n");
- break;
- case 8:
- send("8\r\n");
- break;
- case 9:
- send("9\r\n");
- break;
- case 0:
- send("0\r\n");
- break;
- }
- }
- /**********************
- * 函数功能:将温度光照数据转化为字符串类型,并发送出去
- *
- ***********************/
- void chuansong()
- {
- zhuanhuan(sdata/10);
- zhuanhuan(sdata%10);
- send(".");
- zhuanhuan(xiaoshu1);
- zhuan2(xiaoshu2);
- zhuanhuan(sun/1000);
- zhuanhuan(sun%1000/100);
- zhuanhuan(sun%1000%100/10);
- zhuan2(sun%1000%100%10);
- }
- void SPI_Start(void) //初始化数模SPI
- {
- CLK = 0;
- CS = 1;
- DIN = 1;
- CLK = 1;
- CS = 0;
- }
- void SPI_Write(uchar dat) //使用SPI写入数据
- {
- uchar i;
- CLK = 0;
- for(i=0; i<8; i++)
- {
- DIN = dat >> 7; //放置最高位
- dat <<= 1;
- CLK = 0; //上升沿放置数据
- CLK = 1;
- }
- }
- uint SPI_Read(void) //使用SPI读取数据
- {
- uint i, dat=0;
- CLK = 0;
- for(i=0; i<12; i++) //接收12位数据
- {
- dat <<= 1;
- CLK = 1;
- CLK = 0;
- dat |= DSPORT;
- }
- return dat;
- }
- uint Read_AD_Data(uchar cmd) //读取数摸数据
- {
- uchar i;
- uint AD_Value;
- CLK = 0;
- CS = 0;
- SPI_Write(cmd);
- for(i=6; i>0; i--); //延时等待转换结果
- CLK = 1; //发送一个时钟周期,清除BUSY
- _nop_();
- _nop_();
- CLK = 0;
- _nop_();
- _nop_();
- AD_Value=SPI_Read();
- CS = 1;
- return AD_Value;
- }
- void datapros() //读取光照值,设置读取间隔
- {
- static u8 i;
-
- if(i==5)
- {
- i=0;
- sun = Read_AD_Data(0xA4); // AIN2 光敏电阻
- }
- i++;
-
- }
- /*************************
- * 函数功能:将光照值按位放于字符数组DisplayData中
- *
- **************************/
- void suntr()
- {
- int sun1,sun2,sun3;
- sun1=sun%1000/100;
- sun2=sun%1000%100/10;
- sun3=sun%1000%100%10;
- DisplayData[5]=sun1;
- DisplayData[6]=sun2;
- DisplayData[7]=sun3;
-
- }
- /*******************************************************************************
- * 函 数 名 : LcdWriteCom
- * 函数功能 : 向LCD写入一个字节的命令
- * 输 入 : com
- * 输 出 : 无
- *******************************************************************************/
- #ifndef LCD1602_4PINS //当没有定义这个LCD1602_4PINS时
- void LcdWriteCom(uchar com) //写入命令
- {
- LCD1602_E = 0; //使能
- LCD1602_RS = 0; //选择发送命令
- LCD1602_RW = 0; //选择写入
-
- LCD1602_DATAPINS = com; //放入命令
- Lcd1602_Delay1ms(1); //等待数据稳定
- LCD1602_E = 1; //写入时序
- Lcd1602_Delay1ms(5); //保持时间
- LCD1602_E = 0;
- }
- #else
- void LcdWriteCom(uchar com) //写入命令
- {
- LCD1602_E = 0; //使能清零
- LCD1602_RS = 0; //选择写入命令
- LCD1602_RW = 0; //选择写入
- LCD1602_DATAPINS = com; //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
- Lcd1602_Delay1ms(1);
- LCD1602_E = 1; //写入时序
- Lcd1602_Delay1ms(5);
- LCD1602_E = 0;
- LCD1602_DATAPINS = com << 4; //发送低四位
- Lcd1602_Delay1ms(1);
- LCD1602_E = 1; //写入时序
- Lcd1602_Delay1ms(5);
- LCD1602_E = 0;
- }
- #endif
- /*******************************************************************************
- * 函 数 名 : LcdWriteData
- * 函数功能 : 向LCD写入一个字节的数据
- * 输 入 : dat
- * 输 出 : 无
- *******************************************************************************/
- #ifndef LCD1602_4PINS
- void LcdWriteData(uchar dat) //写入数据
- {
- LCD1602_E = 0; //使能清零
- LCD1602_RS = 1; //选择输入数据
- LCD1602_RW = 0; //选择写入
- LCD1602_DATAPINS = dat; //写入数据
- Lcd1602_Delay1ms(1);
- LCD1602_E = 1; //写入时序
- Lcd1602_Delay1ms(5); //保持时间
- LCD1602_E = 0;
- }
- #else
- void LcdWriteData(uchar dat) //写入数据
- {
- LCD1602_E = 0; //使能清零
- LCD1602_RS = 1; //选择写入数据
- LCD1602_RW = 0; //选择写入
- LCD1602_DATAPINS = dat; //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
- Lcd1602_Delay1ms(1);
- LCD1602_E = 1; //写入时序
- Lcd1602_Delay1ms(5);
- LCD1602_E = 0;
- LCD1602_DATAPINS = dat << 4; //写入低四位
- Lcd1602_Delay1ms(1);
- LCD1602_E = 1; //写入时序
- Lcd1602_Delay1ms(5);
- LCD1602_E = 0;
- }
- #endif
- /*******************************************************************************
- * 函 数 名 : LcdInit()
- * 函数功能 : 初始化LCD屏
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- #ifndef LCD1602_4PINS
- void LcdInit() //LCD初始化子程序
- {
- LcdWriteCom(0x38); //开显示
- LcdWriteCom(0x0c); //开显示不显示光标
- LcdWriteCom(0x06); //写一个指针加1
- LcdWriteCom(0x01); //清屏
- LcdWriteCom(0x80); //设置数据指针起点
- }
- #else
- void LcdInit() //LCD初始化子程序
- {
- LcdWriteCom(0x32); //将8位总线转为4位总线
- LcdWriteCom(0x28); //在四位线下的初始化
- LcdWriteCom(0x0c); //开显示不显示光标
- LcdWriteCom(0x06); //写一个指针加1
- LcdWriteCom(0x01); //清屏
- LcdWriteCom(0x80); //设置数据指针起点
- }
- #endif
- void LEDshow()
- {
- suntr();
- LcdInit();
- LcdWriteCom(0x88); //写地址 80表示初始地址
- LcdWriteData('C');
- LcdWriteCom(0xc8); //写地址 80表示初始地址
- LcdWriteData('L');
- LcdWriteCom(0x82); //写地址 80表示初始地址
- LcdWriteData('0'+DisplayData[0]); //百位
- LcdWriteCom(0x83); //写地址 80表示初始地址
- LcdWriteData('0'+DisplayData[1]);
- LcdWriteCom(0x84);
- LcdWriteData('0'+DisplayData[2]);
- LcdWriteCom(0x85);
- LcdWriteData('0'+DisplayData[3]);
- LcdWriteCom(0x86);
- LcdWriteData('0'+DisplayData[4]);
- LcdWriteCom(0xc2); //0x40+0x80为第二行
- LcdWriteData('0'+DisplayData[5]); //百位
- LcdWriteCom(0xc3);
- LcdWriteData('0'+DisplayData[6]);
- LcdWriteCom(0xc4);
- LcdWriteData('0'+DisplayData[7]);
-
- }
- void main()
- {
-
- UsartInit();
- LcdInit();
-
- while(1)
- {
- Ds18b20ReadTemp();
- datapros();
-
- LEDshow();
- Delay1ms(100);
- send("AT+CIPMUX=1\r\n"); //设置为多路链接
- Delay1ms(100);
- send("AT+CIPSERVER=1,8080\r\n"); //配置为服务器,8080端口
- Delay1ms(100);
- send("AT+CIPSEND=0,11\r\n"); //发送数据,并且数据长度为2个字节
- Delay1ms(100);
- chuansong(); //将温度数据发送出去
-
- }
- }
复制代码
所有资料51hei提供下载:
WIFI.zip
(3.76 KB, 下载次数: 264)
|