基于STM32F103C8T6实现用2.4G模块(NRF2401)传输室内温湿度并显示OLED

对于2.4G模块上的应用,很多是将这个这个模块上的应用实现在51单片机上,我问了很多相关文章的博主,他们从最开始的程序几乎都是从51单片机上,进行开发,感谢这些赶路人,我们这些从事快速开发的爱好者做好的道路。
感谢999994博主,绽放中的青春博主

好了,现在就进入主食阶段

一:对2.4G模块(NRF2401)的介绍

作为我们在开发应用的短距离传输信息的选择模块之一,作为在项目上实现互传的模块,可实现半双工和全双工,可以实现点对点或是 1 对 6 的无线通信。对于 NRF24L01 的固件编程工作主要是参照NRF24L01 的状态机。主要有以下几个状态:
Power Down Mode:掉电模式
Tx Mode:发射模式
Rx Mode:接收模式
Standby-1Mode:待机 1 模式
Standby-2 Mode:待机 2 模式

这里配上接线管脚

PA1 NRF- CSN
PA5-SPI1-SCK NRF -SCK
PA6-SPI1-MISO NRF -MISO
PA7-SPI1-MOSI NRF -MOSI
PA3 NRF-IRQ
PA2 NRF-CE

但是在我应用的项目上我没有使用全双工,项目设计是一个板子(STM32最小系统,以下皆是)上的一个作为主机,一个作为从机,其中主机是负责采集室内的温度,从机是为了负责接收主机主机上的数据,显示在OLED上面,同时为了让自己的项目更好的检测,我在从机上也实现了对主机数据的发送,主句实现接收。
主机上发送:

printf("\r\n 主机端 进入自应答发送模式\r\n"); NRF_TX_Mode();txbuf[0]=temp;            txbuf[1]=humi;//将检测到的温度和湿度赋值给这个非空数组中,实现数据包的发送status = NRF_Tx_Dat(txbuf);//switch(status){case MAX_RT:printf("\r\n 主机端 没接收到应答信号,发送次数超过限定值,发送失败。 \r\n");break;case ERROR:printf("\r\n 未知原因导致发送失败。 \r\n");break;case TX_DS:printf("\r\n 主机端 接收到 从机端 的应答信号,发送成功! \r\n");         break;                                  }               

从机上接收:

printf("\r\n 从机端 进入接收模式\r\n"); NRF_RX_Mode();     //这边的是在收/*等待接收数据*/status = NRF_Rx_Dat(rxbuf);/*判断接收状态*/if(status == RX_DR){printf("\r\n 从机端 接收到 主机端 发送的数据 \r\n");for(i=0;i<2;i++){    if(i%2==0){printf("\r\n 温度的数据为:%d \r\n",rxbuf[i]);OLED_ShowNum(45,2,rxbuf[i],3,16);//显示温度的码值txbuf[i] =1;}else{printf("\r\n 湿度的数据为:%d \r\n",rxbuf[i]);OLED_ShowNum(45,4,rxbuf[i],3,16);//显示湿度的码值txbuf[i] =1;}                                  }       }

主机上接收从机数据:

printf("\r\n 主机端 进入接收模式。 \r\n");   NRF_RX_Mode();status = NRF_Rx_Dat(rxbuf);  switch(status){case RX_DR:for(i=0;i<4;i++){                   printf("\r\n 主机端 接收到 从机端 发送的数据为:%d \r\n",rxbuf[i]);txbuf[i] =rxbuf[i];}break;case ERROR:printf("\r\n 主机端 接收出错。   \r\n");break;          }

从机上发送给主机数据:

printf("\r\n 温度的数据为:%d \r\n",rxbuf[i]);OLED_ShowNum(45,2,rxbuf[i],3,16);//显示温度的码值txbuf[i] =1;//返回发送给主机上的值为1

txbuf[i]就是发送个主机上面的数据

printf("\r\n 湿度的数据为:%d \r\n",rxbuf[i]);OLED_ShowNum(45,4,rxbuf[i],3,16);//显示湿度的码值txbuf[i] =1;//返回发送给主机上的值为1

二.温湿度传感器简介

DHT11是一款价格便宜,易于使用的温度湿度测量二合一传感器。它使用单根总线与单片机进行双向的串行数据传输,信号传输距离可达20米以上。非常适用于对精度和实时性要求不高的温湿度测量场合。
接口设置:

DATA PB11

