天线|RF射频
直播中

王莹

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

如何做一个STM32+NRF24L01程序?

关于NRF24L01的程序,我之前也在这个版面问过,原子给了我一个链接,我测试过,那个程序似乎有些问题,当然也可能是我不明白具体该怎么使用,并不是个人攻击哈,我也是初学STM32,尤其是无线通信部分,理解初学者的心情,所以我把自己写的程序放上来,让初学的同学们做一个参考。



我之前做过CC2530,所以zigbee程序的编写流程对我影响比较大。我认为无线收发程序应该是在发送端和接收端烧写进去不同的程序,这样可以增加灵活性,而且也便于理解。



简单介绍一下程序的情况,我的程序实现1收2发功能,实际上也可以多几路发送,据说最多可以实现1收6发,这个我暂时没有条件。我这个是单位给买的开发板,总共5块mini,最多是1收4发,所以有条件的可以自己做一个多路收发的测试,我就不写了。



两个发射机都是用PC0来采集AD信号,再将采集出来的信号传送到接收端上,接收端使用KEY0来切换显示两个发射机。通道选择比较高深,我暂时不会,所以我在不同的发射机上发送不同的字符串,比如说第一个发射机发送A_x.xx,第二个发射机发送B_x.xx(x.xx是代表AD采集出来的数值,例如1.23),接收端在按键按下后,可以根据接收过来数据的前缀,进行不同的显示,也就达到通道选择的目的了。方法比较笨,但是可以实现。



不多说了,我先放上NRF24L01的代码(中文注释拷出来后就成乱码了,大家凑合看吧,重要的地方我会重新写一下的)。




[C] 纯文本查看 复制代码
#include "24l01.h"#include "delay.h"#include "spi.h"#include "stm32f10x_spi.h"#include "lcd.h"#include "led.h"////////////////////////////////////////////////////////////////////////////////// //±????ò???©?§?°??????????×÷???í???????????????ü????????//ALIENTEK MiniSTM32??·?°?//NRF24L01?????ú??   //??????×?@ALIENTEK//????????:www.openedv.com//????????:2014/3/12//°?±???V1.0//°??¨?ù??????°?±?????//Copyright(C) ?????????í??×????????????? 2009-2019//All rights reserved  //////////////////////////////////////////////////////////////////////////////////    const u8 TX_ADDRESS[TX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //地址很重要,这几行地址一定要写对,可以看看大神们写的帖子const u8 RX_ADDRESS0[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //??0????const u8 RX_ADDRESS1[RX_ADR_WIDTH]={0xc2,0xc2,0xc2,0xc2,0xc1}; //??1????const u8 RX_ADDRESS2[RX_ADR_WIDTH]={0xb3}; //??2????const u8 RX_ADDRESS3[RX_ADR_WIDTH]={0xa5}; //??3????const u8 RX_ADDRESS4[RX_ADR_WIDTH]={0x35}; //??4????const u8 RX_ADDRESS5[RX_ADR_WIDTH]={0x8f}; //??5????//const u8 TX_ADDRESS[TX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //·??????·//const u8 RX_ADDRESS[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //·??????·//??????24L01??IO??void NRF24L01_Init(void){  GPIO_InitTypeDef GPIO_InitStructure;SPI_InitTypeDef  SPI_InitStructure;  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC, ENABLE );GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //???ì????GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //???ì????GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_SetBits(GPIOC,GPIO_Pin_4);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU  ;   //????????GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4);SPI1_Init();    //??????SPISPI_Cmd(SPI1, DISABLE); // SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //?è??SPI???ò?ò?????ò??????????:SPI?è???????????ò?????¤SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//?è??SPI?¤×÷????:?è?????÷SPISPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;//?è??SPI???????ó??:SPI·???????8?????á??SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;//???????®???±????????:?±???ü????????SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;//?????????????????±????SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//NSS???????????¨NSS?????©?????í???¨????SSI???©???í:????NSS??????SSI??????SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;//?¨???¨?????¤·???????:?¨?????¤·???????256SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;//???¨??????????MSB??????LSB??????:??????????MSB??????SPI_InitStructure.SPI_CRCPolynomial = 7;//CRC?????????à????SPI_Init(SPI1, &SPI_InitStructure);  //?ù??SPI_InitStruct?????¨???????????????èSPIx?????÷NRF24L01_CE=0; //????24L01NRF24L01_CSN=1;//SPI???????? }//?ì??24L01??·?????//·?????:0??????;1???§°?u8 NRF24L01_Check(void){u8 buf[5]={0XA5,0XA5,0XA5,0XA5,0XA5};u8 i;SPI1_SetSpeed(SPI_BaudRatePrescaler_8); //spi??????9Mhz?¨24L01??×??óSPI?±????10Mhz?©    NRF24L01_Write_Buf(NRF_WRITE_REG+TX_ADDR,buf,5);//????5??×????????·.NRF24L01_Read_Buf(TX_ADDR,buf,5); //?????????????·  for(i=0;i<5;i++)if(buf!=0XA5)break;    if(i!=5)return 1;//?ì??24L01?í?óreturn 0; //?ì????24L01}  //SPI???????÷//reg:???¨?????÷???·//value:????????u8 NRF24L01_Write_Reg(u8 reg,u8 value){u8 status;   NRF24L01_CSN=0;                 //????SPI????  status =SPI1_ReadWriteByte(reg);//·????????÷??   SPI1_ReadWriteByte(value);      //?????????÷????  NRF24L01_CSN=1;                 //????SPI????     return(status);       //·???×?????}//????SPI?????÷??//reg:???????????÷u8 NRF24L01_Read_Reg(u8 reg){u8 reg_val;     NRF24L01_CSN = 0;          //????SPI????  SPI1_ReadWriteByte(reg);   //·????????÷??  reg_val=SPI1_ReadWriteByte(0XFF);//?????????÷????  NRF24L01_CSN = 1;          //????SPI????      return(reg_val);           //·???×?????}//?????¨???????????¨?¤????????//reg:?????÷(????)//*pBuf:????????//len:?????¤??//·?????,??????????×????????÷?? u8 NRF24L01_Read_Buf(u8 reg,u8 *pBuf,u8 len){u8 status,u8_ctr;         NRF24L01_CSN = 0;           //????SPI????  status=SPI1_ReadWriteByte(reg);//·????????÷??(????),??????×?????       for(u8_ctr=0;u8_ctr






