current position:Home>The SPI protocol of stm32f030f4p6 and nRF24L01 module are used for communication to realize wireless data transmission and reception

The SPI protocol of stm32f030f4p6 and nRF24L01 module are used for communication to realize wireless data transmission and reception

2021-08-25 00:51:39 ECG heart

Single chip microcomputer is purely a personal hobby ,  There are many deficiencies. Please give us more advice ,  Please forgive me for some irregular names in the code .

This paper only realizes the simple design of wireless module ( Can send and receive one byte of data ),  Always wanted to diy A wireless remote control car ,  You need to use the wireless module ,  I've been looking for a long time and found NRF24L01( Hereinafter referred to as NRF) It is the cheapest wireless module ( Excepting WiFi And Bluetooth module ),  Just bought a few ,  because stm32f103 Prices ,  I chose the cheap one stm32f030,  I found a lot of information on the Internet for stm32f030 There is very little information about ,  He and stm32f103 The code is the same , Just try stm32f103 Modify it based on the code , Just can't communicate ,  Can only be sent successfully ,  Unable to receive data ,  Shelved for a long time, and finally chose a new piece  HC-12 Wireless communication module ,  This module is more expensive. Buy a set for the first time ( Send and receive two modules ) Cheaper ,  The farthest communication distance of open field of vision 1 km ( No real measurements have been made ),  He uses serial communication ,  After writing the code and burning it, you can communicate ,  Finally, success diy Wireless remote control car ,  utilize HC-12 I feel overqualified ,  Finally, I thought about this again when I had nothing to do NRF modular ,  Finally we can communicate with each other ,  I don't know what's wrong ,  The only difference is ,  The previous is to modify the information found on the Internet ,  No interrupt is used ,  Use only the while Cycle for detection , This time when I started writing again, I used interrupt ,  After debugging, you can communicate .

Some problems encountered :

1. On the schematic diagram PA4  yes SPI1 The movie selection of spi1_nss Reuse of ,  When configuring PA4 It is also configured as reuse mode ,  Find that you can't succeed ,  The need to configure the output mode solves the problem

2.NRF Of IRQ When the foot configuration is interrupted, it needs to be configured as a falling edge trigger

3.stm32 Boards and NRF When the module is connected, the data output and input lines cannot be cross connected (MCU  Of MISO  and  NRF Of MISO  Connected to a , MOSI Empathy )

Here's the code , Apply to stm32f030

1. spi To configure

#ifndef __bsp_spi_h
#define __bsp_spi_h

#include "stm32f0xx_gpio.h"

#define SPIx SPI1                            //SPI_1
#define SPI1_PORT GPIOA                //PA  port 
#define PORTA_LCK RCC_AHBPeriph_GPIOA    //GPIO  The clock 
#define SPI_LCK RCC_APB2Periph_SPI1//spi  The clock 
#define SPI1_CSN GPIO_Pin_1        //PA1    NSS
#define SPI1_SCK GPIO_Pin_5        //PA5    SCK
#define SPI1_MISO GPIO_Pin_6    //PA6    MISO
#define SPI1_MOSI GPIO_Pin_7    //PA7    MOSI

void SPI_Config(void);
u8 SPI_SendByte(u8 byte);
void Pin_CSN(u8 u);

#endif
bsp_spi.h
#include "bsp_spi.h"
#include "stm32f0xx_gpio.h"

