STM32
直播中

李艺银

7年用户 1037经验值
私信 关注
[问答]

STM32F1 2.4G无线通信模块怎么样?

STM32F1 2.4G无线通信模块怎么样?

回帖(1)

李凯生

2021-12-17 10:55:13
STM32F1 2.4G无线通信模块24L01是一个2.4G的无线通信模块,空旷地实测通信距离70-80米左右。24L01有6个通道,也就是一个无线模块最多可以同时接收6个无线模块的数据,一个通道对应一个。地址一共40位,但是只有通道0可以自由设置地址。其他的5路通道只能设置最后8位地址,前面的32位地址是固定的。自动应答功能,自动重发功能(最多16次),(实测;距离25cm,最大功率0db、开启自动应答、自动重发16次的情况下,传输30-50次会丢失一次数据)使用SPI协议通信,最大通信速度10m bps供电电压1.9-3.6v,一般使用3.3v供电使用(不能使用5v),但是IO口可以容忍5v,可以与5v单片机直接通信。24L01有不同的工作模式,接收模式、发送模式、掉电模式、待机模式等,数据手册都有说明。可以产生中断,节省了单片机的查询时间24L01的指令有点坑,读寄存器的时候直接操作相应寄存器的地址就行。但是在写寄存器的时候就不是直接操作寄存器的地址了,低5位才是寄存器地址,高三位是011.一般发射数据的时候才设置为发送模式,平时用待机模式就行。配置寄存器比较多,也不需要全部配置吧,配置一部分就行,代码中有注释。本实验分为两个工程,一个用于发送,一个用于接收。注释都在发送板的实验里,接收板的注释最好不要看。发送板功能;上电时如果检测到存在24L01   LED会亮一秒钟才会闪烁。如果不存在24L01模块则上电第一秒LED是黑的。一次发送32个u8的数据,但是只有数组的第11位才是有用的,也就是数组下标为10的那个。如果数据发送成功则LED快闪,一秒钟闪5次。如果没有成功发送数据则LED慢闪,一秒钟一次。接收板功能;上电后检查24L01模块,如果上电时LED是黑的且LED不闪烁,那就是没有检测到24L01模块,如果上电后LED常亮表示检测到模块但是没有接收到数据,如果LED闪烁就是接收到数据了。注意;两个工程有部分地方不一样。1、LED的IO口不一样2、24L01模块的控制IO不一样,但是SPI口是一样的3、主函数不一样,一个纯接收一个纯发送当然不一样了至于具体怎么配置寄存器,发送数据接收数据的流程工程里面的函数都注释的很清楚。发送板的工程分5个文件,3个c文件,两个h文件文件
STM32F1 2.4G无线通信模块


24L01是一个2.4G的无线通信模块,空旷地实测通信距离70-80米左右。

24L01有6个通道,也就是一个无线模块最多可以同时接收6个无线模块的数据,一个通道对应一个。地址一共40位,但是只有通道0可以自由设置地址。其他的5路通道只能设置最后8位地址,前面的32位地址是固定的。

自动应答功能,自动重发功能(最多16次),
(实测;距离25cm,最大功率0db、开启自动应答、自动重发16次的情况下,传输30-50次会丢失一次数据)

使用SPI协议通信,最大通信速度10m bps

供电电压1.9-3.6v,一般使用3.3v供电使用(不能使用5v),但是IO口可以容忍5v,可以与5v单片机直接通信。

24L01有不同的工作模式,接收模式、发送模式、掉电模式、待机模式等,数据手册都有说明。

可以产生中断,节省了单片机的查询时间

24L01的指令有点坑,读寄存器的时候直接操作相应寄存器的地址就行。但是在写寄存器的时候就不是直接操作寄存器的地址了,低5位才是寄存器地址,高三位是011.

一般发射数据的时候才设置为发送模式,平时用待机模式就行。

配置寄存器比较多,也不需要全部配置吧,配置一部分就行,代码中有注释。