这个模块也是有相应的代码格式,我这里就提几个注意事项:
1.DHT11使用单一总线通信,即DATA引脚和单片机连接的线。总线总是处于空闲状态和通信状态这个2个状态之间。
2.DHT11上电后,要等待 约 1秒 以越过不稳定状态,在此期间不能发送任何指令。
3.DHT11属于低速传感器,两次通信请求之间的间隔时间不能太短,一般来说要不能低于1秒。
4.当前DHT11通信帧的小数部分默认都是0,厂商预留给以后实现。所以一般只读取整数值部分即可。校验和定义为:前4个Byte的总和的低8位。

三.OLED显示屏

我所用的OLED屏有白色,屏的大小为0.96寸,像素点为128*64,也称之为0.96OLED屏或者12864屏。通时我选择的是4脚,运用的协议是IIC协议,

void IIC_Start(void)
{OLED_SCLK_Set() ;OLED_SDIN_Set();OLED_SDIN_Clr();OLED_SCLK_Clr();
}

理解了OLED的显示方式,汉字取模也是很有必要的,我选择列行式的取模方式,设置为C51原则:

想要更加详细的理解OLED上面的知识我推荐这位博主的博文OLED详细解剖

下面是主机项目工程中的main.c文件:

#include "stm32f10x.h"
#include "usart.h"
#include "delay.h"
#include "DTH117.h"
#include "sys.h"
#include "SPI_NRF.h"
#include <stdarg.h>
#include <string.h>
#include <stdio.h>u8 status;  //用于判断接收/发送状态
u8 txbuf[2];     //发送缓冲
u8 rxbuf[4];//接收缓冲
int i=0;
/*
*读取温湿度传感器DHT11的值,并用串口打印出来
*/void clock_init(void);u8 temp = 0,humi = 0;/**************************************************************************
函数名:int main(void)
参数说明:无
返回值:无
函数作用:主函数
***************************************************************************/int main(void){ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);SPI_NRF_Init();delay_init();DHT11_Init();     clock_init();  usart_init(115200);     //初始化串口printf("\r\n 这是一个 NRF24L01 无线传输实验 \r\n");printf("\r\n 这是无线传输 主机端 的反馈信息\r\n");printf("\r\n   正在检测NRF与MCU是否正常连接。。。\r\n");/*检测NRF模块与MCU的连接*/status = NRF_Check(); /*判断连接状态*/  if(status == SUCCESS)       printf("\r\n      NRF与MCU连接成功!\r\n");  else   printf("\r\n  NRF与MCU连接失败,请重新检查接线。\r\n"); while(1){  DHT11_Read_Data(&temp,&humi);printf("\r\n 主机端 进入自应答发送模式\r\n"); NRF_TX_Mode();txbuf[0]=temp;          txbuf[1]=humi;//将检测到的温度和湿度赋值给这个非空数组中,实现数据包的发送status = NRF_Tx_Dat(txbuf);//这里是发送switch(status)          {case MAX_RT:printf("\r\n 主机端 没接收到应答信号,发送次数超过限定值,发送失败。 \r\n");break;case ERROR:printf("\r\n 未知原因导致发送失败。 \r\n");break;case TX_DS:printf("\r\n 主机端 接收到 从机端 的应答信号,发送成功! \r\n");          break;                                  }               printf("\r\n 主机端 进入接收模式。 \r\n");  NRF_RX_Mode();status = NRF_Rx_Dat(rxbuf);  switch(status){case RX_DR:for(i=0;i<4;i++){                   printf("\r\n 主机端 接收到 从机端 发送的数据为:%d \r\n",rxbuf[i]);txbuf[i] =rxbuf[i];}break;case ERROR:printf("\r\n 主机端 接收出错。   \r\n");break;          }}    }
/**************************************************************************
函数名:void clock_init(void)
参数说明:无
返回值:无
函数作用:开启高速外部时钟,
ADCCLK设置为12MHZ,  SYSCLK设置为72Mhz,PCLK1设置为36MHZ,PKLC2设置为72mhz
***************************************************************************/void clock_init(void){RCC->CR = 0x1010000;RCC->CFGR = 0x1DC402;
}

这里从机项目的main.c文件:

#include "stm32f10x.h"
#include "usart.h"
#include "delay.h"
#include "oled.h"
#include "sys.h"
#include "SPI_NRF.h"
#include <stdarg.h>
#include <string.h>
#include <stdio.h>u8 status;  //用于判断接收/发送状态
u8 txbuf[4];     //发送缓冲
u8 rxbuf[4];//接收缓冲
u8 i;
/*
*读取温湿度传感器DHT11的值,并用串口打印出来
*/void clock_init(void);
/**************************************************************************
函数名:int main(void)
参数说明:无
返回值:无
函数作用:主函数
***************************************************************************/int main(void){ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);SPI_NRF_Init();delay_init();OLED_Init();  clock_init();  usart_init(115200);     //初始化串口OLED_Clear();OLED_Display_On();OLED_ShowCHinese(40,0,0);OLED_ShowCHinese(60,0,1);OLED_ShowCHinese(80,0,2);OLED_ShowCHinese(100,0,3);////显示各个参数的中文OLED_ShowCHinese(0,2,4);OLED_ShowCHinese(18,2,5);    OLED_ShowString(35,2, ":",16);//显示温度中文OLED_ShowCHinese(0,4,6);OLED_ShowCHinese(18,4,7);   OLED_ShowString(35,4, ":",16);//显示温度中文   printf("\r\n 这是一个 NRF24L01 无线传输实验 \r\n");printf("\r\n 这是无线传输 主机端 的反馈信息\r\n");printf("\r\n   正在检测NRF与MCU是否正常连接。。。\r\n");/*检测NRF模块与MCU的连接*/status = NRF_Check(); /*判断连接状态*/  if(status == SUCCESS)      printf("\r\n      NRF与MCU连接成功!\r\n");  else   printf("\r\n  正在检测NRF与MCU是否正常连接。。。\r\n"); while(1){ printf("\r\n 从机端 进入接收模式\r\n"); NRF_RX_Mode();     //这边的是在收/*等待接收数据*/status = NRF_Rx_Dat(rxbuf);/*判断接收状态*/if(status == RX_DR){printf("\r\n 从机端 接收到 主机端 发送的数据 \r\n");for(i=0;i<2;i++){   if(i%2==0){printf("\r\n 温度的数据为:%d \r\n",rxbuf[i]);OLED_ShowNum(45,2,rxbuf[i],3,16);//显示温度的码值txbuf[i] =1;//返回发送给主机上的值为1}else{printf("\r\n 湿度的数据为:%d \r\n",rxbuf[i]);OLED_ShowNum(45,4,rxbuf[i],3,16);//显示湿度的码值txbuf[i] =1;//返回发送给主机上的值为1}                  }   }   printf("\r\n 从机端 进入自应答发送模式"); NRF_TX_Mode();/*不断重发,直至发送成功*/      do{     status = NRF_Tx_Dat(txbuf);}while(status == MAX_RT);} }
/**************************************************************************
函数名:void clock_init(void)
参数说明:无
返回值:无
函数作用:开启高速外部时钟,
ADCCLK设置为12MHZ,  SYSCLK设置为72Mhz,PCLK1设置为36MHZ,PKLC2设置为72mhz
***************************************************************************/void clock_init(void){RCC->CR = 0x1010000;RCC->CFGR = 0x1DC402;
}

成果展示:


项目总结:
总项目实现最大的难点是网上找到了相应的NRF2401的传输格式,只是这个格式并不能实现对你想要的数据的传输,所以这个实现的核心代码还是自己一遍又一遍根据模块实现的逻辑不断完善的,同时在数据传输的过程,OLED的格式我也是将实现数据的传输,让其在室温显示下更加的稳定,同时这个传输有个小小的瑕疵就是,设置了一个阈值,传输的阈值一到就会切换到主机变从机,从机变主机的状态,钻了全双工的空子(假的(✿◡‿◡))


资料打包可用51黑子网
同时也可在本CSDN上下载:资料下载

备注:1. 本文章是个人总结,如有不足之处欢迎指正;
2.文章资料格式是网上找的也是从上面两个博主的,但是核心代码是自己写的,文章资料如有侵权,请联系我。