// initialization 
void SPI_Config()
{
    GPIO_InitTypeDef GPIO_InitStruct;
    SPI_InitTypeDef SPI_InitStruct;
    
    // Port initialization 
    RCC_AHBPeriphClockCmd(PORTA_LCK , ENABLE);// Turn on GPIO The clock 
    RCC_APB2PeriphClockCmd(SPI_LCK, ENABLE);// Turn on SPI_1 The clock 
    
    // Reuse mode 
    GPIO_PinAFConfig(SPI1_PORT,GPIO_PinSource5,GPIO_AF_0);//SCK
    GPIO_PinAFConfig(SPI1_PORT,GPIO_PinSource6,GPIO_AF_0);//MISO
    GPIO_PinAFConfig(SPI1_PORT,GPIO_PinSource7,GPIO_AF_0);//MOSI
    
    GPIO_InitStruct.GPIO_Pin =  SPI1_SCK | SPI1_MISO | SPI1_MOSI;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_Init(SPI1_PORT, &GPIO_InitStruct);
    
    GPIO_InitStruct.GPIO_Pin = SPI1_CSN;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_Init(SPI1_PORT , &GPIO_InitStruct);
    
    //spi initialization 
    //SPI_I2S_DeInit(SPIx);    // Reset the register to the default value 
    //SPI_Cmd(SPIx, DISABLE);
    //SPI_Direction_2Lines_FullDuplex SPI_Direction_1Line_Rx SPI_Direction_1Line_Tx
    SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    //SPI_Mode_Master  host  SPI_Mode_Slave  Slave 
    SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
    SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
    SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;//SPI_CPOL_Low SPI_CPOL_High
    SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;//SPI_CPHA_1Edge SPI_CPHA_2Edge
    SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;
    SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
    //SPI_FirstBit_MSB SPI_FirstBit_LSB
    SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStruct.SPI_CRCPolynomial = 7;
    SPI_Init(SPIx, &SPI_InitStruct);
    //SPI_I2S_IT_TXE SPI_I2S_IT_RXNE SPI_I2S_IT_ERR
    SPI_I2S_ITConfig(SPIx, SPI_I2S_IT_TXE | SPI_I2S_IT_RXNE, ENABLE);// interrupt 
    SPI_RxFIFOThresholdConfig(SPI1, SPI_RxFIFOThreshold_QF);    // important , Set the response data bit to  8  position 
    SPI_Cmd(SPIx, ENABLE);// Can make 
}

//SPI  Send and receive a byte 
u8 SPI_SendByte(u8 byte)
{
    // Set time overflow 
    u32 SPITimeout = 0xffff;
    /*  Wait for the send buffer to be empty ,TXE  event  */
    while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET)
    {
        if ((SPITimeout--) == 0) return 0;
    }
    /*  Write data register , Write the data to be written to the send buffer  */
    SPI_SendData8(SPIx, byte);//SPI_I2S_SendData16
    // Set time overflow 
    SPITimeout = 0xfffff;
    /*  Waiting to receive buffer not empty ,RXNE  event  */
    while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) == RESET)
    {
        if ((SPITimeout--) == 0) return 0;
    }
    /*  Read data register , Get receive buffer data  */
    return SPI_ReceiveData8(SPIx);
}
// Set the chip selection high and low level 
void Pin_CSN(u8 u)
{
    if(u==0)
    {
        SPI1_PORT->BRR = SPI1_CSN;
    }
    else
    {
        SPI1_PORT->BSRR = SPI1_CSN;
    }
}
bsp_spi.c

2.nrf To configure

#ifndef __bsp_nrf0241_h
#define __bsp_nrf0241_h

#include "stm32f0xx_gpio.h"

#define NRF_PORT GPIOA                //PA  port 
#define KEY0 GPIO_Pin_0        //KEY0
#define LED0 GPIO_Pin_4        //LED0
#define NRF_CE GPIO_Pin_2        //PA2    CE
#define NRF_IRQ GPIO_Pin_3        //PA3    IRQ
#define NOP 0xFF //  Empty operation . It can be used to read   Status register 

// Set up ce Set high and pull low 
void Pin_CE(u8 u);
// obtain IRQ Interrupt level ,( Not used )
u8 Get_IRQ(void);
// Write data 
u8 SPI_WriteBuf(u8 reg, u8 *pBuf, u8 len);
// Reading data 
u8 SPI_ReadBuf(u8 reg, u8 *pBuf, u8 len);
// Read and write an instruction 
u8 SPI_RWReg(u8 reg, u8 value);
// To configure 
void NRF_Config(void);
// Get the level of the key ( Used to judge whether the key is pressed )
u8 Get_KEY0(void);
// Configure test keys and LED The lamp 
void KEY0_LED0_Config(void);
// Set up LED The lamp ( Low level on )
void Pin_LED0(u8 u);
// send data buff For data ,len Number of 
void send_data(u8 *buff,u8 len);
// testing NRF Whether the module exists   There is returned 0
u8 nrf24l0_check(void);
// Read status register ,  Used to judge whether the transmission is successful ,  Successful reception ,  The transmission reached the maximum value 
u8 Get_Status(void);
// receive data 
void receive_data(void);
// Get the received data  buf  Store the received data , len The number of data 
void Get_Data(u8 *buf,u8 len);
// Clear all ( send out ,  receive ,  Maximum number of transmissions ) The interrupt 
void ClearStatus(void);

