使用STM32F030F4P6的SPI協議和NRF24L01模塊進行通訊 實現無線數據的收發


單片機這塊純屬個人業余愛好, 有很多不足的地方還請大家多多指教, 代碼中有些命名不規范的地方還請大家多多包涵.

本文只實現無線模塊的簡單的點亮(能收發一個字節數據), 一直想diy一個無線遙控的小車, 就要使用到無線模塊, 找了好久發現NRF24L01(下面簡稱NRF)是最便宜的一款無線模塊(除過WiFi和藍牙模塊), 就買了幾個, 由於stm32f103漲價, 就選擇了便宜的stm32f030, 網上找了很多資料對於stm32f030的資料很少, 他和stm32f103代碼大同小異, 就試着在stm32f103代碼的基礎上修改一下, 就是不能通訊, 只能發送成功, 不能接收到數據, 擱置了好久最后從新選擇了一塊 HC-12 的無線通訊模塊, 這個模塊比較貴首次購買一套(收發兩個模塊)比較便宜, 空曠視野最遠通訊距離1公里(沒有實測量過), 他使用的是串口通訊, 寫好代碼燒錄進去后可以通訊, 最后成功diy了無線遙控小車, 利用HC-12感覺大材小用了, 最后閑來無事就又琢磨一下這個NRF模塊, 終於可以相互通訊了, 也不知道哪里出問題了, 唯一不同的是, 之前的是在網上找的資料上修修改改, 沒有使用中斷, 只使用了while循環進行檢測, 這次重頭開始編寫的時候使用了中斷, 在調試了一下就可以通訊.

遇到的一些問題:

1.原理圖上PA4 是SPI1的片選spi1_nss的復用, 配置的時候把PA4也配置成了復用模式, 發現不能成功, 需要配置成輸出模式解決了問題

2.NRF的IRQ腳配置中斷的時候需要配置為下降沿觸發

3.stm32板子和NRF模塊進行連接的時候數據輸出和輸入線不能交叉連接(MCU 的MISO 和 NRF的 MISO 相連, MOSI同理)

以下是代碼 , 適用於stm32f030

1. spi配置

#ifndef __bsp_spi_h
#define __bsp_spi_h

#include "stm32f0xx_gpio.h"

#define SPIx SPI1                            //SPI_1
#define SPI1_PORT GPIOA                //PA 端口
#define PORTA_LCK RCC_AHBPeriph_GPIOA    //GPIO 時鍾
#define SPI_LCK RCC_APB2Periph_SPI1//spi 時鍾
#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"

//初始化
void SPI_Config()
{
    GPIO_InitTypeDef GPIO_InitStruct;
    SPI_InitTypeDef SPI_InitStruct;
    
    //端口初始化
    RCC_AHBPeriphClockCmd(PORTA_LCK , ENABLE);//開啟GPIO時鍾
    RCC_APB2PeriphClockCmd(SPI_LCK, ENABLE);//開啟SPI_1時鍾
    
    //復用模式
    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初始化
    //SPI_I2S_DeInit(SPIx);    //將寄存器重設為缺省值
    //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 主機 SPI_Mode_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);//中斷
    SPI_RxFIFOThresholdConfig(SPI1, SPI_RxFIFOThreshold_QF);    //重要,把應答數據位設置為 8 位
    SPI_Cmd(SPIx, ENABLE);//使能
}

//SPI 收發一個字節
u8 SPI_SendByte(u8 byte)
{
    //設置時間溢出
    u32 SPITimeout = 0xffff;
    /* 等待發送緩沖區為空,TXE 事件 */
    while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET)
    {
        if ((SPITimeout--) == 0) return 0;
    }
    /* 寫入數據寄存器,把要寫入的數據寫入發送緩沖區 */
    SPI_SendData8(SPIx, byte);//SPI_I2S_SendData16
    //設置時間溢出
    SPITimeout = 0xfffff;
    /* 等待接收緩沖區非空,RXNE 事件 */
    while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) == RESET)
    {
        if ((SPITimeout--) == 0) return 0;
    }
    /* 讀取數據寄存器,獲取接收緩沖區數據 */
    return SPI_ReceiveData8(SPIx);
}
//設置片選高低電平
void Pin_CSN(u8 u)
{
    if(u==0)
    {
        SPI1_PORT->BRR = SPI1_CSN;
    }
    else
    {
        SPI1_PORT->BSRR = SPI1_CSN;
    }
}
bsp_spi.c

