久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4828|回復: 4
打印 上一主題 下一主題
收起左側

STM32F103C8T6實現(xiàn)用2.4G模塊NRF2401傳輸室內(nèi)溫濕度并顯示OLED 源程序

  [復制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:836950 發(fā)表于 2021-8-8 22:23 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
基于STM32F103C8T6實現(xiàn)用2.4G模塊(NRF2401)傳輸室內(nèi)溫濕度并顯示OLED

對于2.4G模塊上的應用,很多是將這個這個模塊上的應用實現(xiàn)在51單片機上,我問了很多相關文章的博主,他們從最開始的程序幾乎都是從51單片機上,進行開發(fā),感謝這些趕路人,我們這些從事快速開發(fā)的愛好者做好的道路。
感謝[999994博主](http://www.zg4o1577.cn/bbs/space-uid-683358.html),[綻放中的青春博主](http://www.zg4o1577.cn/bbs/space-uid-290170.html)

好了,現(xiàn)在就進入主食階段

## 一:對2.4G模塊(NRF2401)的介紹
作為我們在開發(fā)應用的短距離傳輸信息的選擇模塊之一,作為在項目上實現(xiàn)互傳的模塊,可實現(xiàn)半雙工和全雙工,可以實現(xiàn)點對點或是 1 對 6 的無線通信。對于 NRF24L01 的固件編程工作主要是參照NRF24L01 的狀態(tài)機。主要有以下幾個狀態(tài):
Power Down Mode:掉電模式
Tx Mode:發(fā)射模式
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最小系統(tǒng),以下皆是)上的一個作為主機,一個作為從機,其中主機是負責采集室內(nèi)的溫度,從機是為了負責接收主機主機上的數(shù)據(jù),顯示在OLED上面,同時為了讓自己的項目更好的檢測,我在從機上也實現(xiàn)了對主機數(shù)據(jù)的發(fā)送,主句實現(xiàn)接收。
主機上發(fā)送:

```cpp
printf("\r\n 主機端 進入自應答發(fā)送模式\r\n");
        NRF_TX_Mode();

        txbuf[0]=temp;                        
        txbuf[1]=humi;//將檢測到的溫度和濕度賦值給這個非空數(shù)組中,實現(xiàn)數(shù)據(jù)包的發(fā)送
        status = NRF_Tx_Dat(txbuf);//

                  switch(status)
                          {
                            case MAX_RT:
                                          printf("\r\n 主機端 沒接收到應答信號,發(fā)送次數(shù)超過限定值,發(fā)送失敗。 \r\n");
                                 break;
        
                          case ERROR:
                                           printf("\r\n 未知原因?qū)е掳l(fā)送失敗。 \r\n");
                                 break;
        
                          case TX_DS:
                                          printf("\r\n 主機端 接收到 從機端 的應答信號,發(fā)送成功! \r\n");                        
                                 break;                                                                  
                          }                                   
        
```
從機上接收:

```cpp
printf("\r\n 從機端 進入接收模式\r\n");
        NRF_RX_Mode();     //這邊的是在收
         
        /*等待接收數(shù)據(jù)*/
        status = NRF_Rx_Dat(rxbuf);

           /*判斷接收狀態(tài)*/
                 if(status == RX_DR)
        {
                printf("\r\n 從機端 接收到 主機端 發(fā)送的數(shù)據(jù) \r\n");
          for(i=0;i<2;i++)
                                {        
                                        if(i%2==0)
                                        {
                                                printf("\r\n 溫度的數(shù)據(jù)為:%d \r\n",rxbuf[ i]);
                                                OLED_ShowNum(45,2,rxbuf[ i],3,16);//顯示溫度的碼值
                                                txbuf[ i] =1;
                                }
                                else
                               {
                                                printf("\r\n 濕度的數(shù)據(jù)為:%d \r\n",rxbuf[ i]);
                                            OLED_ShowNum(45,4,rxbuf[ i],3,16);//顯示濕度的碼值
                                                txbuf[ i] =1;
                               }                                                                        
                                }               
        }   
```
主機上接收從機數(shù)據(jù):

```cpp
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 主機端 接收到 從機端 發(fā)送的數(shù)據(jù)為:%d \r\n",rxbuf[ i]);
                                        txbuf[ i] =rxbuf[ i];
                                                                                                               
                                }
                                  break;
                        
                         case ERROR:
                                          printf("\r\n 主機端 接收出錯。   \r\n");
                                  break;                  
                        }
               
```




從機上發(fā)送給主機數(shù)據(jù):

```cpp
printf("\r\n 溫度的數(shù)據(jù)為:%d \r\n",rxbuf[ i]);
                                                OLED_ShowNum(45,2,rxbuf[ i],3,16);//顯示溫度的碼值
                                                txbuf[ i] =1;//返回發(fā)送給主機上的值為1
```
txbuf[ i]就是發(fā)送個主機上面的數(shù)據(jù)

```cpp
printf("\r\n 濕度的數(shù)據(jù)為:%d \r\n",rxbuf[ i]);
                                            OLED_ShowNum(45,4,rxbuf[ i],3,16);//顯示濕度的碼值
                                                txbuf[ i] =1;//返回發(fā)送給主機上的值為1
```

## 二.溫濕度傳感器簡介
DHT11是一款價格便宜,易于使用的溫度濕度測量二合一傳感器。它使用單根總線與單片機進行雙向的串行數(shù)據(jù)傳輸,信號傳輸距離可達20米以上。非常適用于對精度和實時性要求不高的溫濕度測量場合。![DHT117溫濕度傳感器](https://img-blog.csdnimg.cn/ddc7 ... ess=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3J5MTMyMzc2OTkyODE=,size_16,color_FFFFFF,t_70#pic_center)
接口設置:
|DATA  | PB11 |
|--|--|

這個模塊也是有相應的代碼格式,我這里就提幾個注意事項:
1.DHT11使用單一總線通信,即DATA引腳和單片機連接的線。總線總是處于空閑狀態(tài)和通信狀態(tài)這個2個狀態(tài)之間。
2.DHT11上電后,要等待 約 1秒 以越過不穩(wěn)定狀態(tài),在此期間不能發(fā)送任何指令。
3.DHT11屬于低速傳感器,兩次通信請求之間的間隔時間不能太短,一般來說要不能低于1秒。
4.當前DHT11通信幀的小數(shù)部分默認都是0,廠商預留給以后實現(xiàn)。所以一般只讀取整數(shù)值部分即可。校驗和定義為:前4個Byte的總和的低8位。


## 三.OLED顯示屏
我所用的OLED屏有白色,屏的大小為0.96寸,像素點為128*64,也稱之為0.96OLED屏或者12864屏。通時我選擇的是4腳,運用的協(xié)議是IIC協(xié)議,

```cpp
void IIC_Start(void)
{

        OLED_SCLK_Set() ;
        OLED_SDIN_Set();
        OLED_SDIN_Clr();
        OLED_SCLK_Clr();
}


理解了OLED的顯示方式,漢字取模也是很有必要的,我選擇列行式的取模方式,設置為C51原則:
[PLC取模軟件]


想要更加詳細的理解OLED上面的知識我推薦這位博主的博文[OLED詳細解剖](https://blog.csdn.net/u010858987 ... 1018.2226.3001.4187)

下面是主機項目工程中的main.c文件:

```cpp
#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;        //用于判斷接收/發(fā)送狀態(tài)
u8 txbuf[2];         //發(fā)送緩沖
u8 rxbuf[4];//接收緩沖
int i=0;
/*
*讀取溫濕度傳感器DHT11的值,并用串口打印出來
*/

void clock_init(void);

u8 temp = 0,humi = 0;


/**************************************************************************
函數(shù)名:int main(void)
參數(shù)說明:無
返回值:無
函數(shù)作用:主函數(shù)
***************************************************************************/
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();

        /*判斷連接狀態(tài)*/  
   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 主機端 進入自應答發(fā)送模式\r\n");
        NRF_TX_Mode();

        txbuf[0]=temp;                        
        txbuf[1]=humi;//將檢測到的溫度和濕度賦值給這個非空數(shù)組中,實現(xiàn)數(shù)據(jù)包的發(fā)送
        status = NRF_Tx_Dat(txbuf);//這里是發(fā)送
                  switch(status)                          {
                            case MAX_RT:
                                          printf("\r\n 主機端 沒接收到應答信號,發(fā)送次數(shù)超過限定值,發(fā)送失敗。 \r\n");
                                 break;
        
                          case ERROR:
                                           printf("\r\n 未知原因?qū)е掳l(fā)送失敗。 \r\n");
                                 break;
        
                          case TX_DS:
                                          printf("\r\n 主機端 接收到 從機端 的應答信號,發(fā)送成功! \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 主機端 接收到 從機端 發(fā)送的數(shù)據(jù)為:%d \r\n",rxbuf[ i]);
                                        txbuf[ i] =rxbuf[ i];
                                                                                                               
                                }
                                  break;
                        
                         case ERROR:
                                          printf("\r\n 主機端 接收出錯。   \r\n");
                                  break;                  
                        }
               
         }           
        
}
/**************************************************************************
函數(shù)名:void clock_init(void)
參數(shù)說明:無
返回值:無
函數(shù)作用:開啟高速外部時鐘,
ADCCLK設置為12MHZ,        SYSCLK設置為72Mhz,PCLK1設置為36MHZ,PKLC2設置為72mhz
***************************************************************************/
void clock_init(void)
{
        RCC->CR = 0x1010000;
        RCC->CFGR = 0x1DC402;
}

