微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > STM32 驱动无线NRF24L01 完成串口数据传输

STM32 驱动无线NRF24L01 完成串口数据传输

时间:12-03 来源:互联网 点击:

}

extern u8 RX_NU;
void test (void)
{
if (Uart2_Get_Flag!=0&&Timer2==0)
{
sent_data(TX_BUF,(u16)Uart2_Get_Flag);
Uart2_Get_Flag=0;
}

if(Timer2==0&&RX_NU==2)
{
RX_NU=1;
USART2_Puts("传输错误 ");
USART2_Puts("\r\n");
}
}

两个中断 串口 和 外部中断

/*******************************************************************************
* Function Name : EXTI0_IRQHandler
* Description : This function handles External interrupt Line 0 request.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
extern u8 sta;
extern char RX_BUF[256];
extern uchar TX_BUF[256];
extern u8 SPI_RW_Reg(u8 reg, u8 value);
extern void RX_Mode(void);
extern uchar SPI_Read_Buf(uchar reg, char * pBuf, uchar bytes);
u8 RX_NU=1;//1接收长度 2接收数据
u16 rectnu,onerc; //接收串长,接收次数
char* PRX_BUF=RX_BUF;
void EXTI0_IRQHandler(void)
{
EXTI_ClearITPendingBit(EXTI_Line0);
tran=1;
CSN_L;
sta=SPI_RW(NOP); // 返回状态寄存器
CSN_H;

if(MAX_RT)
{
USART2_Puts("对方无应答 ");
CSN_L;
SPI_RW(FLUSH_TX); // 清除TX FIFO,若没有清除在清除MAX_RT中断标志后重发
CSN_H;
SPI_RW_Reg(RF_WRITE_REG + STATUS, sta);
}

if(TX_DS)
{
SPI_RW_Reg(RF_WRITE_REG + STATUS, sta); // 清除TX_DS或MAX_RT中断标志
}

if(RX_DR) // 判断是否接受到数据
{

if(RX_NU==1)
{
CE_L;
SPI_Read_Buf(RD_RX_PLOAD, RX_BUF, TX_PLOAD_WIDTH); // 从RX FIFO读出数据
SPI_RW_Reg(RF_WRITE_REG + STATUS, sta); // 清除RX_DS中断标志
rectnu=RX_BUF[0];rectnu|=RX_BUF[1]<8; //接收串长
onerc=rectnu/33+1; //计算接收次数
RX_NU=2;RX_Mode();Timer2=500;/*超时时间*/
return;
}

if(RX_NU==2)
{
CE_L;
SPI_Read_Buf(RD_RX_PLOAD, PRX_BUF, TX_PLOAD_WIDTH); // 从RX FIFO读出数据
SPI_RW_Reg(RF_WRITE_REG + STATUS, sta); // 清除RX_DS中断标志
onerc--;PRX_BUF+=32; //接收计数 接收指针移动

if(!onerc)
{
RX_BUF[rectnu]=\0; //截取有效串长
USART2_Puts(RX_BUF); //串口发送接收到的字符
USART2_Puts("\r\n");
PRX_BUF=RX_BUF; //恢复指针
RX_NU=1;
}

RX_Mode();Timer2=200;/*超时时间*/
return;
}
}
LED;
RX_Mode();

}

/*******************************************************************************
* Function Name : USART2_IRQHandler
* Description : This function handles USART2 global interrupt request.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
extern u16 Uart2_Get_Flag;
extern u8 Uart2_Get_Data;
extern u8 TX_BUF[256];
void USART2_IRQHandler(void)
{
//接收中断
if(USART_GetITStatus(USART2,USART_IT_RXNE)==SET)
{
Timer2=500;//500MS后nfr2401发送
USART_ClearITPendingBit(USART2,USART_IT_RXNE);
TX_BUF[Uart2_Get_Flag]=USART_ReceiveData(USART2);
Uart2_Get_Flag++;
//USART2_Puts(TX_BUF);
}

//溢出-如果发生溢出需要先读SR,再读DR寄存器 则可清除不断入中断的问题
if(USART_GetFlagStatus(USART2,USART_FLAG_ORE)==SET)
{
USART_ClearFlag(USART2,USART_FLAG_ORE);//读SR
USART_ReceiveData(USART2);//读DR
}
}

在 外部中断中 可以一次传输最少要两次 第一次RX_NU==1 用来接收此次传输的数据长度 用来截取有效串长,第二次RX_NU==2 就收数据放到数组里 若是数据长于32个字节就分多次传输。其中引入 超时机制 若是200/500 MS 后传输还没完成(RX_NU再次 等于1)就放弃接收数据 直接接收再次新的串长度。这个机制很重要但还有待完善。

串口中也一样500MS 还没新的数据进来就说明串口接收完成 之后就发送数据。Uart2_Get_Flag 当然就是串长了。

NRF24L01 可以参考其数据手册 都是中文好说好说~~这里就不提了。

#ifndef _API_DEF_
#define _API_DEF_

// Define interface to nRF24L01

//* Define SPI pins
/*sbit CE = P1^0; // Chip Enable pin signal (output)
sbit CSN = P1^1; // Slave Select pin, (output to CSN, nRF24L01)
sbit IRQ = P1^3; // Interrupt signal, from nRF24L01 (input)
sbit MISO = P1^4; // Master In, Slave Out pin (input)
sbit MOSI = P1^5; // Serial Clock pin, (output)
sbit SCK = P1^7; // Master Out, Slave In pin (output)
*/

// SPI(nRF24L01) commands
#define RF_READ_REG 0x00 // Define read command to register
#define RF_WRITE_REG 0x20 // Define write command to register
#define RD_RX_PLOAD 0x61 // Define RX payload register address
#define WR_TX_PLOAD 0xA0 // Define TX payload register address
#define FLUSH_TX 0xE1 // Define flush TX register command
#define FLUSH_RX 0xE2 // Define flush RX register command
#define REUSE_TX_PL 0xE3 // Define reuse TX payload register command
#define NOP 0xFF // Define No Operation, might be used to read status register

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top