想做一个能够远程检测温湿度的东西,这样家里放一个,外面放一个,早上一起来就能看到实时的温湿度,岂不美滋滋。

最初想法是单独买温湿度的传感器,像DHT11那样,然后在买一个无线模块像NRF24L01,然后再配个微控制器啥的,后来在淘宝搜着搜着就发现了WHT20这款神器,他本身就有无线功能,而且他的传感器是SHT20,精度更高。然后这样我就只要配个接收的微控制器,选来选去,觉得51用腻了,STM32有点大材小用了,Arduino  Emmmm......不想用,就用了STM8S这么一个从来没用过的的微控制器。

先说下WHT20和他配套的接收器WSR。

一、WHT20

这是他官方介绍.(我只是不想打这么多字)

上面就有他的引脚,它可以通过串口在线设置,也可以通过WSR进行设置,他的VCC只能接3.3V左右的电压,实际测试,接5V虽然不会坏,但是发的都是乱码。

1.通过串口设置

通过串口设置时候,要把他的SET脚拉低,然后通过串口给他发送指令。(十六进制发送)

CC是开始标志;Time就是他的采集周期,可以设置1-65536s(占两个字节);NETID是他的网络号,只有WHT20和WSR的网络号相同时候才能通信,范围0-65535(两个字节);功率是设置他的发射功率(一个字节);波特率就是串口波特率(一个字节);Chose设置1时,他无线发射的同时也会通过串口发送,0就只无线发射(一个字节);Channel就是通信频道,有128个频道(一个字节);SUM是前面所有字节加起来,取低八位(一个字节),这校验和正确的时候,传感器才会返回值,不正确也能设置成功,不过不会返回....不知道算不算它的一个BUG;FF结束标志。

功率的对应表。

波特率对应表。

2.无线设置

短暂拉低KEY脚后拉高,此时就可以等待WSR的设置指令,此时传感器参数会恢复到默认状态NETID=0000,power=12dBm,channel=0x64.然后WSR就发射设置指令,按照如下格式。

只有指定的传感器ID才能接受设置参数,FFFFFF的话,会设置所有处于设置状态的传感器。

传感器设置成功后悔将参数保存到EEPROM中,然后发射返回值。

二、WSR

CS是片选,接低电平工作。SET是设置,拉低可通过串口对他进行设置。

1.串口设置自身参数。

拉低SET脚后,串口发送0XAA+0X5A+模块ID+NETID+0X00+POWER+0X00+波特率+0X00+Channel+0X00

+0X00+0X12+0X00+SUM

参数意义同WHT20。

2.设置传感器参数

WSR的SET拉低,通过串口发送AA5E指令,就可以设置处于设置状态的WHT20了

参数意义同WHT20,设置成功后就会返回AA5F指令

再就是他们之间的通讯协议了

这款传感器还是不错的,功耗真的挺低的,实测,12dBm的功率,采集周期7S,我用的锂电池,平均电流大概在1.6mA左右,也就是一个2000mah的锂电池,能用大概40多天。

STM8S

这个单片机不能用keil开发,只能用IAR和官方的STVD,网上的程序也是挺少的,开发它我也废了一番功夫。

我要用它的串口然后再用它驱动12864,我用的那一款引脚很少,所以12864我就用了SPI驱动方式。

说到底只是款单片机,看下时钟,看下各种片内外设寄存器就能用了呗。这个淘宝买的系统板,4块钱一个,真是便宜啊。。

官方的资料也是少之又少,他这板子用的是内部RC振荡电路提供时钟源,官方介绍说他因为出产,环境啥的不同,导致有差异。。。。就直接说不太准就行了呗.......,而且他是啥三级流水线,这个三级流水线意思就是呢...取指令,指令解码,指令执行交给了三个人去做,这样效率会快很多,但是
这也就造成一个问题,一条汇编指令,他的周期我不知道是多少了....