```

這里從機項目的main.c文件:

```cpp
#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;        //用于判斷接收/發(fā)送狀態(tài)
u8 txbuf[4];         //發(fā)送緩沖
u8 rxbuf[4];//接收緩沖
u8 i;
/*
*讀取溫濕度傳感器DHT11的值,并用串口打印出來
*/

void clock_init(void);
/**************************************************************************
函數(shù)名:int main(void)
參數(shù)說明:無
返回值:無
函數(shù)作用:主函數(shù)
***************************************************************************/
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);
                 //
                 //顯示各個參數(shù)的中文
    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();

        /*判斷連接狀態(tài)*/  
   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();     //這邊的是在收
         
        /*等待接收數(shù)據(jù)*/
        status = NRF_Rx_Dat(rxbuf);

           /*判斷接收狀態(tài)*/
                 if(status == RX_DR)
        {
                printf("\r\n 從機端 接收到 主機端 發(fā)送的數(shù)據(jù) \r\n");
          for(i=0;i<2;i++)
                                {        
                                        if(i%2==0)
                                        {
                                                printf("\r\n 溫度的數(shù)據(jù)為:%d \r\n",rxbuf[ i]);
                                                OLED_ShowNum(45,2,rxbuf[ i],3,16);//顯示溫度的碼值
                                                txbuf[ i] =1;//返回發(fā)送給主機上的值為1
                                }
                                else
                               {
                                                printf("\r\n 濕度的數(shù)據(jù)為:%d \r\n",rxbuf[ i]);
                                            OLED_ShowNum(45,4,rxbuf[ i],3,16);//顯示濕度的碼值
                                                txbuf[ i] =1;//返回發(fā)送給主機上的值為1
                               }                                       
                                       
                                }        
        }   
         
                printf("\r\n 從機端 進入自應答發(fā)送模式");
                  NRF_TX_Mode();
               
                /*不斷重發(fā),直至發(fā)送成功*/         
         do
           {           
                status = NRF_Tx_Dat(txbuf);
                  
                }while(status == MAX_RT);
        }

}
/**************************************************************************
函數(shù)名:void clock_init(void)
參數(shù)說明:無
返回值:無
函數(shù)作用:開啟高速外部時鐘,
ADCCLK設置為12MHZ,        SYSCLK設置為72Mhz,PCLK1設置為36MHZ,PKLC2設置為72mhz
***************************************************************************/
void clock_init(void)
{
        RCC->CR = 0x1010000;
        RCC->CFGR = 0x1DC402;
}

