初始化24l01大致步骤
要控制模块需要使用“SPI”接口
C8T6有两个SPI,根据情况来选择对应的端口
NSS引脚可以不用.
初始化SPI
void SPI2_INIT(void)
{
GPIO_InitTypeDef gpio_init;
SPI_InitTypeDef spi_init;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //使能引脚
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE); //使能spi
gpio_init.GPIO_Mode=GPIO_Mode_AF_PP; //复用推挽输出
gpio_init.GPIO_Pin=GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15; //选择对应的引脚
gpio_init.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &gpio_init);
spi_init.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_256;
spi_init.SPI_CPHA= SPI_CPHA_2Edge; //时钟第二个跳变沿 数据被采集
spi_init.SPI_CPOL=SPI_CPOL_High; //SCK空闲为高电平
spi_init.SPI_CRCPolynomial= 7; //CRC值为什么是7??
spi_init.SPI_DataSize= SPI_DataSize_8b; //数据大小是8位结构
spi_init.SPI_Direction=SPI_Direction_2Lines_FullDuplex; //spi双线全双工
spi_init.SPI_FirstBit= SPI_FirstBit_MSB; //从MSB高位开始传输
spi_init.SPI_Mode= SPI_Mode_Master; //spi设为主模式
spi_init.SPI_NSS=SPI_NSS_Soft; //硬件控制?
SPI_Init(SPI2,&spi_init);
SPI_Cmd(SPI2, ENABLE); //使能外设
SPI2_READ_WRITE_BYTE(0xff); //发一个ff数据
}
//设置波特率
void SPI2_SET_SPEED(u8 SPI_BaudRatePrescaler)
{
SPI2->CR1&=0XFFC7; //3-5位清0 设置波特率
SPI2->CR1|=SPI_BaudRatePrescaler;
SPI_Cmd(SPI2,ENABLE);
}
u8 SPI2_READ_WRITE_BYTE(u8 txdata)
{
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);//等待发送区空
SPI_I2S_SendData(SPI2, txdata); //通过spi发送一个byte
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET); //等待接收一个byte
return SPI_I2S_ReceiveData(SPI2); //返回spi收到的数据
}
void nrf24l01_init(void)
{
GPIO_InitTypeDef gpio_init;
SPI_InitTypeDef spi_init;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
gpio_init.GPIO_Mode=GPIO_Mode_Out_PP; //普通io口设置
gpio_init.GPIO_Speed=GPIO_Speed_50MHz;
gpio_init.GPIO_Pin=GPIO_Pin_12|GPIO_Pin_15;
GPIO_Init(GPIOA,&gpio_init);
//PA15和PA12是CE 和CSN
gpio_init.GPIO_Mode=GPIO_Mode_IPU ;
gpio_init.GPIO_Pin=GPIO_Pin_8;
GPIO_Init(GPIOA, &gpio_init);
//IRQ引脚
SPI2_INIT();
//重设spi
SPI_Cmd(SPI2, DISABLE);
//根据协议重新设置spi
spi_init.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_16; //
spi_init.SPI_CPHA=SPI_CPHA_1Edge;
spi_init.SPI_CPOL=SPI_CPOL_Low; //空闲为低电平
spi_init.SPI_CRCPolynomial=7;
spi_init.SPI_DataSize=SPI_DataSize_8b;
spi_init.SPI_Direction=SPI_Direction_2Lines_FullDuplex;
spi_init.SPI_FirstBit=SPI_FirstBit_MSB;
spi_init.SPI_Mode=SPI_Mode_Master;
spi_init.SPI_NSS=SPI_NSS_Soft;
SPI_Init(SPI2,&spi_init);
SPI_Cmd(SPI2,ENABLE);
NRF24L01_CE=0;
NRF24L01_CSN=1;
}
到这里spi设置完成,基本可以跟24l01通信
读写24l01函数
u8 nrf24l01_write_reg(u8 reg, u8 value)
{
u8 status;
NRF24L01_CSN=0;
status=SPI2_READ_WRITE_BYTE(reg); //发送寄存器地址,
SPI2_READ_WRITE_BYTE(value);//发送寄存器值
NRF24L01_CSN=1;
return(status);
}
u8 nrf24l01_read_reg(u8 reg)
{
u8 reg_val;
NRF24L01_CSN=0;
SPI2_READ_WRITE_BYTE(reg);
reg_val=SPI2_READ_WRITE_BYTE(0XFF);
NRF24L01_CSN=1;
return(reg_val);
}
检测24l01是否存在
返回为1则失败,0 成功
u8 nrf24l01_check(void)
{
u8 buf[5]={0XA5,0XA5,0XA5,0XA5,0XA5};
u8 i;
SPI2_SET_SPEED(SPI_BaudRatePrescaler_4);
nrf24l01_write_buf(NRF_WRITE_REG+TX_ADDR,buf,5);
nrf24l01_read_buf(TX_ADDR,buf,5);
for(i=0; i<5; i++)if(buf[i]!=0xA5)break;
if(i!=5)return 1;
return 0;
}
读写指定长度的字符串
u8 nrf24l01_read_buf(u8 reg, u8 *pbuf, u8 len)
{
u8 s,ctr;
NRF24L01_CSN=0;
s=SPI2_READ_WRITE_BYTE(reg);
for(ctr=0; ctr<len; ctr++)pbuf[ctr]=SPI2_READ_WRITE_BYTE(0XFF);
NRF24L01_CSN=1;
return s;
}
u8 nrf24l01_write_buf(u8 reg, u8 *pbuf, u8 len)
{
u8 s,ctr;
NRF24L01_CSN=0;
s=SPI2_READ_WRITE_BYTE(reg);
for(ctr=0; ctr<len; ctr++) SPI2_READ_WRITE_BYTE(*pbuf++);//接收指定数量数据
NRF24L01_CSN=1;
return s;
}
发送一个指定字符串
接收成功返回0,否则返回寄存器值
u8 nrf24l01_txpacket(u8 *txbuf)
{
u8 sta;
SPI2_SET_SPEED(SPI_BaudRatePrescaler_4);
NRF24L01_CSN=0;
nrf24l01_write_buf(WR_TX_PLOAD, txbuf, tx_pload_width);
NRF24L01_CSN=1;
while(NRF24L01_IRQ!=0);
sta=nrf24l01_read_reg(STATUS);
nrf24l01_write_reg(NRF_WRITE_REG+STATUS,sta);
return sta;
}
u8 nrf24l01_rxpacket(u8 *rxbuf)
{
RX_DR=0x40;
TX_DS=0x20;
MAX_RT=0x10; //最大发送值
TX_FIFO_MAX=0x01;
SPI2_SET_SPEED(SPI_BaudRatePrescaler_8);
rx_status=nrf24l01_read_reg(STATUS); //发送状态字,得到寄存器状态
nrf24l01_write_reg(NRF_WRITE_REG+STATUS,rx_status); //清除寄存器值
if(rx_status&RX_DR)
{
nrf24l01_read_buf(RD_RX_PLOAD,rxbuf, rx_pload_width); //把数据放入字符串地址里
nrf24l01_write_reg(FLUSH_RX,0xff); //清除状态寄存器
return rx_status;
}
return rx_status;
}
24l01有两个模式,需要根据状态切换
切换发送接收模式
u8 nrf24l01_mod(u8 m)
{
if(m==1)
{
nrf24l01_tx_mode();
}
else
{
nrf24l01_rx_mode();
}
return m;
}
至此,基本设置完成,
//直接发送一个字符串
void tx_24l01(u8 *tx_buf)
{
nrf24l01_mod(1);//设置模块为发送模式
s=0;
RX_DR=0x40;
TX_DS=0x20; //
MAX_RT=0x10;
TX_FIFO_MAX=0x01;
s=nrf24l01_txpacket(tx_buf); //调用函数发送
while(1)
{
if(s&TX_DS)
{
printf("发送成功");
nrf24l01_mod(0);//发送成功后要设为接收模式
break;
}
else if(s&MAX_RT)//判断发送次数,超出最大值
{
printf("最大值");
nrf24l01_mod(0);//
break;
}
else //以上皆不是则返回错误
{
printf(" erro");
break;
}
}
}
接收数据
24l01主要关注2个寄存器,
设置寄存器
状态寄存器每次通信必读取的寄存器
h文件需要设置的内容