STM32
直播中

shawon

12年用户 622经验值
私信 关注
[问答]

如何利用STM32F103C8T6对NRF24L01芯片进行初始化呢

如何利用STM32F103C8T6对NRF24L01芯片进行初始化呢?有哪些步骤?

回帖(1)

杨玲

2021-12-16 14:25:49
初始化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!=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        
        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        
        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文件需要设置的内容






举报

更多回帖

×
20
完善资料,
赚取积分