2.nrf配置

#ifndef __bsp_nrf0241_h
#define __bsp_nrf0241_h

#include "stm32f0xx_gpio.h"

#define NRF_PORT GPIOA                //PA 端口
#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 // 空操作。可以用來讀 狀態寄存器

//設置ce置高和拉低
void Pin_CE(u8 u);
//獲取IRQ中斷的電平,(沒有用到)
u8 Get_IRQ(void);
//寫入數據
u8 SPI_WriteBuf(u8 reg, u8 *pBuf, u8 len);
//讀取數據
u8 SPI_ReadBuf(u8 reg, u8 *pBuf, u8 len);
//讀寫一條指令
u8 SPI_RWReg(u8 reg, u8 value);
//配置
void NRF_Config(void);
//獲取按鍵的電平(用於判斷按鍵是否按下)
u8 Get_KEY0(void);
//配置測試按鍵和LED燈
void KEY0_LED0_Config(void);
//設置LED燈(低電平點亮)
void Pin_LED0(u8 u);
//發送數據buff為數據,len為個數
void send_data(u8 *buff,u8 len);
//檢測NRF模塊是否存在 存在返回0
u8 nrf24l0_check(void);
//讀取狀態寄存器, 用於判斷發送成功, 接收成功, 發送達到最大值
u8 Get_Status(void);
//接收數據
void receive_data(void);
//獲取接收到的數據 buf 存放接收的數據, len數據個數
void Get_Data(u8 *buf,u8 len);
//清除所有(發送, 接收, 最大發送次數)的中斷
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);
    //用戶測試的按鍵和LED燈
    GPIO_InitStruct.GPIO_Pin =  KEY0;//按鍵
    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燈
    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);//低電平 熄滅LED燈
    //添加按鍵中斷
    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;//上升沿觸發
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);
    //中斷
    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority = 1;        //子優先級1
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;        //IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);    //根據指定的參數初始化VIC寄存器
}
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;
    }
}
//地址
u8 TX_ADDRESS1[5]= {0x34,0x43,0x10,0x10,0x01}; //本地地址
u8 RX_ADDRESS1[5]= {0x34,0x43,0x10,0x10,0x01}; //接收地址
//配置
void NRF_Config()
{
    GPIO_InitTypeDef GPIO_InitStruct;
    NVIC_InitTypeDef NVIC_InitStructure;
    EXTI_InitTypeDef EXTI_InitStructure;
    
    //端口初始化
    RCC_AHBPeriphClockCmd(PORTA_LCK , ENABLE);
    
    GPIO_InitStruct.GPIO_Pin =  NRF_CE;//CE 輸出
    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 中斷輸入
    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);
    
    //中斷
    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;//下降沿觸發
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);
    //中斷
    NVIC_InitStructure.NVIC_IRQChannel = EXTI2_3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority = 1;        //子優先級1
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;        //IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);    //根據指定的參數初始化VIC寄存器
    
    //配置RNF
    Pin_CSN(1);
    Pin_CE(0);
    //0x02 發射, 0x03 接收- crc不使能 crc模式:8位效驗
    //0x0e 發射, 0x0f 接收- crc使能 crc模式:16位效驗
    SPI_RWReg(0x20+0x00,0x02);//0x02 發射, 0x03 接收
    SPI_RWReg(0x20+0x01,0x00);//自動應答 若通道0應答:0x01 禁止自動應答:0x00
    SPI_RWReg(0x20+0x02,0x01);//接收地址允許 通道0允許
    SPI_RWReg(0x20+0x03,0x03);//設置地址寬度 5個地址寬度
    SPI_RWReg(0x20+0x04,0x00);//建立自動重發 禁止自動重發
    SPI_RWReg(0x20+0x05,40);//射頻通道
    SPI_RWReg(0x20+0x06,0x07);//射頻寄存器
    SPI_RWReg(0x20+0x07,0x70);//狀態寄存器
    SPI_WriteBuf(0x20+0x0A,RX_ADDRESS1,5);//通道0接收地址
    SPI_WriteBuf(0x20+0x10,TX_ADDRESS1,5);//發送地址
    SPI_RWReg(0x20+0x11,32);//接收數據通道0有效數據寬度 1-32 字節
}
//發送
void TX_MODE()
{
    //配置RNF
    Pin_CSN(1);
    Pin_CE(0);
    //0x02 發射, 0x03 接收- crc不使能 crc模式:8位效驗
    //0x0e 發射, 0x0f 接收- crc使能 crc模式:16位效驗
    SPI_RWReg(0x20+0x00,0x02);
    SPI_RWReg(0x20+0x01,0x00);//自動應答 若通道0應答:0x01 禁止自動應答:0x00
    SPI_RWReg(0x20+0x02,0x01);//接收地址允許 通道0允許
    SPI_RWReg(0x20+0x03,0x03);//設置地址寬度 5個地址寬度
    SPI_RWReg(0x20+0x04,0x00);//建立自動重發 禁止自動重發
    SPI_RWReg(0x20+0x05,40);//射頻通道
    SPI_RWReg(0x20+0x06,0x07);//射頻寄存器
    SPI_RWReg(0x20+0x07,0x70);//狀態寄存器
    SPI_WriteBuf(0x20+0x0A,RX_ADDRESS1,5);//通道0接收地址
    SPI_WriteBuf(0x20+0x10,TX_ADDRESS1,5);//發送地址
    SPI_RWReg(0x20+0x11,32);//接收數據通道0有效數據寬度 1-32 字節
}
//接收
void RX_MODE()
{
    //配置RNF
    Pin_CSN(1);
    Pin_CE(0);
    //0x02 發射, 0x03 接收- crc不使能 crc模式:8位效驗
    //0x0e 發射, 0x0f 接收- crc使能 crc模式:16位效驗
    SPI_RWReg(0x20+0x00,0x03);//0x02 發射, 0x03 接收
    SPI_RWReg(0x20+0x01,0x00);//自動應答, 若通道0應答:0x01 禁止自動應答:0x00
    SPI_RWReg(0x20+0x02,0x01);//接收地址允許 通道0允許
    SPI_RWReg(0x20+0x03,0x03);//設置地址寬度 5個地址寬度
    SPI_RWReg(0x20+0x04,0x00);//建立自動重發 禁止自動重發
    SPI_RWReg(0x20+0x05,40);//射頻通道
    SPI_RWReg(0x20+0x06,0x07);//射頻寄存器
    SPI_RWReg(0x20+0x07,0x70);//狀態寄存器
    SPI_WriteBuf(0x20+0x0A,RX_ADDRESS1,5);//通道0接收地址
    SPI_WriteBuf(0x20+0x10,TX_ADDRESS1,5);//發送地址
    SPI_RWReg(0x20+0x11,32);//接收數據通道0有效數據寬度 1-32 字節
    Pin_CE(1);
    delay_us(120);
}