#endif
bsp_nrf0241.h
#include "bsp_nrf0241.h"
#include "stm32f0xx_gpio.h"
#include "bsp_spi.h"
#include "delay.h"

void KEY0_LED0_Config()
{
    GPIO_InitTypeDef GPIO_InitStruct;
    NVIC_InitTypeDef NVIC_InitStructure;
    EXTI_InitTypeDef EXTI_InitStructure;
    
    RCC_AHBPeriphClockCmd(PORTA_LCK , ENABLE);
    // User tested keys and LED The lamp 
    GPIO_InitStruct.GPIO_Pin =  KEY0;// Key 
    GPIO_InitStruct.GPIO_PuPd  = GPIO_PuPd_UP;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_Init(NRF_PORT, &GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin = LED0;//LED The lamp 
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_Init(NRF_PORT , &GPIO_InitStruct);
    Pin_LED0(1);// Low level   Extinguish LED The lamp 
    // Add key interrupt 
    EXTI_InitStructure.EXTI_Line = KEY0;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    //EXTI_Trigger_Rising , EXTI_Trigger_Falling , EXTI_Trigger_Rising_Falling
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;// Rising edge trigger 
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);
    // interrupt 
    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority = 1;        // Sub priority 1
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;        //IRQ Channel enable 
    NVIC_Init(&NVIC_InitStructure);    // Initialize... According to the specified parameters VIC register 
}
u8 Get_KEY0(void)
{
    return GPIO_ReadInputDataBit(NRF_PORT, KEY0);
}
void Pin_LED0(u8 u)
{
    if(u==0)
    {
        NRF_PORT->BRR = LED0;
    }
    else
    {
        NRF_PORT->BSRR = LED0;
    }
}
// Address 
u8 TX_ADDRESS1[5]= {0x34,0x43,0x10,0x10,0x01}; // Local address 
u8 RX_ADDRESS1[5]= {0x34,0x43,0x10,0x10,0x01}; // Receiving address 
// To configure 
void NRF_Config()
{
    GPIO_InitTypeDef GPIO_InitStruct;
    NVIC_InitTypeDef NVIC_InitStructure;
    EXTI_InitTypeDef EXTI_InitStructure;
    
    // Port initialization 
    RCC_AHBPeriphClockCmd(PORTA_LCK , ENABLE);
    
    GPIO_InitStruct.GPIO_Pin =  NRF_CE;//CE  Output 
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_Init(NRF_PORT, &GPIO_InitStruct);
    
    GPIO_InitStruct.GPIO_Pin =  NRF_IRQ;//IRQ  Interrupt input 
    GPIO_InitStruct.GPIO_PuPd  = GPIO_PuPd_NOPULL;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_Init(NRF_PORT, &GPIO_InitStruct);
    
    // interrupt 
    EXTI_InitStructure.EXTI_Line = NRF_IRQ;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    //EXTI_Trigger_Rising , EXTI_Trigger_Falling , EXTI_Trigger_Rising_Falling
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;// Falling edge trigger 
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);
    // interrupt 
    NVIC_InitStructure.NVIC_IRQChannel = EXTI2_3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority = 1;        // Sub priority 1
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;        //IRQ Channel enable 
    NVIC_Init(&NVIC_InitStructure);    // Initialize... According to the specified parameters VIC register 
    
    // To configure RNF
    Pin_CSN(1);
    Pin_CE(0);
    //0x02  launch , 0x03  receive - crc Do not enable  crc Pattern :8 Bit validity 
    //0x0e  launch , 0x0f  receive - crc Can make  crc Pattern :16 Bit validity 
    SPI_RWReg(0x20+0x00,0x02);//0x02  launch , 0x03  receive 
    SPI_RWReg(0x20+0x01,0x00);// Auto answer   If channel 0 The reply :0x01  Auto answer is prohibited :0x00
    SPI_RWReg(0x20+0x02,0x01);// The receiving address allows   passageway 0 allow 
    SPI_RWReg(0x20+0x03,0x03);// Set the address width  5 Address width 
    SPI_RWReg(0x20+0x04,0x00);// Establish automatic retransmission   Prohibit automatic retransmission 
    SPI_RWReg(0x20+0x05,40);// RF channels 
    SPI_RWReg(0x20+0x06,0x07);// RF register 
    SPI_RWReg(0x20+0x07,0x70);// Status register 
    SPI_WriteBuf(0x20+0x0A,RX_ADDRESS1,5);// passageway 0 Receiving address 
    SPI_WriteBuf(0x20+0x10,TX_ADDRESS1,5);// Sending address 
    SPI_RWReg(0x20+0x11,32);// Receive data channel 0 Effective data width  1-32  byte 
}
// send out 
void TX_MODE()
{
    // To configure RNF
    Pin_CSN(1);
    Pin_CE(0);
    //0x02  launch , 0x03  receive - crc Do not enable  crc Pattern :8 Bit validity 
    //0x0e  launch , 0x0f  receive - crc Can make  crc Pattern :16 Bit validity 
    SPI_RWReg(0x20+0x00,0x02);
    SPI_RWReg(0x20+0x01,0x00);// Auto answer   If channel 0 The reply :0x01  Auto answer is prohibited :0x00
    SPI_RWReg(0x20+0x02,0x01);// The receiving address allows   passageway 0 allow 
    SPI_RWReg(0x20+0x03,0x03);// Set the address width  5 Address width 
    SPI_RWReg(0x20+0x04,0x00);// Establish automatic retransmission   Prohibit automatic retransmission 
    SPI_RWReg(0x20+0x05,40);// RF channels 
    SPI_RWReg(0x20+0x06,0x07);// RF register 
    SPI_RWReg(0x20+0x07,0x70);// Status register 
    SPI_WriteBuf(0x20+0x0A,RX_ADDRESS1,5);// passageway 0 Receiving address 
    SPI_WriteBuf(0x20+0x10,TX_ADDRESS1,5);// Sending address 
    SPI_RWReg(0x20+0x11,32);// Receive data channel 0 Effective data width  1-32  byte 
}
// receive 
void RX_MODE()
{
    // To configure RNF
    Pin_CSN(1);
    Pin_CE(0);
    //0x02  launch , 0x03  receive - crc Do not enable  crc Pattern :8 Bit validity 
    //0x0e  launch , 0x0f  receive - crc Can make  crc Pattern :16 Bit validity 
    SPI_RWReg(0x20+0x00,0x03);//0x02  launch , 0x03  receive 
    SPI_RWReg(0x20+0x01,0x00);// Auto answer ,  If channel 0 The reply :0x01  Auto answer is prohibited :0x00
    SPI_RWReg(0x20+0x02,0x01);// The receiving address allows   passageway 0 allow 
    SPI_RWReg(0x20+0x03,0x03);// Set the address width  5 Address width 
    SPI_RWReg(0x20+0x04,0x00);// Establish automatic retransmission   Prohibit automatic retransmission 
    SPI_RWReg(0x20+0x05,40);// RF channels 
    SPI_RWReg(0x20+0x06,0x07);// RF register 
    SPI_RWReg(0x20+0x07,0x70);// Status register 
    SPI_WriteBuf(0x20+0x0A,RX_ADDRESS1,5);// passageway 0 Receiving address 
    SPI_WriteBuf(0x20+0x10,TX_ADDRESS1,5);// Sending address 
    SPI_RWReg(0x20+0x11,32);// Receive data channel 0 Effective data width  1-32  byte 
    Pin_CE(1);
    delay_us(120);
}