回帖(3)

李秀珍

2020-5-12 08:47:35
接下来就是发送端程序了,发送端是要在两个不同的mini板里烧写不同的程序,有一部分代码是需要修改的,大家看中文注释吧,乱码就不用看了。




[C] 纯文本查看 复制代码
#include "led.h"#include "delay.h"#include "sys.h"#include "usart.h"#include "lcd.h"#include "key.h"#include "spi.h"#include "24l01.h"   #include "adc.h"#include "stm32f10x_adc.h"//ALIENTEK Mini STM32??·?°?·????ú??24//?????¨?????é  //?????§????www.openedv.com//?????????í??×?????????????   int main(void) { u8 key,mode;//???????????????¨?? u8 i,*p; u16 adcx; float temp;u16 t=0; u8 tmp_buf[10]="A_";//????u8 tmp_buf2[10]="B_"; //???? char buffer[10];delay_init();     //???±??????????NVIC_Configuration(); uart_init(9600); //?®??????????9600LED_Init();  //????????LED??????????????LCD_Init();   //??????LCD  KEY_Init();//°??ü??????Adc_Init(); NRF24L01_Init();    //??????NRF24L01   POINT_COLOR=RED;//?è??×??????ì?? LCD_ShowString(60,50,200,16,16,"Mini STM32");LCD_ShowString(60,70,200,16,16,"NRF24L01 TEST");LCD_ShowString(60,90,200,16,16,"ATOM@ALIENTEK");LCD_ShowString(60,110,200,16,16,"2014/3/12");   while(NRF24L01_Check())//?ì?éNRF24L01??·?????.{LCD_ShowString(60,130,200,16,16,"NRF24L01 Error");delay_ms(200);LCD_Fill(60,130,239,130+16,WHITE); delay_ms(200);}   LCD_ShowString(60,130,200,16,16,"NRF24L01 OK");//·?????LCD_ShowString(60,150,200,16,16,"NRF24L01 TX_Mode");NRF24L01_TX_Mode(); while(1)//??????·??·?¨????????????!{adcx=Get_Adc_Average(ADC_Channel_10,10);temp=(float)adcx*(3.3/4096);sprintf(buffer,"%f",temp);p=buffer;//这个是第一个发射机的代码,把前面有屏蔽的部分去掉,同时要把后面第二个发射机的代码屏蔽掉,编译后就可以直接烧写进第一个mini板了// for(i=2;i<6;i++)//这么写是想只取3位数字,例如1.23或者12.3// {// tmp_buf=*p;// p++;// }// if(NRF24L01_TxPacket(tmp_buf)==TX_OK)// {// LCD_ShowString(60,170,239,32,16,"Sended DATA:");// LCD_ShowString(0,190,239,32,16,tmp_buf); // tmp_buf[9]=0; // }//以下是第二个发射机,使用的时候也是一样的,要把前面第一个发射机的几行代码屏蔽掉,再烧写进第二个发射机for(i=2;i<6;i++){tmp_buf2=*p;p++;}if(NRF24L01_TxPacket(tmp_buf2)==TX_OK){LCD_ShowString(60,170,239,32,16,"Sended DATA:");LCD_ShowString(0,190,239,32,16,tmp_buf2); tmp_buf2[9]=0;}else{    LCD_ShowString(60,170,239,32,16,"Send Failed "); LCD_Fill(0,188,240,218,WHITE);//??????????????   };LED0=!LED0;delay_ms(500);}   }