//發送數據
void send_data(u8 *buff,u8 len)
{
    TX_MODE();
    SPI_RWReg(0xE1,0xFF);//清除發送寄存器
    SPI_WriteBuf(0xA0,buff,len);//寫入發送寄存器
    Pin_CE(1);
    delay_us(20);
    Pin_CE(0);
}
//接收數據
void receive_data()
{
    RX_MODE();
    SPI_RWReg(0xE2,0xFF);//清除接收寄存器
    Pin_CE(1);
    delay_us(120);
}
//獲取數據
void Get_Data(u8 *buf,u8 len)
{
    SPI_ReadBuf(0x61,buf,len);
}
//清除中斷
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);
}

//用於寫數據:為寄存器地址,pBuf:為待寫入數據地址,uchars:寫入數據的個數
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;
}
//功能: 用於讀數據,reg:為寄存器地址,pBuf:為待讀出數據地址,uchars:讀出數據的個數
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;
}
//功能:NRF24L01 讀寫寄存器函數
u8 SPI_RWReg(u8 reg, u8 value) 
{
    u8 status = 0x00;
    Pin_CSN(0);
    delay_us(100);
    status = SPI_SendByte(reg); //發送寄存器地址,
    SPI_SendByte(value);//發送寄存器值
    delay_us(100);
    Pin_CSN(1);
    return (status);
}
//功能:NRF24L01 讀寫寄存器函數
u8 Get_Status() 
{
    return SPI_RWReg(0x07,0xFF);
}
//檢測是否存在
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 中斷內的函數