本实验分为两个工程,一个用于发送,一个用于接收。注释都在发送板的实验里,接收板的注释最好不要看。
发送板功能;上电时如果检测到存在24L01   LED会亮一秒钟才会闪烁。如果不存在24L01模块则上电第一秒LED是黑的。一次发送32个u8的数据,但是只有数组的第11位才是有用的,也就是数组下标为10的那个。如果数据发送成功则LED快闪,一秒钟闪5次。如果没有成功发送数据则LED慢闪,一秒钟一次。
接收板功能;上电后检查24L01模块,如果上电时LED是黑的且LED不闪烁,那就是没有检测到24L01模块,如果上电后LED常亮表示检测到模块但是没有接收到数据,如果LED闪烁就是接收到数据了。

注意;两个工程有部分地方不一样。
1、LED的IO口不一样
2、24L01模块的控制IO不一样,但是SPI口是一样的
3、主函数不一样,一个纯接收一个纯发送当然不一样了

至于具体怎么配置寄存器,发送数据接收数据的流程工程里面的函数都注释的很清楚。
发送板的工程分5个文件,3个c文件,两个h文件
文件 Main.c
#include "sys.h"
#include "delay.h"
#include "spi_24l01.h"
#include "24L01.h"

#define LED(value) GPIO_WriteBit(GPIOE,GPIO_Pin_5,value)


/************************************************************
功能;LED闪烁,间隔为100ms
其中LED接在PB5上,低电平有效
****************************************************************/

void init_led();





int main(void)
{       
        u16 ms_count=0;
        u8 led_flag=0;
        u8  buf_data[33]={0};//用来存放临时数据
        delay_init();        //延时函数初始化
        init_led();         //LED初始化。LED是低电平有效
        init_24L01();//无线模块初始化
       
        LED(NRF24L01_Check());//如果检测到无线模块,LED会亮1秒钟
        delay_ms(1000);
       
        NRF24L01_TX_Mode();//设置为发送模式
       
        while(1)
        {
                if(NRF24L01_TxPacket(buf_data) == TX_OK)//其实数据是一直发送的
                {
                        buf_data[10]=!buf_data[10];//就拿数组中的一个元素作为LED的标志位吧,
                        delay_ms(100);
                        LED(buf_data[10]);//如果发送成功,那么接收板和发送板的LED是同步闪烁的
                }
                else//如果发送失败
                {
                        ms_count++;
                        delay_ms(1);
                        if(ms_count>1000)//那就是慢闪了
                        {
                                ms_count=0;
                                led_flag = !led_flag;                       
                                LED(led_flag);
                        }
                }
        }
}





void init_led()  
{
        GPIO_InitTypeDef GPIO_InitStruct;//GPIO结构体
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);//打开GPIOB和GPIOE时钟

        GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出
        GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;//PB5
        GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;//翻转速度=10MHZ
        GPIO_Init(GPIOE, &GPIO_InitStruct);
        GPIO_WriteBit(GPIOE,GPIO_Pin_5,1);//初始化输出1吧
}



文件spi_24l01.c   
好像这样命名文件很不规范,不过无所谓了

#include "spi_24l01.h"


/**********************************
SPI初始化,
这个初始化是给24l01用的,所以在24l01初始化的时候不需要更改SPI初始化的配置
至于24L01的SPI协议中相位选择,高位在前还是低位在前等在24L01的时序图中可以看出来
***********************************/

void spi_init()
{
        GPIO_InitTypeDef GPIO_InitStruct;
        SPI_InitTypeDef SPI_InitStruct;
       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
       
        GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
        GPIO_InitStruct.GPIO_Pin=GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
        GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStruct);
        GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);//PB13/14/15上拉,不加上拉不知道行不行
       
        SPI_Cmd(SPI2, DISABLE); // 最好是在关闭状态配置SPI
       
        SPI_InitStruct.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_8;//72/8=9mhz
        SPI_InitStruct.SPI_CPHA=SPI_CPHA_1Edge;//第一个时钟就开始传数据了
        SPI_InitStruct.SPI_CPOL=SPI_CPOL_Low;//时钟线空闲的时候为低
        SPI_InitStruct.SPI_CRCPolynomial=7;//据说这玩意不为0就行
        SPI_InitStruct.SPI_DataSize=SPI_DataSize_8b;//每帧数据位8位
        SPI_InitStruct.SPI_Direction=SPI_Direction_2Lines_FullDuplex;//火力全开,全双工
        SPI_InitStruct.SPI_FirstBit=SPI_FirstBit_MSB;//好像时序图上是先传输低位的,????????
        SPI_InitStruct.SPI_Mode=SPI_Mode_Master;//STM32当然作为主机了
        SPI_InitStruct.SPI_NSS=SPI_NSS_Soft;//这玩意也不是很懂,大概意思是由软件控制SPI何时开始传输吧
        SPI_Init(SPI2,&SPI_InitStruct);
       
        SPI_Cmd(SPI2,ENABLE);//既然配置好了就开工吧
}