举报

仲娜娜

2020-5-12 08:58:53
然后就是接收端了,两个发射机发射过来的字符串格式是这样的:A_1.23以及B_4.56,在按下KEY0时,可以判断前缀是A还是B,然后剔除掉前缀,只显示1.23或者4.56。代码如下。




[C] 纯文本查看 复制代码
//???????????ò?????ò?á??????×???????????×?mini°????ò??·?±????????????é//°ü?¨?????????÷??pH???????÷??DHT11//±????ò??????????1??2·????????ò????????#include "led.h"#include "delay.h"#include "sys.h"#include "usart.h"#include "lcd.h"#include "key.h"#include "spi.h"#include "24l01.h"   #include "stdio.h"//ALIENTEK Mini STM32??·?°?·????ú??24//?????¨?????é  //?????§????www.openedv.com//?????????í??×?????????????   int main(void) { u8 key,flag=1;//flag是用于切换不同的通道,初始默认是通道1,或者说是第一个发射机u16 t=0; u8 rec_buf[10];//????????u8 rec_temp1[10];//??????·?????1??????????????????u8 rec_temp2[10];//??????·?????2?????????????????? u8 *p;u8 i=0;delay_init();     //???±??????????NVIC_Configuration(); uart_init(9600); //?®??????????9600LED_Init();  //????????LED??????????????LCD_Init();   //??????LCD  KEY_Init();//°??ü?????? NRF24L01_Init();    //??????NRF24L01   POINT_COLOR=RED;//?è??×??????ì?? LCD_ShowString(60,50,200,16,16,"Mini STM32");LCD_ShowString(60,70,200,16,16,"NRF24L01 TEST");LCD_ShowString(60,90,200,16,16,"ATOM@ALIENTEK");LCD_ShowString(60,110,200,16,16,"2014/3/12");   while(NRF24L01_Check())//?ì?éNRF24L01??·?????.{LCD_ShowString(60,130,200,16,16,"NRF24L01 Error");delay_ms(200);LCD_Fill(60,130,239,130+16,WHITE); delay_ms(200);}   LCD_ShowString(60,130,200,16,16,"NRF24L01 OK");//??????LCD_ShowString(60,150,200,16,16,"NRF24L01 RX_Mode");LCD_ShowString(60,170,200,16,16,"Received DATA:");NRF24L01_RX_Mode(); while(1){//选择不同的发射机,本程序暂时是2个发射机key=KEY_Scan(0);if(key==KEY0_PRES){flag++;//flag初始为1,加1表示选择发射机2 if(flag>2)//如果达到3,需要重置为1,就是第一个发射机flag=1;}if(NRF24L01_RxPacket(rec_buf)==0)//???©??????????,?ò????????{ //????????·????ú1????????°ü?¨???? p=rec_buf;if(flag==1){if(rec_buf[0]=='A'){p++;p++;LCD_ShowString(0,190,239,32,16,p);LED0=!LED0;}}if(flag==2){if(rec_buf[0]=='B'){p++;p++;LCD_ShowString(0,190,239,32,16,p);LED1=!LED1;}}}else delay_us(100);}}




举报

陶天瑛

2020-5-12 09:30:33
楼主不赖啊,不错,谢谢分享!!!
举报

更多回帖

×
20
完善资料,
赚取积分