|
NRF24L01使用出了問(wèn)題,但找不到原因,發(fā)此帖向各位前輩請(qǐng)教一下
需求:采用NRF24L01作無(wú)線傳輸,接收端接收到特定數(shù)組,蜂鳴器就會(huì)響,當(dāng)接收到數(shù)組不為此數(shù)組時(shí),蜂鳴器關(guān)閉
問(wèn)題:接收端不能正常工作
部分代碼如下:
(一)NRF24L01配置
- #include "bsp_spi_nrf.h"
- u8 RX_BUF[RX_PLOAD_WIDTH]; //接收數(shù)據(jù)緩存
- u8 TX_BUF[TX_PLOAD_WIDTH]; //發(fā)射數(shù)據(jù)緩存
- u8 TX_ADDRESS[TX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x01}; // 定義一個(gè)靜態(tài)發(fā)送地址
- u8 RX_ADDRESS[RX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x01};
- void Delay(__IO u32 nCount)
- {
- for(; nCount != 0; nCount--);
- }
- /*------------------------------------------------------------SPI的 I/O配置-------------------------------------------------------------------*/
- void SPI_NRF_Init(void)
- {
- SPI_InitTypeDef SPI_InitStructure;
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA
- |NRF_CSN_GPIO_CLK
- |NRF_CE_GPIO_CLK
- |NRF_IRQ_GPIO_CLK,ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
- /*SCK,MISO,MOSI引腳(PA5,PA6,PA7)*/
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復(fù)用功能
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- /*CSN引腳*/
- GPIO_InitStructure.GPIO_Pin = NRF_CSN_PIN;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Init(NRF_CSN_GPIO_PORT, &GPIO_InitStructure);
- /*CE引腳*/
- GPIO_InitStructure.GPIO_Pin = NRF_CE_PIN;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Init(NRF_CE_GPIO_PORT, &GPIO_InitStructure);
- /*IRQ引腳*/
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ; //上拉輸入
- GPIO_Init(NRF_IRQ_GPIO_PORT, &GPIO_InitStructure);
-
- NRF_CSN_HIGH(); //拉高csn引腳,NRF進(jìn)入空閑狀態(tài)
- /*配置SPI*/
- SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //雙線全雙工
- SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主模式
- SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //數(shù)據(jù)大小8位
- SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //時(shí)鐘極性,空閑時(shí)為低
- SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //第1個(gè)邊沿有效,上升沿為采樣時(shí)刻
- SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信號(hào)由軟件產(chǎn)生
- SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; //8分頻,9MHz
- SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //高位在前
- SPI_InitStructure.SPI_CRCPolynomial = 7;
- SPI_Init(SPI1, &SPI_InitStructure);
- SPI_Cmd(SPI1, ENABLE);//使能SPI
- }
- /*----------------------------------------------------向NRF讀/寫一字節(jié)數(shù)據(jù)--------------------------------------------------------------*/
- u8 SPI_NRF_RW(u8 dat)
- {
- while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); //當(dāng)SPI發(fā)送緩沖器非空時(shí)等待
- SPI_I2S_SendData(SPI1, dat); //通過(guò)SPI發(fā)送一字節(jié)數(shù)據(jù)
- while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); //當(dāng)SPI接收緩沖器為空時(shí)等待
- return SPI_I2S_ReceiveData(SPI1); //返回從SPI接收到的數(shù)據(jù)
- }
- /*---------------------------------------------------向NRF特定的寄存器寫入數(shù)據(jù)----------------------------------------------------------------*/
- //reg:NRF的命令+寄存器地址\
- dat:將要向寄存器寫入的數(shù)據(jù)\
- status:NRF的status寄存器的狀態(tài)
- u8 SPI_NRF_WriteReg(u8 reg,u8 dat)
- {
- u8 status;
- NRF_CE_LOW();
- NRF_CSN_LOW(); //置低CSN,使能SPI傳輸
- status = SPI_NRF_RW(reg); //發(fā)送命令及寄存器號(hào)
- SPI_NRF_RW(dat); //向寄存器寫入數(shù)據(jù)
- NRF_CSN_HIGH(); //CSN拉高,完成
- return(status); //返回狀態(tài)寄存器的值
- }
- /*--------------------------------------------------從NRF特定的寄存器讀出數(shù)據(jù)-----------------------------------------------------------------*/
- //reg:NRF的命令+寄存器地址\
- reg_val:寄存器中的數(shù)據(jù)
- u8 SPI_NRF_ReadReg(u8 reg)
- {
- u8 reg_val;
- NRF_CE_LOW();
- NRF_CSN_LOW(); //置低CSN,使能SPI傳輸
- SPI_NRF_RW(reg); //發(fā)送寄存器號(hào)
- reg_val = SPI_NRF_RW(NOP); //讀取寄存器的值
- NRF_CSN_HIGH(); //CSN拉高,完成
-
- return reg_val;
- }
- /*------------------------------------------------------向NRF的寄存器中寫入一串?dāng)?shù)據(jù)----------------------------------------------------------*/
- //reg : NRF的命令+寄存器地址\
- pBuf:用于存儲(chǔ)將被讀出的寄存器數(shù)據(jù)的數(shù)組,外部定義\
- bytes: pBuf的數(shù)據(jù)長(zhǎng)度\
- status:NRF的status寄存器的狀態(tài)\
- u8 SPI_NRF_ReadBuf(u8 reg,u8 *pBuf,u8 bytes)
- {
- u8 status, byte_cnt;
- NRF_CE_LOW();
- NRF_CSN_LOW(); //置低CSN,使能SPI傳輸
-
-
- status = SPI_NRF_RW(reg); //發(fā)送寄存器號(hào)
- for(byte_cnt=0;byte_cnt<bytes;byte_cnt++) //讀取緩沖區(qū)數(shù)據(jù)
- pBuf[byte_cnt] = SPI_NRF_RW(NOP);
- NRF_CSN_HIGH(); //CSN拉高,完成
-
- return status; //返回寄存器狀態(tài)值
- }
- /*-----------------------------------------------------向NRF的寄存器中寫入一串?dāng)?shù)據(jù)-------------------------------------------------------------*/
- //reg : NRF的命令+寄存器地址\
- pBuf:存儲(chǔ)了將要寫入寫寄存器數(shù)據(jù)的數(shù)組,外部定義\
- bytes: pBuf的數(shù)據(jù)長(zhǎng)度\
- status: NRF的status寄存器的狀態(tài)
- u8 SPI_NRF_WriteBuf(u8 reg ,u8 *pBuf,u8 bytes)
- {
- u8 status,byte_cnt;
- NRF_CE_LOW();
- NRF_CSN_LOW(); //置低CSN,使能SPI傳輸
- status = SPI_NRF_RW(reg); //發(fā)送寄存器號(hào)
- for(byte_cnt=0;byte_cnt<bytes;byte_cnt++) //向緩沖區(qū)寫入數(shù)據(jù)
- SPI_NRF_RW(*pBuf++);
-
- NRF_CSN_HIGH(); //CSN拉高,完成
- return (status); //返回NRF24L01的狀態(tài)
- }
- /*----------------------------------------------------------配置并進(jìn)入接收模式-------------------------------------------------------------*/
- void NRF_RX_Mode(void)
- {
- NRF_CE_LOW();
- SPI_NRF_WriteBuf(NRF_WRITE_REG+RX_ADDR_P0,RX_ADDRESS,RX_ADR_WIDTH);//寫RX節(jié)點(diǎn)地址
- SPI_NRF_WriteReg(NRF_WRITE_REG+EN_AA,0x01); //使能通道0的自動(dòng)應(yīng)答
- SPI_NRF_WriteReg(NRF_WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址
- SPI_NRF_WriteReg(NRF_WRITE_REG+RF_CH,CHANAL); //設(shè)置RF通信頻率
- SPI_NRF_WriteReg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH); //選擇通道0的有效數(shù)據(jù)寬度
- SPI_NRF_WriteReg(NRF_WRITE_REG+RF_SETUP,0x0f); //設(shè)置TX發(fā)射參數(shù),0db增益,2Mbps,低噪聲增益開(kāi)啟
- SPI_NRF_WriteReg(NRF_WRITE_REG+CONFIG, 0x0f); //配置基本工作模式的參數(shù);PWR_UP,EN_CRC,16BIT_CRC,接收模式
- NRF_CE_HIGH(); //CE拉高,進(jìn)入接收模式
- }
- /*----------------------------------------------------------配置發(fā)送模式-----------------------------------------------------------*/
- void NRF_TX_Mode(void)
- {
- NRF_CE_LOW();
- SPI_NRF_WriteBuf(NRF_WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH); //寫TX節(jié)點(diǎn)地址
- SPI_NRF_WriteBuf(NRF_WRITE_REG+RX_ADDR_P0,RX_ADDRESS,RX_ADR_WIDTH); //設(shè)置TX節(jié)點(diǎn)地址,主要為了使能ACK
- SPI_NRF_WriteReg(NRF_WRITE_REG+EN_AA,0x01); //使能通道0的自動(dòng)應(yīng)答
- SPI_NRF_WriteReg(NRF_WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址
- SPI_NRF_WriteReg(NRF_WRITE_REG+SETUP_RETR,0x1a); //設(shè)置自動(dòng)重發(fā)間隔時(shí)間:500us + 86us;最大自動(dòng)重發(fā)次數(shù):10次
- SPI_NRF_WriteReg(NRF_WRITE_REG+RF_CH,CHANAL); //設(shè)置RF通道為CHANAL
- SPI_NRF_WriteReg(NRF_WRITE_REG+RF_SETUP,0x0f); //設(shè)置TX發(fā)射參數(shù),0db增益,2Mbps,低噪聲增益開(kāi)啟
- SPI_NRF_WriteReg(NRF_WRITE_REG+CONFIG,0x0e); //配置基本工作模式的參數(shù);PWR_UP,EN_CRC,16BIT_CRC,發(fā)射模式,開(kāi)啟所有中斷
- NRF_CE_HIGH(); //CE拉高,進(jìn)入發(fā)送模式
- Delay(0xffff); //CE要拉高一段時(shí)間才進(jìn)入發(fā)送模式
- }
- /*---------------------------------------------------------主要用于NRF與MCU是否正常連接--------------------------------------------------------*/
- //retval: SUCCESS/ERROR 連接正常/連接失敗
- u8 NRF_Check(void)
- {
- u8 buf[5]={0xC2,0xC2,0xC2,0xC2,0xC2};
- u8 buf1[5];
- u8 i;
-
-
- SPI_NRF_WriteBuf(NRF_WRITE_REG+TX_ADDR,buf,5);//寫入5個(gè)字節(jié)的地址
- SPI_NRF_ReadBuf(TX_ADDR,buf1,5); //讀出寫入的地址
- for(i=0;i<5;i++) //判斷是否連接成功
- {
- if(buf1[i]!=0xC2)
- break;
- }
- if(i==5)
- return SUCCESS ; //MCU與NRF成功連接
- else
- return ERROR ; //MCU與NRF不正常連接
- }
- /*-----------------------------------------------------向NRF的發(fā)送緩沖區(qū)中寫入數(shù)據(jù)--------------------------------------------------------------*/
- //txBuf:存儲(chǔ)了將要發(fā)送的數(shù)據(jù)的數(shù)組,外部定義\
- retval: 發(fā)送結(jié)果,成功返回TXDS,失敗返回MAXRT或ERROR
- u8 NRF_Tx_Dat(u8 *txbuf)
- {
- u8 state;
- NRF_CE_LOW(); //CE為低,進(jìn)入待機(jī)模式1
- SPI_NRF_WriteBuf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);//寫數(shù)據(jù)到TX BUF 最大 32個(gè)字節(jié)
- NRF_CE_HIGH(); //CE為高,txbuf非空,發(fā)送數(shù)據(jù)包
-
- while(NRF_Read_IRQ()!=0); //等待發(fā)送完成中斷
- state = SPI_NRF_ReadReg(STATUS); //讀取狀態(tài)寄存器的值
- SPI_NRF_WriteReg(NRF_WRITE_REG+STATUS,state); //清除TX_DS或MAX_RT中斷標(biāo)志
- SPI_NRF_WriteReg(FLUSH_RX,NOP); //清除TX FIFO寄存器
- /*判斷中斷類型*/
- if(state&MAX_RT) //達(dá)到最大重發(fā)次數(shù)
- return MAX_RT;
- else if(state&TX_DS) //發(fā)送完成
- return TX_DS;
- else
- return ERROR; //其他原因發(fā)送失敗
- }
- /*--------------------------------------------------------從NRF的接收緩沖區(qū)中讀出數(shù)據(jù)------------------------------------------------------------*/
- //rxBuf :用于接收該數(shù)據(jù)的數(shù)組,外部定義\
- retval: 接收結(jié)果
- u8 NRF_Rx_Dat(u8 *rxbuf)
- {
- u8 state;
- NRF_CE_HIGH(); //進(jìn)入接收狀態(tài)
- /*輪詢標(biāo)志*/
- while(NRF_Read_IRQ()==0)
- {
- NRF_CE_LOW(); //進(jìn)入待機(jī)狀態(tài)
- state=SPI_NRF_ReadReg(NRF_READ_REG+STATUS); //讀取status寄存器的值
- SPI_NRF_WriteReg(NRF_WRITE_REG+STATUS,state); //清除中斷標(biāo)志
- /*判斷是否接收到數(shù)據(jù)*/
- if(state&RX_DR) //接收到數(shù)據(jù)
- {
- SPI_NRF_ReadBuf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH); //讀取數(shù)據(jù)
- SPI_NRF_WriteReg(FLUSH_RX,NOP); //清除RX FIFO寄存器
- return RX_DR;
- }
- else
- return ERROR; //沒(méi)收到任何數(shù)據(jù)
- }
- return ERROR; //沒(méi)收到任何數(shù)據(jù)
- }
- void Beep_ON(void)
- {
- GPIO_InitTypeDef GPIO_InitBeep;
-
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
-
- GPIO_InitBeep.GPIO_Mode=GPIO_Mode_Out_PP;
- GPIO_InitBeep.GPIO_Pin=GPIO_Pin_0;
- GPIO_InitBeep.GPIO_Speed=GPIO_Speed_50MHz;
- GPIO_Init(GPIOC,&GPIO_InitBeep);
-
- GPIO_SetBits(GPIOC, GPIO_Pin_0);
- }
- void Beep_OFF(void)
- {
- GPIO_InitTypeDef GPIO_InitBeep;
-
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
-
- GPIO_InitBeep.GPIO_Mode=GPIO_Mode_Out_PP;
- GPIO_InitBeep.GPIO_Pin=GPIO_Pin_0;
- GPIO_InitBeep.GPIO_Speed=GPIO_Speed_50MHz;
- GPIO_Init(GPIOC,&GPIO_InitBeep);
-
- GPIO_ResetBits(GPIOC, GPIO_Pin_0);
- }
- (二)接收端main.c部分代碼
- int compare(u8 x[],u8 y[])
- {
- int a=0;
- for(i=0;i<32;i++)
- {
- if(x[i]==y[i])
- a++;
- }
- if(a==32)
- return 1;
- else
- return 0;
- }
- void main(void)
- {
- int ans=0;
- SPI_NRF_Init();
- LED_GPIO_Config();
- NRF_RX_Mode();
- for(i=0;i<32;i++)
- mishi[i]=i;
- while(1)
- {
- status=NRF_Rx_Dat(rxbuf);
- if(status==RX_DR)
- ans=compare(rxbuf,mishi);
- if(ans==1)
- Beep_ON();
- else
- Beep_OFF();
- }
- // LED_RGB('R');
- }
- (三)發(fā)射端部分代碼
- SPI_NRF_Init();
- NRF_TX_Mode();
- if (count>57600)
- {
- //Beep_ON();
- NRF_Tx_Dat(mishi);
- }
- else NRF_Tx_Dat(errorbuf);
復(fù)制代碼 |
|