打印
[产品应用]

用CW32实现2.4G无线传输

[复制链接]
1687|27
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
木木guainv|  楼主 | 2022-10-21 16:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前言
现在越来越多的智能家居,遥控飞机进入了我们大家的生活中,而2.4G的无线传输因为其免费开源被广泛使用,而现在MCU国产化又是我们国家发展芯片的大趋势,所以本文就CW32F030系列的开发板实现无线传输通信,为以后的智能家居可能会提供一点帮助。

一、无线传输的基础
我们是使用CW32F030的SPI已经市面上常见的NRF24L01模块来实现两块开发板之间的无线传输,可以远程控制另一块开发板的点灯或者其他操作

二、配置步骤以及功能实现
1.配置LED以及按键KEY,SPI的设置
代码如下:

#include "cw32f030.h"
#include "led.h"
#include "cw32f030_rcc.h"


void LED_Init(void)
{
     GPIO_InitTypeDef  GPIO_InitStructure;            

     RCC_AHBPeriphClk_Enable(RCC_AHB_PERIPH_GPIOB, ENABLE);

     GPIO_InitStructure.Pins = GPIO_PIN_9;            
     GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;     
     GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;   
     GPIO_Init(CW_GPIOB, &GPIO_InitStructure);   

     GPIO_WritePin(CW_GPIOB, GPIO_PIN_9, GPIO_Pin_RESET);


     GPIO_InitStructure.Pins = GPIO_PIN_8;            
     GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;     
     GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;   
     GPIO_Init(CW_GPIOB, &GPIO_InitStructure);   

     GPIO_WritePin(CW_GPIOB, GPIO_PIN_8, GPIO_Pin_RESET);



}

#include "cw32f030.h"
#include "key.h"
#include "led.h"
#include "cw32f030_rcc.h"

void KEY_Init(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;  

    RCC_AHBPeriphClk_Enable(RCC_AHB_PERIPH_GPIOA, ENABLE);
    GPIO_InitStructure.Pins = GPIO_PIN_1;            
    GPIO_InitStructure.Mode = GPIO_MODE_INPUT_PULLUP;//上拉输入
    GPIO_InitStructure.Speed = GPIO_SPEED_HIGH ;   
    GPIO_Init(CW_GPIOA, &GPIO_InitStructure);        


    GPIO_InitStructure.Pins = GPIO_PIN_2;            
    GPIO_InitStructure.Mode = GPIO_MODE_INPUT_PULLUP;
    GPIO_InitStructure.Speed = GPIO_SPEED_HIGH ;   
    GPIO_Init(CW_GPIOA, &GPIO_InitStructure);        
}

//引脚配置



extern uint8_t status_key;
void KEY_Scan(void)
{               
    static uint8_t flag_key0,flag_key1;
        if(KEY0==0)
        {
            flag_key0++;
            if(flag_key0==1)
            {
                status_key=1;
            }   
            if(flag_key0>2)flag_key0=2;
        }
        else
        {
            flag_key0=0;
        }

        if(KEY1==0)
        {
            flag_key1++;
            if(flag_key1==1)
            status_key=2;        
            if(flag_key1>2)flag_key1=2;            
        }   
        else
        {
            flag_key1=0;
        }
        delay1ms(10);
}


void SPI2_Init(void)   
{
      SPI_InitTypeDef  SPI_InitStructure;
      GPIO_InitTypeDef GPIO_InitStructure;


     //配置SPI2管脚
   RCC_AHBPeriphClk_Enable( SPIx_MISO_GPIO_CLK|SPIx_SCK_GPIO_CLK |  SPIx_MOSI_GPIO_CLK |  SPIx_CS_GPIO_CLK, ENABLE);
     SPIx_APBClkENx(SPIx_CLK,ENABLE);   
     SPIx_SCK_AF();
     SPIx_MOSI_AF();
     SPIx_MISO_AF();
     //SPIx_CS_AF();


    GPIO_InitStructure.Pins = GPIO_PIN_6 | GPIO_PIN_10;
    GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_Init(CW_GPIOB, &GPIO_InitStructure);

    GPIO_InitStructure.Pins = GPIO_PIN_1;
    GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_Init(CW_GPIOF, &GPIO_InitStructure);

    GPIO_InitStructure.Pins =  GPIO_PIN_7;   
    GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
    GPIO_InitStructure.Speed =  GPIO_SPEED_HIGH;  
    GPIO_Init(CW_GPIOB, &GPIO_InitStructure);  

    (CW_GPIOF->BRR = bv1);
    //SPI2配置选项
    RCC_APBPeriphClk_Enable1(RCC_APB1_PERIPH_SPI2,ENABLE);  
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_Speed    = SPI_Speed_Low;
    SPI_Init(CW_SPI2, &SPI_InitStructure);

    //使能SPI2
    SPI_Cmd(CW_SPI2, ENABLE);  }

2.配置NRF24L01的初始化以及收发的函数
void NRF24L01_Init(void)
{
        GPIO_InitTypeDef   GPIO_InitStructure;

        RCC_AHBPeriphClk_Enable(RCC_AHB_PERIPH_GPIOA , ENABLE );
        GPIO_InitStructure.Pins = GPIO_PIN_5;//CE
        GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP ;   
        GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
        GPIO_Init(CW_GPIOA, &GPIO_InitStructure);


        GPIO_InitStructure.Pins = GPIO_PIN_4;//CS
        GPIO_Init(CW_GPIOA, &GPIO_InitStructure);
        GPIO_WritePin(CW_GPIOA,GPIO_PIN_4 ,GPIO_Pin_SET);

        GPIO_InitStructure.Pins = GPIO_PIN_3;//IRQ
        GPIO_InitStructure.Mode = GPIO_MODE_INPUT_PULLUP;   
        GPIO_Init(CW_GPIOA, &GPIO_InitStructure);

        SPI2_Init();           //初始化SPI,在这里所有的引脚配置完毕

        GPIO_WritePin(CW_GPIOA, GPIO_PIN_5, GPIO_Pin_RESET);         //Standby
        GPIO_WritePin(CW_GPIOA, GPIO_PIN_4, GPIO_Pin_RESET);//SPI片选        
       
        while(NRF24L01_Check());        //2.检查NRF24L01是否在位.       
        NRF24L01_RX_Mode();       
}


uint8_t NRF24L01_TxPacket(uint8_t *txbuf)
{
        uint8_t sta;

        GPIO_WritePin(CW_GPIOA, GPIO_PIN_5, GPIO_Pin_RESET);
                NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);//写数据到TX BUF  32个字节
        GPIO_WritePin(CW_GPIOA, GPIO_PIN_5, GPIO_Pin_SET);//启动发送          
        while(NRF24L01_IRQ!=0);//等待发送完成
        sta=NRF24L01_Read_Reg(STATUS);  //读取状态寄存器的值          
        NRF24L01_Write_Reg(NRF_WRITE_REG+STATUS,sta); //清除TX_DS或MAX_RT中断标志
        if(sta&MAX_TX)//达到最大重发次数
        {
                NRF24L01_Write_Reg(FLUSH_TX,0xff);//清除TX FIFO寄存器
                return MAX_TX;
        }
        if(sta&TX_OK)//发送完成
        {
                return TX_OK;
        }
        return 0xff;//其他原因发送失败
}


uint8_t NRF24L01_RxPacket(uint8_t *rxbuf)
{
        uint8_t sta;                                                                              
        //SPI1_SetSpeed(SPI_BaudRatePrescaler_8); //spi速度为9Mhz(24L01的最大SPI时钟为10Mhz)   
        sta=NRF24L01_Read_Reg(STATUS);  //读取状态寄存器的值             
        NRF24L01_Write_Reg(NRF_WRITE_REG+STATUS,sta); //清除TX_DS或MAX_RT中断标志
        if(sta&RX_OK)//接收到数据
        {
                NRF24L01_Read_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据
                NRF24L01_Write_Reg(FLUSH_RX,0xff);//清除RX FIFO寄存器
                return 0;
        }          
        return 1;//没收到任何数据
}                                            








3.主函数的实现

void RCC_Configuration(void);

const char on[]={"ledon"};
const char off[]="ledoff";
uint8_t command[8];
uint8_t status_key;


int main(void)
{       
       RCC_Configuration();
       uint8_t momo,key,mode;
             uint16_t t=0;
       LED_Init();
       KEY_Init();
       NRF24L01_Init();
             uint8_t tmp_buf[33]={0x03,0x03};
             uint8_t  tmp_buf_2[33]={0x30,0x30};
                         
       while(1)
      {
             NRF24L01_TX_Mode();       
                   if(KEY0==0)//读取按键0
                   {
                                    delay1ms(10);
            if(KEY0==0)//读取按键0
                        {
                                     momo=1;
                         // NRF24L01_TxPacket(tmp_buf);
                        }
                   }
                if(KEY1==0)//读取按键0
                {
                                 delay1ms(10);
         if(KEY1==0)//读取按键0
                {
            //NRF24L01_TxPacket(tmp_buf_2);
                        momo=0;
                }
                }
                if(momo==0)
                {
                  NRF24L01_TxPacket(tmp_buf);
                  LED0_OFF;          
                }
                if(momo==1)
                {
                                  NRF24L01_TxPacket(tmp_buf_2);
                      LED0_ON;          
                }
               
                        {
               
               
                 delay1ms(10);
                        }
       }       
}