要想延时准还得用汇编........
volatile u8 fac_us=0; void delay_init(u8 clk)
{if(clk>16)fac_us=(16-4)/4;//24Mhz时,stm8大概19个周期为1uselse if(clk>4)fac_us=(clk-4)/4; else fac_us=1;
}void delay_us(u16 nus)
{
__asm(
"PUSH A          \n"    //压栈 1T
"DELAY_XUS:      \n"
"LD A,fac_us     \n"    //倍延加载到累加器A 1T
"DELAY_US_1:     \n"
"NOP             \n"    //1T
"DEC A           \n"    //1T
"JRNE DELAY_US_1 \n"    //!=0 跳转(2T)到DELAY_US_1执行, =0 不跳转(1T).
"NOP             \n"    //1T
"DECW X          \n"    //1T
"JRNE DELAY_XUS  \n"    //!=0 跳转(2T)到DELAY_XUS 执行, =0 不跳转(1T).
"POP A           \n"    //出栈 1T
);
}
STM8S 通过SPI驱动LCD12864
void SPI_12864_Init(void)
{SPI_Init(SPI_FIRSTBIT_MSB, SPI_BAUDRATEPRESCALER_2, SPI_MODE_MASTER,\SPI_CLOCKPOLARITY_HIGH, SPI_CLOCKPHASE_2EDGE, \SPI_DATADIRECTION_2LINES_FULLDUPLEX, SPI_NSS_SOFT, 0x00);SPI_Cmd(ENABLE);GPIO_Init(GPIOC,GPIO_PIN_4,\GPIO_MODE_OUT_PP_HIGH_FAST );//定义LED的管脚的模式GPIO_WriteHigh(GPIOC, GPIO_PIN_4);}
void LCD_wr(u8 lcd_com,u8 lcd_data)                                         //写入LCD数据或命令
{u8 lcd_data_msb,lcd_data_lsb;lcd_data_msb=0xf0&lcd_data;lcd_data_lsb=(0x0f&lcd_data)<<4;if(lcd_com==0)                                        //写命令{while (SPI_GetFlagStatus( SPI_FLAG_TXE) == RESET);        //等待 SPI 发送缓冲空SPI_SendData(0xf8);                        // SPI 发送数据--命令指令-- }if(lcd_com==1)                                        //写数据{while (SPI_GetFlagStatus( SPI_FLAG_TXE) == RESET);               //等待 SPI1 发送缓冲空SPI_SendData(0xfa);                    //SPI1 发送数据--数据指令--}delay_ms(1);while(SPI_GetFlagStatus( SPI_FLAG_TXE) == RESET);                //等待 SPI1 接收数据完毕SPI_SendData(lcd_data_msb);                   //SPI1 发送高4位数据delay_ms(1);while(SPI_GetFlagStatus( SPI_FLAG_TXE) == RESET);                //Wait for SPI1 Tx buffer emptySPI_SendData(lcd_data_lsb);            // SPI1 发送低4位数据delay_ms(1);
}
void initlcd(void)                          //LCD初始化
{LCD_wr(0,0x30);                  //30---基本指令动作 delay_ms (4);LCD_wr(0,0x01);                  //清屏,地址指针指向00Hdelay_ms (3);LCD_wr(0,0x06);                  //光标的移动方向delay_ms (1);LCD_wr(0,0x0c);                  //开显示,关游标delay_ms (1);
}
//LCD显示字符串
//X Y起始坐标
//*ptr 字符串地址  dat 字符串长度
//返回值 无
void LCD_showstring(u8 X,u8 Y,u8 *ptr,u8 dat)
{u8 i;switch(X)         //判断第几行{case 0:Y|=0x80;break;case 1:Y|=0x90;break;case 2:Y|=0x88;break;case 3:Y|=0x98;break;default:break;}LCD_wr(0,Y);       //发送起始地址for (i=0;i<dat;i++){LCD_wr(1,*ptr++);}
}
//LCD显示数字(包括负数)
//X,Y 数字显示起始地址
void LCD_shownum(u8 X,u8 Y,char num)
{switch(X)        //判断第几行{case 0:Y|=0x80;break;case 1:Y|=0x90;break;case 2:Y|=0x88;break;case 3:Y|=0x98;break;default:break;}LCD_wr(0,Y);if(num>=128)           //大于128代表负数{LCD_wr(1,0x2D);       //显示‘-’num=num&0x7f;         //最高位置零LCD_wr(1,num/10+0x30);//取十位LCD_wr(1,num%10+0x30);//取个位}else if(num<128){LCD_wr(1,(num)/10+0x30);LCD_wr(1,(num)%10+0x30);}
}
串口相关程序
void Uart_Init(void)
{UART1_DeInit();UART1_Init((u32)9600, UART1_WORDLENGTH_8D, UART1_STOPBITS_1, \UART1_PARITY_NO , UART1_SYNCMODE_CLOCK_DISABLE , UART1_MODE_TXRX_ENABLE);UART1_ITConfig(UART1_IT_RXNE_OR,ENABLE  );UART1_Cmd(ENABLE );}void UART1_SendByte(u8 data)
{UART1_SendData8((unsigned char)data);/* Loop until the end of transmission */while (UART1_GetFlagStatus(UART1_FLAG_TXE) == RESET);
}void UART1_SendString(u8* Data,u16 len)
{u16 i=0;for(;i<len;i++)UART1_SendByte(Data[i]);}u8 UART1_ReceiveByte(void)
{u8 USART1_RX_BUF; while (UART1_GetFlagStatus(UART1_FLAG_RXNE) == RESET);USART1_RX_BUF=UART1_ReceiveData8();return  USART1_RX_BUF;}void CLR_BUF()         //清空串口接收缓存
{point=0;memset( RxBuffer,0,20);
}#pragma vector=20
__interrupt void UART1_RX_IRQHandler(void)
{ u8 Res;static u8 start;//LCD_display(0,0,"hello1",8);if(UART1_GetITStatus(UART1_IT_RXNE )!= RESET)  /*接收中断(接收到的数据必须是0x0d 0x0a结尾)*/{Res =UART1_ReceiveData8();/*(USART1->DR);读取接收到的数据,当读完数据后自动取消RXNE的中断标志位*/if(Res==0xAA) {start=1;} //判断数据是否开始if(Res==0x5B) {cmd_responce=1;}  //判断是否是命令if(Res==0xFF) {start=0;usart_flag=1;}  //判断是否结束if(start) RxBuffer[point++]=Res;    //读取命令OR数据}}
WSR相关函数
void wsr_Init(void)
{GPIO_Init(GPIOA,GPIO_PIN_1,\GPIO_MODE_OUT_PP_HIGH_FAST );//SET脚接A1GPIO_Init(GPIOA,GPIO_PIN_2,\GPIO_MODE_OUT_PP_HIGH_FAST );//CS脚接A2GPIO_WriteLow(GPIOA, GPIO_PIN_2);GPIO_WriteHigh(GPIOA, GPIO_PIN_1);
}
//WSR设置函数
//NETID:网络号 power:功率 channel:频道 baud:波特率
//返回参数:0:设置不成功
//          1:设置成功
u8 wsr_set(u8 NETID,u8 power,u8 channel,u8 baud)
{ u8 i;u8 cmd[18]={0xAA,0X5A,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X04,0X00,0X64,0X00,0X00,0X00,0X12,0X00,0X00};//命令数组cmd[5]=NETID;cmd[7]=power;cmd[9]=baud;cmd[11]=channel;for(i=0;i<17;i++)cmd[17]=cmd[17]+cmd[i];   //添加校验位GPIO_WriteLow(GPIOA, GPIO_PIN_1);  //SET Ldelay_ms(1);UART1_SendString(cmd,18); //发送命令//delay_ms(1);while(!cmd_responce);   //等待命令回复cmd_responce=0;GPIO_WriteHigh(GPIOA, GPIO_PIN_1); //SET Hdelay_ms(3);if(RxBuffer[5]==NETID&&RxBuffer[7]==power&&RxBuffer[9]==baud&&RxBuffer[11]==channel)   //判断是否设置成功{CLR_BUF();return 1;}CLR_BUF();return 0;
}

WHT20无线温湿度传感器 STM8S单片机相关推荐

  1. 「新品速递」AHE100无线温湿度传感器

    01 产品概述 AHE100无线温湿度传感器主要应用于中高电压开关柜.接线盒.环网柜.箱变箱等内部环境的温度和湿度检测.组件采用特殊外壳,通风良好,外型精美,可保护内件,延长使用寿命. 02 技术指标 ...

  2. RT-Thread 应用篇 — 在STM32L051上使用 RT-Thread (二、无线温湿度传感器 之 CubeMX配置)

    应用篇-在STM32L051上使用RT-Thread 第二篇,使用STM32CubeMX 进行对应外设配置,同时做一些简单测试. 目录 前言 一.使用 STM32CubeMX 配置 1.1 基础步骤 ...

  3. RT-Thread 应用篇 — 在STM32L051上使用 RT-Thread (一、无线温湿度传感器 之 新建项目)

    学完了 RT-Thread 内核基础,来使用 RT-Thread 实现一个小应用. 硬件平台:STM32L051C8 TCM310(Enocean无线芯片) 软件平台:RT-Thread Studio ...

  4. 12、基于51单片机多机 NRF24L01 无线温湿度 DHT11报警设计

    毕设帮助.开题指导.技术解答(有偿)见文末. 目录 摘要 一.硬件方案 二.设计功能 三.实物图 四.原理图 五.PCB图 六.程序源码 七.资料包括 摘要 温度湿度在工农业生产中占有很重要的地位,是 ...

  5. 51单片机 DHT11温湿度传感器 MQ2传感器

    目录 前言 程序思路 DHT11 一.DHT11基础储备 二.接口说明 三.协议及数据格式 ​编辑 四.DHT11代码 MQ-2烟雾传感器 一.MQ-2烟雾传感器介绍 二.工作原理 三.时序配置 四. ...

  6. 【51单片机快速入门指南】6.4:DHT11、DHT22单总线温湿度传感器

    目录 硬知识 DHT11 DHT22 通信协议 读取步骤 数据解读 DHT11 DHT22 示例程序 DHT11_22.c DHT11_22.h 测试程序 main.c 实验现象 DHT11 DHT2 ...

  7. STM8单片机读取DHT11温湿度传感器

    DHT11是一款温湿度传感器,也是使用一根总线来驱动,使用方法和ds18b20温度传感器很类似. 供电电压 3.3~5.5V DC 测量范围 湿度5% ~ 95%RH, 温度-20℃ ~ +60℃ 测 ...

  8. 传感器自学笔记第八章——DHT11温湿度传感器(附带自己写的很好用的51单片机DHT11代码模板,参数列表只有一个字符数组指针)

    作者:GWD 时间:2019.06.26 DHT11温湿度传感器(单总线类) 一. 学习要点: 1.(重要)单总线类传感器检测高电平while(DHT11 == 1) temp |=0x01;出错,因 ...

  9. 51单片机控制DHT11温湿度传感器,并使用OLED屏幕显示

    目录 前言 一.MCU主控选型 二.DHT11温湿度传感器 1.模块介绍 2.软件实现 DHT11.c DHT11.h 三.OLED显示屏 1.模块介绍 2.软件实现 OLED.c OLED.h OL ...

最新文章

  1. Codeforces Hello 2019 D. Makoto and a Blackboard[DP+数论+概率期望]
  2. linux重启memcache_memcache和memcached区别
  3. Actions require unique method/path combination for Swagger
  4. 干货—MySQL常见的面试题+索引原理分析!
  5. 因果推断与反事实预测——几篇关联论文(二十六)
  6. mysql存储php数组_mysql数据库存储PHP数组、对象的方法
  7. VB mschart控件的使用
  8. 表单构建html的页面代码,网页设计表单制作代码 制作一个很简单网页表单代码...
  9. archlinux i3wm flameshot使用
  10. 扁平化管理:硅谷高效工作法
  11. 无基础如何备考软考软件设计师?
  12. android8.0系统 原生,羡慕原生安卓8.0?索尼XPZ系统占用11GB苦不堪言
  13. 消极和积极的道德--给亲爱的安德烈
  14. 安装多可预览控件后,不能正常预览和修改该怎么办?
  15. 祝所有程序员1024节日快乐。
  16. 我讨厌你公事公办的样子
  17. Matlab语句:rmoutliers(检测并删除数据中的离群值)
  18. 百度云同步盘网络异常【1】解决办法
  19. 《缠中说禅108课》84:本 ID 理论一些必须注意的问题
  20. 未能加载或程序集“XXXX,Version=0.0.0.0,Culter=neutral,PublicKeyToken=null”或它的某一个依赖项。试图加载格式不正确的程序。...

热门文章

  1. 【游戏开发创新】当我学了Blender 建模,自制3D电脑桌面,回收站爆发了,把我做的模型都吐了出来(Blender | Unity | FBX)
  2. Spring和Quartz实现的定时任务调度
  3. 在Blender中做一个小独角兽
  4. 【python+selenium】点触文字验证码的识别
  5. 三星910S3L单m2接口更换硬盘系统克隆全程攻略
  6. INDEMIND:多传感器融合,机器人的必由之路
  7. js动态函数(方法)
  8. element plus组件居中显示
  9. 夜神安卓(android)模拟器 摇一摇
  10. 【Free5GC】test.sh脚本测试流程