本帖最后由 逗比的狼 于 2016-2-3 12:38 编辑
两个
单片机接两个NRF24L01,一发送一接受。代码如下:
#include "NRF24L01.H"
// PA3 --- CE, PA4 --- CSN, PA5 --- CLK, PA6 --- MISO, PA7 --- MOSI, PA8 --- IRQ
//CE,CSN,IQR操作函数
#define CE_L GPIO_ResetBits(GPIOA, GPIO_Pin_3)
#define CE_H GPIO_SetBits(GPIOA, GPIO_Pin_3)
#define CSN_L GPIO_ResetBits(GPIOA, GPIO_Pin_4)
#define CSN_H GPIO_SetBits(GPIOA, GPIO_Pin_4)
#define READ_IRQ GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8)
uint8_t RX_TX_ADDR[RX_TX_ADDR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //发送、接收地址
void NRF_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
// PA5 --- CLK, PA7 --- MOSI
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// PA6 --- MISO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOA
tiNG;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// PA3 --- CE, PA4 --- CSN
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// PA8 --- IRQ
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
CE_L;
CSN_H;
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_CRCPolynomial = 7;
SPI_Init(SPI1,&SPI_InitStructure);
SPI_Cmd(SPI1, ENABLE);
}
uint8_t SPI_ReadWriteByte(uint8_t byte)
{
uint8_t retry = 0;
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET)
{
if(retry++ > 200)
return 0;
}
retry = 0;
SPI_I2S_SendData(SPI1, byte);
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET)
{
if(retry++ > 200)
return 0;
}
return SPI_I2S_ReceiveData(SPI1);
}
uint8_t NRF_ReadReg(uint8_t reg)
{
uint8_t data;
CE_L;
CSN_L; //使能SPI传输
SPI_ReadWriteByte(reg); //发送寄存器地址
data = SPI_ReadWriteByte(0xFF); //读出寄存器数据
CSN_H; //失能SPI传输
return data;
}
uint8_t NRF_WriteReg(uint8_t reg, uint8_t data)
{
uint8_t status;
CE_L;
CSN_L; //使能SPI传输
status = SPI_ReadWriteByte(reg); //发送寄存器地址,并接收状态值
SPI_ReadWriteByte(data); //写入寄存器数据
CSN_H; //失能SPI传输
return status;
}
uint8_t NRF_ReadBuf(uint8_t reg, uint8_t *pBuf, uint8_t len)
{
uint8_t i, status;
CE_L;
CSN_L; //使能SPI传输
status = SPI_ReadWriteByte(reg); //发送寄存器地址,并接收状态值
for(i = 0; i < len; i++)
pBuf
= SPI_ReadWriteByte(0xFF);//读出缓冲区数据
CSN_H; //失能SPI传输
return status;
}
uint8_t NRF_WriteBuf(uint8_t reg, uint8_t *pBuf, uint8_t len)
{
uint8_t i, status;
CE_L;
CSN_L; //使能SPI传输
status = SPI_ReadWriteByte(reg); //发送寄存器地址,并接收状态值
for(i = 0; i < len; i++)
SPI_ReadWriteByte(pBuf); //写入缓冲区数据
CSN_H; //失能SPI传输
return status;
}
uint8_t NRF_Check(void)
{
uint8_t i, buf[5] = {0xA5, 0xA5, 0xA5, 0xA5, 0xA5};
NRF_WriteBuf(WR_REG+TX_ADDR,buf,5); //写入5个字节的地址.
NRF_ReadBuf(TX_ADDR,buf,5); //读出写入的地址
for(i = 0; i < 5; i++)
if(buf != 0xA5)
break;
if(i != 5)
return 0; //检测NRF错误
return 1; //检测到NRF
}
void NRF_RxMode(void)
{
CE_L;
NRF_WriteReg(WR_REG + SETUP_AW, 0x03); //设置发送地址宽度:5字节
NRF_WriteBuf(WR_REG + TX_ADDR, RX_TX_ADDR, RX_TX_ADDR_WIDTH); //写TX节点地址
NRF_WriteBuf(WR_REG + RX_ADDR_P0, RX_TX_ADDR, RX_TX_ADDR_WIDTH); //写RX节点地址
//NRF_WriteReg(WR_REG + EN_AA, 0x01); //使能接收通道0的自动应答
NRF_WriteReg(WR_REG + EN_AA, 0x00); //关闭接收通道0的自动应答
NRF_WriteReg(WR_REG + EN_RXADDR, 0x01); //使能接收通道0的接收地址
NRF_WriteReg(WR_REG + SETUP_RETR, 0x1A); //设置自动重发时间间隔:500+86us,最大自动重发次数:10次
NRF_WriteReg(WR_REG + RF_CH, 40); //设置RF通信频率
NRF_WriteReg(WR_REG + RF_SETUP, 0x0F); //设置TX发射参数,0dB增益,2Mbps,低噪声增益开启
NRF_WriteReg(WR_REG + RX_PW_P0, RX_TX_PLOAD_WIDTH); //设置通道0的有效数据宽度
NRF_WriteReg(WR_REG + NRF_CONFIG, 0x0F); //配置工作模式参数,PWR_UP,EN_CRC,16BIT_CRC,接受模式,中断全开
CE_H; //CE高,进入接收模式
Delay(1);
}
void NRF_TxMode(void)
{
CE_L;
NRF_WriteReg(WR_REG + SETUP_AW, 0x03); //设置发送地址宽度:5字节
NRF_WriteBuf(WR_REG + TX_ADDR, RX_TX_ADDR, RX_TX_ADDR_WIDTH); //写TX节点地址
NRF_WriteBuf(WR_REG + RX_ADDR_P0, RX_TX_ADDR, RX_TX_ADDR_WIDTH); //写RX节点地址
//关闭自动应答,自动重发,测试用
NRF_WriteReg(WR_REG + EN_AA, 0x00); //NRF_WriteReg(WR_REG + EN_AA, 0x01); //使能接收通道0的自动应答
NRF_WriteReg(WR_REG + EN_RXADDR, 0x00); //NRF_WriteReg(WR_REG + EN_RXADDR, 0x01); //使能接收通道0的接收地址
NRF_WriteReg(WR_REG + SETUP_RETR, 0x00);//NRF_WriteReg(WR_REG + SETUP_RETR, 0x1A); //设置自动重发时间间隔:500+86us,最大自动重发次数:10次
NRF_WriteReg(WR_REG + RF_CH, 40); //设置RF通信频率
NRF_WriteReg(WR_REG + RF_SETUP, 0x0F); //设置TX发射参数,0dB增益,2Mbps,低噪声增益开启
NRF_WriteReg(WR_REG + NRF_CONFIG, 0x0E); //配置工作模式参数,PWR_UP,EN_CRC,16BIT_CRC,发射模式,中断全开
CE_H; //CE高,进入发射模式
Delay(1);
}
uint8_t NRF_TestTx(uint8_t data)
{
uint8_t status = 0;
do
{
CE_L;
NRF_WriteReg(WR_TX_PLOAD, data);
CE_H;
Delay(1);
if(status++ > 250)
break;
}while(READ_IRQ != 0);
NRF_WriteReg(FLUSH_TX, NOP);
CE_L;
Delay(1);
status = NRF_ReadReg(RD_REG + STATUS);
NRF_WriteReg(WR_REG + STATUS, status);
return status;
}
uint8_t NRF_TestRx(void)
{
uint8_t data = 0;
while(READ_IRQ != 0)
{
if(data++ > 250)
break;
}
CE_L;
Delay(1);
data = NRF_ReadReg(RD_REG + STATUS);
NRF_WriteReg(WR_REG + STATUS, data);
return data;
}
发送端:
NRF_Init();
NRF_TxMode();
if(NRF_Check() == 0)
USART_SendString(USART1, "ERROR");
else
USART_SendString(USART1, "OK");
然后每隔100ms执行
GPIO_WriteBit(GPIOB, GPIO_Pin_0, ((BitAction)(1 - GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_0))));
USART_SendNum(USART1, (NRF_TestTx(0x01)), 0);
USART_SendString(USART1, "
");
串口接收到46即0x2E,说明数据发送出去了
接收端:
NRF_Init();
NRF_RxMode();
if(NRF_Check() == 0)
USART_SendString(USART1, "ERROR");
else
USART_SendString(USART1, "OK");
每隔100ms执行
GPIO_WriteBit(GPIOB, GPIO_Pin_0, ((BitAction)(1 - GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_0))));
USART_SendNum(USART1, (NRF_TestRx()), 0);
USART_SendString(USART1, "
");
串口只能接收到14即0x0E,接收一直不成功。
求大神帮忙看看是不是代码设置的有问题。
一周热门 更多>