/**********************************************************
SPI收发一帧数据,因为是双向同步传输的,所以读和写可以共用一个函数
*************************************************************/

u8 spi_readWrite_byte(u8 SPI_TXdata)
{
        u8 try_count=0;
        while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE)== 0)//等待发送寄存器把数据发送完
        {
                try_count++;
                if(try_count>240)
                        break;
        }
        SPI_I2S_SendData(SPI2,SPI_TXdata);
       
        try_count=0;
        while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE)== 0)//这一次是等待接收完成
        {
                try_count++;
                if(try_count>240)
                        break;
        }
       
        return SPI_I2S_ReceiveData(SPI2);//返回读到的数据
}



文件spi_24l01.h

#ifndef _SPI_24L01_H
#define _SPI_24L01_H
#include "sys.h"

void spi_init();
u8 spi_readWrite_byte(u8 L_data);

#endif

文件24L01.c
#include "24L01.h"
#include "spi_24l01.h"
#include "delay.h"

//设置地址,每个通道都可以设置不同的地址,但是这里只设置了一个通道
const u8 TX_ADDRESS[5]={0x34,0x43,0x10,0x10,0x01}; //发送地址
const u8 RX_ADDRESS[5]={0x34,0x43,0x10,0x10,0x01};
/*******************************************************
24l01模块用起来不难,但是该怎么封装函数才是最合理的呢,
感觉原子哥的函数封装得挺合理的,就像原子的代码一样封装函数吧
**********************************************************/

void init_24L01()
{
        GPIO_InitTypeDef GPIO_InitStruct;//GPIO结构体
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOG,ENABLE);//打开GPIOB和GPIOE时钟

        GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出
        GPIO_InitStruct.GPIO_Pin=GPIO_Pin_12;//PB5
        GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;//翻转速度=10MHZ
        GPIO_Init(GPIOB, &GPIO_InitStruct);
        //GPIO_WriteBit(GPIOB,GPIO_Pin_12,1);//把这个拉高是为了防止在同一个SPI上的其他模块干扰
        GPIO_SetBits(GPIOB,GPIO_Pin_12);//上拉,原子的开发板才需要加这个上拉       
       
        //GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出
        GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7;
        GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;//这个速度应该是无所谓的吧
        GPIO_Init(GPIOG, &GPIO_InitStruct);
       
        GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_5;   
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD;
        GPIO_Init(GPIOG, &GPIO_InitStruct);
       
        GPIO_ResetBits(GPIOG,GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8);//PG6,7,8上拉        ,这几个IO是用来控制24L01模块的
       
        spi_init(); //SPI初始化,这里不需要重新配置SPI协议,因为SPI就是根据24L01的要求初始化的
       
        NRF24L01_CE=0;                         //发送数据时拉高,现在不发送数据,所以暂时为低
        NRF24L01_CSN=1;                        //SPI片选取消
}



/********************************
读取寄存器
入口;寄存器地址
返回值;读到的数据
说明;入口直接给寄存器地址就好,不需要考虑读寄存器的高三位指令,
**********************************/
u8 NRF24L01_Read_Reg(u8 reg)
{
         u8 temp_RXdata;
         NRF24L01_CSN=0;
         spi_readWrite_byte(reg);
         temp_RXdata = spi_readWrite_byte(0xff);
         NRF24L01_CSN=1;
         return temp_RXdata;
}