基于STM32F103C8T6实现用2.4G模块(NRF2401)传输室内温湿度并显示OLED相关推荐

  1. 基于STM32和阿里云的矿道环境监测系统(温湿度DHT117,NRF2401(2.4G模块),气体传感器(MQ-3),0.96寸OLED屏,wifi模块)

    基于STM32和阿里云的矿道环境监测系统(温湿度DHT117,NRF2401(2.4G模块),气体传感器(MQ-3)) 系统实现的功能 系统实现的是运用一块STM32F103C8T6作为发射端节点,上 ...

  2. 推荐基于4G模块打造的超低功耗4G摄像头通讯板

    目前市面上大部分的通信板子都是用4G+MCU的模式去做,这样做体积太大,成功有很高,在市面上没啥优势. 如果直接基于4G模块直接开发体积会小,成本明显要低.下面给大家推荐一款: 看上的找我:152 2 ...

  3. 基于Xavier 移植移远EG25G 4G模块

    基于Jetson Xavier NX 移植移远EG25G 4G模块 先敲一下黑板,使劲敲 大家一定先试一下直接插上4G模块后,linux能否读出来,就是右上角的wifi设置那里面出不出现移动网络信息, ...

  4. 基于Stm32的4G模块实现内网透传通信(代码后附)

    基于Stm32的4G模块实现内网透传通信 一.内网透传即内网映射,内网IP端口映射外网连接访问过程的实现.内网透传通信实现过程又有以下几种区别: 1)路由器映射.适合自己本地路由有公网IP网络环境,用 ...

  5. 【回顾】基于树莓派下的4G模块(EC200U-CN)实现远程控制短信的收发

    1. 项目简介: 树莓派通过USB与4G模块(EC200U-CN)进行连接,通过串口进行通信,使用AT指令进行控制短信收发,在远程PC端上部署短信收发的控制端,PC端通过MQTT物理网通信协议发布指令 ...

  6. 基于OneNet平台设计的多节点温度采集系统-有人云4G模块+STM32

    一.设计说明 设计思路: 每个测量点采用4G+STM32+温度测量模块组成:采集温度数据之后直接上传到OneNet物联网云平台,在OneNET云平台上设计可视化界面进行显示,并且也可以在手机APP设备 ...

  7. 驱动程序开发:基于EC20 4G模块自动拨号联网的两种方式(GobiNet工具拨号和PPP工具拨号)

    目录 一.EC20 4G模块简介 二.根据移远官方文档修改EC20 4G模组驱动   1.因为EC20 4G模组min-pice接口其实就是usb接口,因此需要修改Linux内核源码drivers/u ...

  8. 基于STM32+4G模块设计的智能灌溉系统

    一.前言 农业灌溉会直接影响作物的生长,合理的灌溉能够提升作物的质量和产量,更有助于水资源的持续利用.过度的灌溉不仅降低水资源利用率,还可能造成作物养分流失.病虫害.内涝等众多问题.因此随着农业智能化 ...

  9. 基于STM32F103C8T6的MPU6050调试与数字运动处理器DMP

    基于STM32F103C8T6的MPU6050调试与数字运动处理器DMP StrongerHangover 笔者之前也接触过MPU6050模块,但是并没有真正的去了解内部的通讯方式与内部的寄存器操作, ...

最新文章

  1. learnByWork
  2. 排序算法系列:选择排序算法
  3. 3.mysql的中文问题,database级操作,表级操作,数据CRUD,分组操作,时间和日期,字符串相关函数,表的约束
  4. C算法--入门 2.3
  5. 投递简历得不到回复,并不是你的简历不好,可能是这个原因
  6. python-标示符和关键字
  7. 【Siddhi 5】Siddhi 5 源码编译
  8. 精妙SQL语句集合(收集)
  9. Spring4Shell 漏洞已遭Mirai 僵尸网络利用
  10. mysql事务高级_mysql高级 标量 与事务
  11. 代码整洁之道读书笔记----第五章---格式--如何让代码整体布局更清晰
  12. 2021年Delphi第26届应用软件开发展示挑战赛的获胜者名单
  13. 公司让微信加人有没有软件_没有人想要使用软件
  14. Pocket PC C#
  15. 微信小游戏排行榜卡顿或无法滑动
  16. Python 爬虫 性能 相关( asyncio 模块 --- 高性能爬虫 )
  17. 批量导入数据将word文档转换成HTML文档
  18. 高等数学(第七版)同济大学 习题9-4 (前11题)个人解答
  19. panda3D学习之路
  20. Win11如果在桌面右击新建没有文本文档

热门文章

  1. “降噪”与“匠心”兼得:索尼WH-1000XM4评测体验
  2. DirectX11 几何体示例Demo
  3. Win32 API (1) WinExec
  4. python中return的用法
  5. linux mrtg 安装,Linux系统mrtg详细安装、设置说明
  6. 修改浏览器默认滚动条样式,兼容IE和谷歌
  7. 分布式系统原理(9)Paxos 协议
  8. NC | 土壤微生物组的结构和功能揭示全球湿地N2O释放
  9. 用wordpress搭建博客网站看到一个不错点鼠标特效插件canvas-nest
  10. psycopg2离线安装