```
成果展示:
[雙板接線圖]
串口打印]

[室內(nèi)檢測]

項目總結:
總項目實現(xiàn)最大的難點是網(wǎng)上找到了相應的NRF2401的傳輸格式,只是這個格式并不能實現(xiàn)對你想要的數(shù)據(jù)的傳輸,所以這個實現(xiàn)的核心代碼還是自己一遍又一遍根據(jù)模塊實現(xiàn)的邏輯不斷完善的,同時在數(shù)據(jù)傳輸?shù)倪^程,OLED的格式我也是將實現(xiàn)數(shù)據(jù)的傳輸,讓其在室溫顯示下更加的穩(wěn)定,同時這個傳輸有個小小的瑕疵就是,設置了一個閾值,傳輸?shù)拈撝狄坏骄蜁袚Q到主機變從機,從機變主機的狀態(tài),鉆了全雙工的空子(假的(????))

代碼:
基于STM32F103C8T6實現(xiàn)用2.4G模塊(NRF2401)傳輸室內(nèi)溫濕度.7z (157.63 KB, 下載次數(shù): 227)

評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏12 分享淘帖 頂1 踩
回復

使用道具 舉報

沙發(fā)
ID:584195 發(fā)表于 2021-8-19 16:02 | 只看該作者
我好多年以后做過STM8的傳輸,感覺還是沒有驅(qū)動好。
回復

使用道具 舉報

板凳
ID:836950 發(fā)表于 2021-8-31 16:48 | 只看該作者
zyluglugl 發(fā)表于 2021-8-19 16:02
我好多年以后做過STM8的傳輸,感覺還是沒有驅(qū)動好。

驅(qū)動在設置上使能沒有注意的話,然后自己也不知道錯在哪里,那就有的忙的!自己真心體會到這種不快樂的快樂
回復

使用道具 舉報

地板
ID:412508 發(fā)表于 2022-5-2 11:18 | 只看該作者
謝謝樓主,寫的很詳細,自已慢慢消化一下。
回復

使用道具 舉報

5#
ID:1094757 發(fā)表于 2023-9-30 23:19 | 只看該作者

謝謝樓主,寫的很詳細,自已慢慢消化一下。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产精品一区一区 | 精精国产视频 | 国产欧美精品一区二区三区 | 中文字幕在线观看一区 | 日韩欧美高清dvd碟片 | 国产精品永久免费视频 | 一区二区三区欧美在线观看 | 91操操操| 国产不卡在线播放 | 久久久国产一区二区三区 | 国产日韩精品一区 | 国产精品伦理一区二区三区 | 国产天天操| 精品一区二区三区四区五区 | 久久国产日韩 | 亚洲精品久久久久中文字幕欢迎你 | 久久亚洲视频 | 波多野结衣二区 | 91精品久久 | 99一级毛片 | 91在线网| 成人午夜免费网站 | 欧美一区二区久久 | 国产99久久久国产精品 | 久久久久久久久久爱 | 欧美精品在线一区二区三区 | 欧美色性 | 国产精品亚洲综合 | 日本一卡精品视频免费 | 国产精品视频久久 | 欧美日韩不卡合集视频 | 国产精品国产a | 亚洲免费视频播放 | 黄色网页在线 | 久草在线高清 | 久草在线免费资源 | 亚洲精品福利视频 | www.奇米| 日韩一区二区免费视频 | 天天综合国产 | 午夜影院免费体验区 |