/**************************************
写寄存器;
入口参数1;寄存器地址,高三位会在函数里面处理
入口参数2;要写进寄存器的值
返回值;好像没什么用
*************************************/
u8 NRF24L01_Write_Reg(u8 reg,u8 value)
{
         u8 temp_RXdata;
         NRF24L01_CSN=0;
         spi_readWrite_byte(reg);
         temp_RXdata = spi_readWrite_byte(value);
         NRF24L01_CSN=1;
         return temp_RXdata;       
}

/******************************************
向寄存器中连续写数据;一般是设置通道地址和把数据从单片机发送到24L01的缓冲区
入口参数1;寄存器地址
入口参数2;要写入数组的地址
入口参数3;数据的长度
返回值;这个并没有什么用
******************************************/

u8 NRF24L01_Write_Buf(u8 reg, u8 *pBuf, u8 len)
{
        u8 i,status;
        NRF24L01_CSN=0;
        status = spi_readWrite_byte(reg);
        for(i=0;i         {
                spi_readWrite_byte(*pBuf++);               
        }
        NRF24L01_CSN=1;
        return status;//返回这个状态值有什么用呢
}




/********************************************
把数据从24L01的接收缓冲区读取到单片机中
入口参数1;寄存器地址
入口参数2;接收数组的地址
入口参数3;要读取的数据的长度
返回值;并没有什么用
********************************************/
u8 NRF24L01_Read_Buf(u8 reg,u8 *pBuf,u8 len)
{
        u8 i,status;
        NRF24L01_CSN=0;
        status = spi_readWrite_byte(reg);
        for(i=0;i         {
                pBuf=spi_readWrite_byte(0xff);               
        }
        NRF24L01_CSN=1;
        return status;//返回这个状态值有什么用呢
}




/*************************************
检测是否纯存在24L01模块
原理;往模块的寄存器里写数据,然后再把数据读出来
如果读取出来的数据是写进去的数据的话,证明模块存在,
如果数据不一样,那就是不存在了。
返回值;0=存在模块,1=不存在模块
注意;不管模块存在与否,程序都不能在这里死等
****************************************/
u8 NRF24L01_Check(void)
{
        u8 status;
        u8 test_data[2]={0x01,0x01};
       
        NRF24L01_CSN=0;
        NRF24L01_Write_Buf(W_REGISTER+TX_ADDR,test_data,2);
        NRF24L01_Read_Buf(TX_ADDR,test_data,2);
        if(test_data[0] + test_data[1] == 0x02)
                status = 0;//存在就返回0
        else
                status = 1;//不存在就返回1
       
        NRF24L01_CSN=1;
        return status;
}

/***************************************
把24L01接收到的数据读取到单片机里
入口参数;接收回来后存放数据的数组地址
返回值;一个标志位,0=成功,1=失败
说明;每次数据接收默认接收32个u8
******************************************/
u8 NRF24L01_RxPacket(u8 *txbuf)
{
        u8 status;
        status = NRF24L01_Read_Reg(STATUS);//读取状态寄存器的值
        NRF24L01_Write_Reg(W_REGISTER | STATUS,status);//因为寄存器是写1清零,所以把读取到的数据重新写进去就可以清除状态了
        NRF24L01_Read_Buf(R_RX_PAYLOAD,txbuf,32);
        if(status&RX_OK)
        {               
                NRF24L01_Write_Reg(FLUSH_RX,0xff);//清除TX FIFO寄存器 ,如果不清除会怎么样?
                return 0; //接收成功就返回0
        }
        return 1;//返回1就是接收失败了
}


/***************************************
把数据通过无线电发送出去
分两个步骤;
   1、把数据通过SPI从单片机发送到24L01的缓冲区
         2、把数据从24L01的缓冲区通过无线电发送出去
入口参数1;要发送的数组的首地址
返回值;标志位,MAX_TX=发送次数到达最大,反正就是发送失败了
                        TX_OK=发送成功,0xff=其他乱七八糟的原因导致的发送失败
*****************************************/
u8 NRF24L01_TxPacket(u8 *rxbuf)
{
        u8 status;
        NRF24L01_CE=0;
        NRF24L01_Write_Buf(W_RX_PAYLOAD,rxbuf,32);//一次性把32字节写到24L01的缓冲区
        NRF24L01_CE=1;//把数据通过无线发送出去
        while(NRF24L01_IRQ == 1);//等待发送完成,完成后会产生一个低电平中断
       
        status = NRF24L01_Read_Reg(STATUS);//读取状态寄存器的值
        NRF24L01_Write_Reg(W_REGISTER | STATUS,status);//因为寄存器是写1清零,所以把读取到的数据重新写进去就可以清除状态了
        if(status&MAX_TX)//到达最大重发次数
        {
                NRF24L01_Write_Reg(FLUSH_TX,0xff);//清除TX FIFO寄存器 ,如果不清除会怎么样?
                return MAX_TX;
        }
        if(status&TX_OK)//发送成功
        {
                return TX_OK;
        }
       
        return 0xff;//能运行到这里,肯定是发生了一些神奇的错误
}






                                 
//该函数初始化NRF24L01到TX模式
//设置TX地址,写TX数据宽度,设置RX自动应答的地址,填充TX发送数据,选择RF频道,波特率和LNA HCURR
//PWR_UP,CRC使能
//当CE变高后,即进入RX模式,并可以接收数据了                  
//CE为高大于10us,则启动发送.         
void NRF24L01_TX_Mode(void)
{                                                                                                                 
        NRF24L01_CE=0;            
          NRF24L01_Write_Buf(W_REGISTER | TX_ADDR,(u8*)TX_ADDRESS,5);//写TX节点地址
          NRF24L01_Write_Buf(W_REGISTER | RX_ADDR_P0,(u8*)RX_ADDRESS,5); //设置TX节点地址,主要为了使能ACK          

          NRF24L01_Write_Reg(W_REGISTER | EN_AA,0x01);     //使能通道0的自动应答   
          NRF24L01_Write_Reg(W_REGISTER | EN_RXADDR,0x01); //使能通道0的接收地址  
          NRF24L01_Write_Reg(W_REGISTER | SETUP_RETR,0x1f);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:16次
          NRF24L01_Write_Reg(W_REGISTER | RF_CH,40);       //设置RF通道为40
          NRF24L01_Write_Reg(W_REGISTER | RF_SETUP,0x0f);  //设置TX发射参数,0db增益,2Mbps,低噪声增益开启   
          NRF24L01_Write_Reg(W_REGISTER | CONFIG,0x0e);    //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断
        NRF24L01_CE=1;//CE为高,10us后启动发送
}







//该函数初始化NRF24L01到RX模式
//设置RX地址,写RX数据宽度,选择RF频道,波特率和LNA HCURR
//当CE变高后,即进入RX模式,并可以接收数据了       
void NRF24L01_RX_Mode(void)
{
        NRF24L01_CE=0;          
          NRF24L01_Write_Buf(W_REGISTER | RX_ADDR_P0,(u8*)RX_ADDRESS,5);//写RX节点地址
          
          NRF24L01_Write_Reg(W_REGISTER | EN_AA,0x01);    //使能通道0的自动应答   
          NRF24L01_Write_Reg(W_REGISTER | EN_RXADDR,0x01);//使能通道0的接收地址           
          NRF24L01_Write_Reg(W_REGISTER | RF_CH,40);             //设置RF通信频率                  
          NRF24L01_Write_Reg(W_REGISTER | RX_PW_P0,32);//选择通道0的有效数据宽度             
          NRF24L01_Write_Reg(W_REGISTER | RF_SETUP,0x0f);//设置TX发射参数,0db增益,2Mbps,低噪声增益开启   
          NRF24L01_Write_Reg(W_REGISTER | CONFIG, 0x0f);//配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式
          NRF24L01_CE = 1; //CE为高,进入接收模式
}



文件24L01.h

#ifndef _24L01_H
#define _24L01_H
#include  "sys.h"

void NRF24L01_TX_Mode(void);
void NRF24L01_RX_Mode(void);
u8 NRF24L01_RxPacket(u8 *rxbuf);
u8 NRF24L01_TxPacket(u8 *txbuf);
u8 NRF24L01_Write_Buf(u8 reg, u8 *pBuf, u8 len);
u8 NRF24L01_Read_Buf(u8 reg,u8 *pBuf,u8 len);
u8 NRF24L01_Read_Reg(u8 reg);
u8 NRF24L01_Write_Reg(u8 reg,u8 value);
u8 NRF24L01_Check(void);
void init_24L01();





//********************************************
//下面是24L01的端口控制线
//注意;发送板和接收板这3个引脚是不一样的
#define NRF24L01_CE   PGout(8) //24L01片选信号 ,0=使能,1=不使能,
#define NRF24L01_CSN  PGout(7) //SPI片选信号           0=SPI使能,1=SPI不使能,
#define NRF24L01_IRQ  PGin(6)  //IRQ主机数据输入,24L01的中断口,中断产生时本中断线被拉低



//***********************************************************
//下面是24L01模块的指令和寄存器地址,是直接从数据手册拷贝过来的
#define R_REGISTER     0x00
#define W_REGISTER           0x20
#define R_RX_PAYLOAD   0x61
#define W_RX_PAYLOAD   0xa0
#define FLUSH_TX                   0xe1
#define FLUSH_RX                   0xe2
#define REUSE_TX_PL           0xe3
#define NOP                                                 0xff

//这几个其实就是状态寄存器里面的状态位,为了计算方便定义为宏
#define MAX_TX                  0x10  //达到最大发送次数中断
#define TX_OK                   0x20  //TX发送完成中断
#define RX_OK                   0x40  //接收到数据中断

//寄存器地址
#define CONFIG                                 0X00
#define EN_AA                                         0X01
#define EN_RXADDR                         0X02
#define SETUP_AW                         0X03
#define SETUP_RETR                 0X04
#define RF_CH                                         0X05
#define RF_SETUP                         0X06
#define STATUS                                 0X07
#define OBSERVE_TX                 0X08
#define CD                                                 0X09
#define RX_ADDR_P0                 0X0A
#define RX_ADDR_P1                 0X0B
#define RX_ADDR_P2                 0X0C
#define RX_ADDR_P3                 0X0D
#define RX_ADDR_P4                 0X0E
#define RX_ADDR_P5                 0X0F
#define TX_ADDR                                 0X10
#define RX_PW_P0                         0X11
#define RX_PW_P1                         0X12
#define RX_PW_P2                         0X13
#define RX_PW_P3                         0X14
#define RX_PW_P4                         0X15
#define RX_PW_P5                         0X16
#define FIFO_STATUS                 0X17
#define NOP                                                 0xff
#define NOP                                                 0xff
#define NOP                                                 0xff
#define NOP                                                 0xff
#define NOP                                                 0xff




#endif



对于接收板,只有Main.c不一样,其他的四个文件大部分都是一样的(除了控制线的IO口不一样),所以这里只放接收板的main.c文件
#include "sys.h"
#include "delay.h"
#include "spi_24l01.h"
#include "24L01.h"

#define LED(value) GPIO_WriteBit(GPIOA,GPIO_Pin_8,value)


/************************************************************
功能;LED闪烁,间隔为100ms
其中LED接在PB5上,低电平有效
****************************************************************/

void init_led();




int main(void)
{       
        u8  buf_data[33]={0};//用来存放临时数据
        delay_init();        //延时函数初始化
        init_led();         //LED初始化
        init_24L01();
        LED(NRF24L01_Check());
       
        NRF24L01_RX_Mode();

        while(1)
        {
                if(NRF24L01_RxPacket(buf_data) == 0)
                {
                        LED(buf_data[10]);
                }
                else
                {
                        delay_us(200);
                }
        }
}

  

void init_led()  
{
        GPIO_InitTypeDef GPIO_InitStruct;//GPIO结构体
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//打开GPIOB和GPIOE时钟

        GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出
        GPIO_InitStruct.GPIO_Pin=GPIO_Pin_8;//PB5
        GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;//翻转速度=10MHZ
        GPIO_Init(GPIOA, &GPIO_InitStruct);
        GPIO_WriteBit(GPIOA,GPIO_Pin_5,1);//初始化输出1吧
}
举报

更多回帖

×
20
完善资料,
赚取积分