void RCC_Configuration(void)
{
  //SYSCLK = HSI = 24MHz = HCLK = PCLK
  RCC_HSI_Enable(RCC_HSIOSC_DIV2);

  //外设时钟使能
  RCC_AHBPeriphClk_Enable(RCC_AHB_PERIPH_GPIOA | RCC_AHB_PERIPH_GPIOB, ENABLE);
  RCC_APBPeriphClk_Enable1(RCC_APB1_PERIPH_SPI2,ENABLE);
}








接收端的配置
void RCC_Configuration(void);

const char on[]={"ledon"};
const char off[]="ledoff";
uint8_t command[8];
uint8_t status_key;
uint8_t tmp_buf[33];

int main(void)
{       
       RCC_Configuration();
       uint8_t momo,key,mode;
             uint16_t t=0;
       LED_Init();
       KEY_Init();
       NRF24L01_Init();
             
                         
       while(1)
        {
                  NRF24L01_RX_Mode();       
            NRF24L01_RxPacket(tmp_buf);
                       
                if(tmp_buf[0]==0x03|tmp_buf[1]==0x03)
                {
                LED0_ON;
               
                }
                else{
                LED0_OFF;         
                }                       
                delay1ms(10);       
                       
               
    }

}




void RCC_Configuration(void)
{
  //SYSCLK = HSI = 24MHz = HCLK = PCLK
  RCC_HSI_Enable(RCC_HSIOSC_DIV2);

  //外设时钟使能
  RCC_AHBPeriphClk_Enable(RCC_AHB_PERIPH_GPIOA | RCC_AHB_PERIPH_GPIOB, ENABLE);
  RCC_APBPeriphClk_Enable1(RCC_APB1_PERIPH_SPI2,ENABLE);
}

总结
通过设置中断是可以实现两块板子之间的双向传输功能。


使用特权

评论回复
沙发
uptown| | 2022-12-4 21:43 | 只看该作者
传输的距离大约是多少?              

使用特权

评论回复
板凳
yeates333| | 2022-12-5 23:18 | 只看该作者
这个如何实现双工通信呢?              

使用特权

评论回复
地板
albertaabbot| | 2022-12-6 13:30 | 只看该作者
最大可以支持多少个节点实现通信呢?

使用特权

评论回复
5
hilahope| | 2022-12-6 14:19 | 只看该作者
最低成本就是nrf2401了。              

使用特权

评论回复
6
uytyu| | 2022-12-6 15:31 | 只看该作者
这个用的是zigbee实现的吗              

使用特权

评论回复
7
hudi008| | 2022-12-6 18:40 | 只看该作者
硬件spi驱动的NRF24L01吗?

使用特权

评论回复
8
weifeng90| | 2022-12-7 17:59 | 只看该作者
芯源有带无线或者蓝牙的MCU吗?

使用特权

评论回复
9
modesty3jonah| | 2022-12-10 09:16 | 只看该作者
这个NRF24L01中断怎么应用的 ?

使用特权

评论回复
10
daichaodai| | 2022-12-15 08:37 | 只看该作者
还以为是芯源出了带2.4G无线的MCU呢。

使用特权

评论回复
11
Undshing| | 2022-12-26 12:08 | 只看该作者
传输距离多远啊?

使用特权

评论回复
12
robertesth| | 2023-1-5 13:23 | 只看该作者
有完整的设计电路吗?              

使用特权

评论回复
13
wwppd| | 2023-1-5 13:43 | 只看该作者
是否使用了中断来接收数据呢?              

使用特权

评论回复
14
beacherblack| | 2023-1-5 14:12 | 只看该作者
推荐使用zigbee,更简单。              

使用特权

评论回复
15
alvpeg| | 2023-1-5 14:42 | 只看该作者
我以为是无线控制的模块呢              

使用特权

评论回复
16
minzisc| | 2023-1-5 15:52 | 只看该作者
NRF24L01的价格还是比较便宜的。

使用特权

评论回复
17
lihuami| | 2023-1-6 12:34 | 只看该作者
怎么同时配置为发送或者接收?              

使用特权

评论回复
18
lzmm| | 2023-1-6 13:40 | 只看该作者
这个双向通信的时候,是否会响应到发送或者接收?

使用特权

评论回复
19
loutin| | 2023-1-6 17:48 | 只看该作者
最大的传输距离是多少?              

使用特权

评论回复
20
xiaoyaodz| | 2023-1-6 19:19 | 只看该作者
怎么实现数据的互传?              

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

156

主题

4130

帖子

5

粉丝