// send data 
void send_data(u8 *buff,u8 len)
{
    TX_MODE();
    SPI_RWReg(0xE1,0xFF);// Clear the transmit register 
    SPI_WriteBuf(0xA0,buff,len);// Write to send register 
    Pin_CE(1);
    delay_us(20);
    Pin_CE(0);
}
// receive data 
void receive_data()
{
    RX_MODE();
    SPI_RWReg(0xE2,0xFF);// Clear the receive register 
    Pin_CE(1);
    delay_us(120);
}
// get data 
void Get_Data(u8 *buf,u8 len)
{
    SPI_ReadBuf(0x61,buf,len);
}
// Clear interrupt 
void ClearStatus()
{
    Pin_CE(0);
    SPI_RWReg(0x20+0x07,0x70);
    Pin_CE(1);
    delay_us(20);
}
void Pin_CE(u8 u)
{
    if(u==0)
    {
        NRF_PORT->BRR = NRF_CE;
    }
    else
    {
        NRF_PORT->BSRR = NRF_CE;
    }
}
u8 Get_IRQ(void)
{
    return GPIO_ReadInputDataBit(NRF_PORT, NRF_IRQ);
}

// For writing data : For register address ,pBuf: Is the address of the data to be written ,uchars: Number of data written 
u8 SPI_WriteBuf(u8 reg, u8 *pBuf, u8 len) 
{
    u8 s,ctr;
    Pin_CSN(0);
    delay_us(100);
    s=SPI_SendByte(reg);
    
    for(ctr=0; ctr<len; ctr++)
        SPI_SendByte(*pBuf++);
    Pin_CSN(1);
    delay_us(100);
    return s;
}
// function :  For reading data ,reg: For register address ,pBuf: Is the address of the data to be read ,uchars: Number of read data 
u8 SPI_ReadBuf(u8 reg, u8 *pBuf, u8 len) 
{
    u8 s,ctr;
    Pin_CSN(0);
    delay_us(100);
    s=SPI_SendByte(reg);
    
    for(ctr=0; ctr<len; ctr++)
        pBuf[ctr]=SPI_SendByte(NOP);
    Pin_CSN(1);
    delay_us(100);
    return s;
}
// function :NRF24L01  Read / write register function 
u8 SPI_RWReg(u8 reg, u8 value) 
{
    u8 status = 0x00;
    Pin_CSN(0);
    delay_us(100);
    status = SPI_SendByte(reg); // Send register address ,
    SPI_SendByte(value);// Send register value 
    delay_us(100);
    Pin_CSN(1);
    return (status);
}
// function :NRF24L01  Read / write register function 
u8 Get_Status() 
{
    return SPI_RWReg(0x07,0xFF);
}
// Detect the presence of 
u8 nrf24l0_check(void)
{
    u8 buf[5]={0XA5,0XA5,0XA5,0XA5,0XA5};
    u8 i;
    SPI_WriteBuf(0x20+0x10,buf,5);
    SPI_ReadBuf(0x10,buf,5);
    for(i=0; i<5; i++)if(buf[i]!=0xA5)break;
    if(i!=5)return 1;
    return 0;
}
bsp_nrf0241.c

3.stm32f0xx_it.c Function in interrupt

#include "delay.h"
#include "stm32f0xx.h"
#include "bsp_nrf0241.h"
// Key interrupt 
void EXTI0_1_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line0)!= RESET)
    {
        delay_ms(20);
        if(Get_KEY0()!= RESET)// Eliminate key jitter 
        {
            u8 tx_buf[32]={0x11};// User test data 
            send_data(tx_buf,32);// send out 
        }
        EXTI_ClearITPendingBit(EXTI_Line0);// Clear interrupt flag 
    }
}
//nrf2401 Send receive interrupt 
void EXTI2_3_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line3)!= RESET)
    {
        u8 gstatus = Get_Status();// To obtain state 
        // send out 
        if((gstatus & 0x20) != 0)
        {
            // Send successfully  LED The light flashes once 
            Pin_LED0(0);
            delay_ms(1000);
            Pin_LED0(1);
        }
        // Maximum number of times to send 
        if((gstatus & 0x10) != 0)
        {
            // Maximum number of times to send 
            Pin_LED0(0);
            delay_ms(1000);
            Pin_LED0(1);
        }
        // receive 
        if((gstatus & 0x40) != 0)
        {
            // Data received 
            u8 tx_bufr[32];
            Get_Data(tx_bufr,32);
            if(tx_bufr[0] == 0x11)// Compare with the sent data 
            {
                Pin_LED0(0);
                delay_ms(1000);
                Pin_LED0(1);
            }
        }
        // Clear interrupt flag 
        EXTI_ClearITPendingBit(EXTI_Line3);
    }
    ClearStatus();// Clear interrupt 
    receive_data();// Continue to receive 
}
stm32f0xx_it.c

4.delay.h  The time delay function ( From the Internet )

#include "stm32f0xx.h"
#include "delay.h"

static u8  fac_us=0;//us Delay multiplier 
static u16 fac_ms=0;//ms Delay multiplier 
// Initialization delay function 
//SYSTICK The clock is fixed to HCLK Of the clock 1/8
//SYSCLK: The system clock 
void delay_init(u8 SYSCLK)
{
    SysTick->CTRL&=0xfffffffb;//bit2 Empty , Select the external clock   HCLK/8
    fac_us=SYSCLK/8;            
    fac_ms=(u16)fac_us*1000;
}                                    
// Time delay nms
// Be careful nms The scope of the 
//SysTick->LOAD by 24 Bit register , therefore , The maximum delay is :
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLK Unit is Hz,nms Unit is ms
// Yes 72M Under the condition of ,nms<=1864 
void delay_ms(u16 nms)
{                     
    u32 temp;           
    SysTick->LOAD=(u32)nms*fac_ms;// Time loading (SysTick->LOAD by 24bit)
    SysTick->VAL =0x00;           // Clear the counter 
    SysTick->CTRL=0x01 ;          // Start counting down   
    do
    {
        temp=SysTick->CTRL;
    }
    while(temp&0x01&&!(temp&(1<<16)));// Wait for time to arrive    
    SysTick->CTRL=0x00;       // Turn off the counter 
    SysTick->VAL =0X00;       // Clear the counter               
}   
// Time delay nus
//nus To delay us Count .                                               
void delay_us(u32 nus)
{        
    u32 temp;             
    SysTick->LOAD=nus*fac_us;     
    SysTick->VAL=0x00;
    SysTick->CTRL=0x01 ;
    do
    {
        temp=SysTick->CTRL;
    }
    while(temp&0x01&&!(temp&(1<<16)));
    SysTick->CTRL=0x00;
    SysTick->VAL =0X00; 
}
delay.h

5.main.c  Entry test function

#include "stm32f0xx.h"
#include "delay.h"
#include "bsp_spi.h"
#include "bsp_nrf0241.h"

void daly(uint32_t a)
{
    for(;a>0;a--);
}

int main(void)
{
    // Initialization delay function  stm32f030 by 48
    delay_init(48);
    /*
    *KEY0_LED0_Config(); Configure a key and a LED The lamp 
    * PA0  Key 
    * PA4 LED The lamp ( Users of the system LED The lamp   Low level on )
    *
    *SPI_Config(); To configure SPI
    * PA1 NSS  Chip selection 
    * PA5 SCK  The clock 
    * PA6 MISO  Host input and slave output 
    * PA7 MOSI  Host output slave input 
    *
    *NRF_Config(); To configure NRF24L01
    * PA2 CE  Control transceiver 
    * PA3 IRQ  Send receive interrupt 
    */
    KEY0_LED0_Config();
    SPI_Config();
    NRF_Config();
    delay_us(20);
    if(nrf24l0_check()==0)
    {
        // There is nrf2401 modular 
        Pin_LED0(0);
        delay_ms(1000);
        Pin_LED0(1);
        
        receive_data();// receive 
    }
    while(1){ }
}
main.c

 

Prepare two pieces for sending and receiving stm32f030 SCM and NRF Wireless module   Connect with DuPont wire ( Be careful MISO  and  MOSI To correspond to the connection , Do not cross connect ),  It is also necessary to lead to... For testing key0 Button , LED It is the default of the board PA4,  After connecting, insert a burner into the two boards to burn the compiled code ,  You can press KEY0 Tested ,  If another MCU LED The light on indicates success .

If you have insufficient places and experience, please exchange in the comment area .

copyright notice
author[ECG heart],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2021/08/20210825005134300P.html

Random recommended