#include "delay.h"
#include "stm32f0xx.h"
#include "bsp_nrf0241.h"
//按鍵中斷
void EXTI0_1_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line0)!= RESET)
    {
        delay_ms(20);
        if(Get_KEY0()!= RESET)//消除按鍵抖動
        {
            u8 tx_buf[32]={0x11};//用戶測試的數據
            send_data(tx_buf,32);//發送
        }
        EXTI_ClearITPendingBit(EXTI_Line0);//清除中斷標志
    }
}
//nrf2401收發中斷
void EXTI2_3_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line3)!= RESET)
    {
        u8 gstatus = Get_Status();//獲取狀態
        //發送
        if((gstatus & 0x20) != 0)
        {
            //發送成功 LED燈閃爍一次
            Pin_LED0(0);
            delay_ms(1000);
            Pin_LED0(1);
        }
        //發送達到最大次數
        if((gstatus & 0x10) != 0)
        {
            //發送最大次數
            Pin_LED0(0);
            delay_ms(1000);
            Pin_LED0(1);
        }
        //接收
        if((gstatus & 0x40) != 0)
        {
            //接收到數據
            u8 tx_bufr[32];
            Get_Data(tx_bufr,32);
            if(tx_bufr[0] == 0x11)//和發送數據進行對比
            {
                Pin_LED0(0);
                delay_ms(1000);
                Pin_LED0(1);
            }
        }
        //清除中斷標志
        EXTI_ClearITPendingBit(EXTI_Line3);
    }
    ClearStatus();//清除中斷
    receive_data();//繼續接收
}
stm32f0xx_it.c

4.delay.h 延時函數(摘自網絡)

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

static u8  fac_us=0;//us延時倍乘數
static u16 fac_ms=0;//ms延時倍乘數
//初始化延遲函數
//SYSTICK的時鍾固定為HCLK時鍾的1/8
//SYSCLK:系統時鍾
void delay_init(u8 SYSCLK)
{
    SysTick->CTRL&=0xfffffffb;//bit2清空,選擇外部時鍾  HCLK/8
    fac_us=SYSCLK/8;            
    fac_ms=(u16)fac_us*1000;
}                                    
//延時nms
//注意nms的范圍
//SysTick->LOAD為24位寄存器,所以,最大延時為:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLK單位為Hz,nms單位為ms
//對72M條件下,nms<=1864 
void delay_ms(u16 nms)
{                     
    u32 temp;           
    SysTick->LOAD=(u32)nms*fac_ms;//時間加載(SysTick->LOAD為24bit)
    SysTick->VAL =0x00;           //清空計數器
    SysTick->CTRL=0x01 ;          //開始倒數  
    do
    {
        temp=SysTick->CTRL;
    }
    while(temp&0x01&&!(temp&(1<<16)));//等待時間到達   
    SysTick->CTRL=0x00;       //關閉計數器
    SysTick->VAL =0X00;       //清空計數器              
}   
//延時nus
//nus為要延時的us數.                                               
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 入口測試函數

#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)
{
    //初始化延時函數 stm32f030為48
    delay_init(48);
    /*
    *KEY0_LED0_Config();配置一個按鍵和一個LED燈
    * PA0 按鍵
    * PA4 LED燈(系統自帶的用戶LED燈 低電平點亮)
    *
    *SPI_Config();配置SPI
    * PA1 NSS 片選
    * PA5 SCK 時鍾
    * PA6 MISO 主機輸入從機輸出
    * PA7 MOSI 主機輸出從機輸入
    *
    *NRF_Config();配置NRF24L01
    * PA2 CE 控制收發
    * PA3 IRQ 收發中斷
    */
    KEY0_LED0_Config();
    SPI_Config();
    NRF_Config();
    delay_us(20);
    if(nrf24l0_check()==0)
    {
        //存在nrf2401模塊
        Pin_LED0(0);
        delay_ms(1000);
        Pin_LED0(1);
        
        receive_data();//接收
    }
    while(1){ }
}
main.c

 

准備兩塊用於收發的stm32f030單片機和NRF無線模塊 用杜邦線連接起來(注意 MISO 和 MOSI 要對應連接, 不要交叉連接), 有必要還要引出用於測試的key0按鈕, LED是板子默認的PA4, 連接好后分別給兩塊板子插上燒錄器燒錄編譯好的代碼, 就可以按KEY0進行測試了, 如果另外一個單片機的LED燈亮說明成功了.

如果有不足的地方和經驗歡迎在評論區交流.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM