close

ST_logo_20130425.png

nRF24L01相關介紹在網上相當多,推薦以下可參考與學習網站,

nRF24L01無線收發器模組與Arduino通訊實驗(一) - 網昱多媒體

nRF24L01無線收發器模組與Arduino通訊實驗(二):一對一通訊

nRF24L01無線收發器模組與Arduino通訊實驗(三):降低電源雜訊干擾

Arduino 無線傳輸模組 NRF24L01 測試

nRF24L01模組接腳定義如下,

Untitled Sketch_bb.png

1. 實驗材料

實驗需要兩組來做傳送與接收,

nRF24L01*2

229157.jpg

STM32F103C8T6開發板*2

20181027_181027_0001.jpg

USB TO TTL*1

20181015_181015_0003.jpg

J-link*1

20181027_181027_0002.jpg

USB延長線*1

20181015_181015_0001.jpg

線材*1

402985.jpg

USB A to B(當供電源使用)*1

229169.jpg

2. 電路接線圖

CE設在PA2

2.JPG

IRQ設在PA3

3.JPG

SPI 1設在PA4 PA5 PA6 PA7

4.JPG

3. 程式撰寫

在ExtDevices_Configuration下新增nrf24l01_config.h,

#ifndef __NRF24L01_CONFIG_H
#define __NRF24L01_CONFIG_H

#include "main.h"

//nRF24L01寄存器操作命令
#define R_REGISTER          0x00  //讀配置寄存器,低5位為寄存器地址
#define W_REGISTER         0x20 //寫配置寄存器,低5位為寄存器地址  
#define R_RX_PAYLOAD    0x61 //讀RX有效數據,1~32字節
#define W_TX_PAYLOAD   0xA0 //寫TX有效數據,1~32字節
#define FLUSH_TX             0xE1 //清除TX FIFO寄存器.發射模式下用
#define FLUSH_RX             0xE2 //清除RX FIFO寄存器.接收模式下用  
#define REUSE_TX_PL        0xE3 //重新使用上一包數據,CE為高,數據包被不斷發送
#define NOP                      0xFF //空操作,可以用來讀狀態寄存器 

//nRF24L01寄存器位址
#define CONFIG 0x00 //配置寄存器地址
                                    //bit6,中斷RX_DR使能     
                                    //bit5,中斷TX_DS使能
                                    //bit4,中斷MAX_RT(達到最大重發次數中斷)使能
                                    //bit3,CRC使能
                                    //bit2,CRC模式
                                    //bit1,電選擇
                                    //bit0,1接收模式,0發射模式                                                                                                                                                                                                                           
#define EN_AA 0x01 //使能自動應答功能 bit0~5,對應通道0~5
#define EN_RXADDR 0x02 //接收地址允許,bit0~5,對應通道0~5
#define SETUP_AW 0x03 //設置地址寬度(所有數據通道)
                                        //'00' - Illegal
                                        //'01' - 3 bytes 
                                       //'10' - 4 bytes
                                       //'11' - 5 bytes                                                                                                                     
#define SETUP_RETR 0x04 //建立自動重發
                                           //'0000' - Wait 250+86uS 
                                           //'0001' - Wait 500+86uS
                                           //'0010' - Wait 750+86uS        
                                           //......
                                           //'1111' - Wait 4000+86uS                                                                                                                        
#define RF_CH 0x05 //RF通道
                                 //bit6:0, 工作通道頻率                                                                                                                        
#define RF_SETUP 0x06 //RF寄存器
                                       //bit3,傳輸速率(0:1Mbps,1:2Mbps)
                                       //bit2:1,發射功率
                                       //bit0,低噪聲放大器增益                                                                                                                    
#define STATUS 0x07 //狀態寄存器
                                    //bit6,接收數據完成中斷    
                                    //bit5,數據發送完成中斷
                                    //bit4,自動重發完成中斷
                                    //bit3:1,接收數據通道號(最大:6)
                                    //bit0,TX FIFO滿標誌        
                                                                                                                       
#define STATUS_MAX_RT 0x10 //達到最大發送次數中斷,即自動重發完成中斷
#define STATUS_TX_DS 0x20 //TX發送完成中斷,即數據發送完成中斷
#define STATUS_RX_DR 0x40 //接收到數據中斷,即數據接收完成中斷

#define OBSERVE_TX 0x08 //發送檢測寄存器
                                            //bit7:4,數據包丟失計數器
                                            //bit3:0,重發計數器
#define CD 0x09 //載波檢測寄存器,
                            //bit0,載波檢測
#define RX_ADDR_P0 0x0A //數據通道0接收地址,最大長度5個字節,低字節在前
#define RX_ADDR_P1 0x0B //數據通道1接收地址,最大長度5個字節,低字節在前
#define RX_ADDR_P2 0x0C //數據通道2接收地址,最低字節可設置,高字節,必須同RX_ADDR_P1[39:8]相等
#define RX_ADDR_P3 0x0D //數據通道3接收地址,最低字節可設置,高字節,必須同RX_ADDR_P1[39:8]相等 
#define RX_ADDR_P4 0x0E //數據通道4接收地址,最低字節可設置,高字節,必須同RX_ADDR_P1[39:8]相等 
#define RX_ADDR_P5 0x0F //數據通道5接收地址,最低字節可設置,高字節,必須同RX_ADDR_P1[39:8]相等 
#define TX_ADDR 0x10 //發送地址(低字節在前),ShockBurstTM模式下,RX_ADDR_P0與此地址相等
#define RX_PW_P0 0x11 //接收數據通道0有效數據寬度(1~32字節),設置為0則非法
#define RX_PW_P1 0x12 //接收數據通道1有效數據寬度(1~32字節),設置為0則非法
#define RX_PW_P2 0x13 //接收數據通道2有效數據寬度(1~32字節),設置為0則非法
#define RX_PW_P3 0x14 //接收數據通道3有效數據寬度(1~32字節),設置為0則非法
#define RX_PW_P4 0x15 //接收數據通道4有效數據寬度(1~32字節),設置為0則非法
#define RX_PW_P5 0x16 //接收數據通道5有效數據寬度(1~32字節),設置為0則非法
#define FIFO_STATUS 0x17 //FIFO狀態寄存器
                                            //bit6,1,循環發送上一數據包;0,不循環
                                            //bit5,TX FIFO滿標誌
                                            //bit4,TX FIFO空標誌
                                            //bit2:3,保留
                                            //bit1,RX FIFO滿標誌
                                            //bit0,RX FIFO寄存器空標誌

#define TX_ADR_WIDTH 5 //5字節的地址寬度
#define RX_ADR_WIDTH 5 //5字節的地址寬度
#define TX_PLOAD_WIDTH 32 //32字節的地址寬度
#define RX_PLOAD_WIDTH 32 //32字節的地址寬度

/* nRF24L01接收模式 */                
void NRF24L01_RX_Mode(void);
/* nRF24L01寫入模式 */
void NRF24L01_TX_Mode(void);
/* nRF24L01傳送一次數據 */
uint8_t NRF24L01_TxPacket(uint8_t *txbuf);
/* nRF24L01接受一次數據 */
uint8_t NRF24L01_RxPacket(uint8_t *rxbuf);
/* nRF24L01檢查是否存在 */
uint8_t NRF24L01_Check(void);
/* nRF24L01接收Buffer */
uint8_t NRF24L01_Read_Buf(uint8_t reg, uint8_t *pBuf, uint8_t len);
/* nRF24L01寫入Buffer */
uint8_t NRF24L01_Write_Buf(uint8_t reg, uint8_t *pBuf, uint8_t len);
/* nRF24L01 SPI寄存器寫入 */                                                                                                                        
uint8_t NRF24L01_Write_Reg(uint8_t reg, uint8_t value);                                                                                                                        
/* nRF24L01 SPI寄存器讀取 */                                                                                                                        
uint8_t NRF24L01_Read_Reg(uint8_t reg);                                                                                                                        
                                
#endif 

在ExtDevices_Configuration下新增nrf24l01_config.c,

#include "nrf24l01_config.h"

const uint8_t TX_ADDRESS[TX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //發送地址
const uint8_t RX_ADDRESS[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //接收地址     
         
/*
程式名稱:nRF24L01接收模式
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/1/7
程式修改日期:N/A
程式說明:
該函數初始化NRF24L01到RX模式
設置RX地址,寫RX數據寬度,選擇RF頻道,波特率和LNA HCURR
當CE變高後,即進入RX模式,並可以接收數據了
*/
void NRF24L01_RX_Mode(void){
    
    /* CE Low */
  GPIO_ResetBits(GPIOA, GPIO_Pin_2);
    
  NRF24L01_Write_Buf(W_REGISTER + RX_ADDR_P0, (u8*)RX_ADDRESS, RX_ADR_WIDTH);
  /* 寫RX節點地址 */

  //使能通道0的自動應答    
  NRF24L01_Write_Reg(W_REGISTER + EN_AA, 0x01); 

  //使能通道0的接收地址 
  NRF24L01_Write_Reg(W_REGISTER + EN_RXADDR, 0x01);

  //設置RF頻道為40        
  NRF24L01_Write_Reg(W_REGISTER + RF_CH, 40);

  //選擇通道0的有效數據寬度
  NRF24L01_Write_Reg(W_REGISTER + RX_PW_P0, RX_PLOAD_WIDTH);
  //設置TX發射參數,0db增益,2Mbps,低噪聲增益開啟
  NRF24L01_Write_Reg(W_REGISTER + RF_SETUP, 0x0f); 

  //配置基本工作模式的參數;PWR_UP,EN_CRC,16BIT_CRC,接收模式
  NRF24L01_Write_Reg(W_REGISTER + CONFIG, 0x0f);
  /* CE High */
  GPIO_SetBits(GPIOA, GPIO_Pin_2);

/*
程式名稱:nRF24L01寫入模式
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/1/7
程式修改日期:N/A
程式說明:
該函數初始化NRF24L01到TX模式
設置TX地址,寫TX數據寬度,設置RX自動應答的地址,填充TX發送數據,選擇RF頻道,波特率和LNA HCURR
PWR_UP,CRC使能
當CE變高後,即進入RX模式,並可以接收數據了
CE為高大於10us,則啟動發送.
*/
void NRF24L01_TX_Mode(void){                                                        
    /* CE Low */
  GPIO_ResetBits(GPIOA, GPIO_Pin_2);  
    
  NRF24L01_Write_Buf(W_REGISTER + TX_ADDR, (u8*)TX_ADDRESS, TX_ADR_WIDTH);

  //寫TX節點地址
  NRF24L01_Write_Buf(W_REGISTER + RX_ADDR_P0, (u8*)RX_ADDRESS, RX_ADR_WIDTH);
  //使能通道0的自動應答  
  NRF24L01_Write_Reg(W_REGISTER + EN_AA, 0x01); 

  //使能通道0的接收地址  
  NRF24L01_Write_Reg(W_REGISTER + EN_RXADDR, 0x01);

  //設置自動重發間隔時間:500us + 86us;最大自動重發次數:10次
  NRF24L01_Write_Reg(W_REGISTER + SETUP_RETR, 0x1a);

  //設置RF頻道為40     
  NRF24L01_Write_Reg(W_REGISTER + RF_CH, 40);

  //設置TX發射參數,0db增益,2Mbps,低噪聲增益開啟
  NRF24L01_Write_Reg(W_REGISTER + RF_SETUP, 0x0f);  

  //配置基本工作模式的參數;PWR_UP,EN_CRC,16BIT_CRC,接收模式,開啟所有中斷
  NRF24L01_Write_Reg(W_REGISTER + CONFIG, 0x0e);
  /* CE High */
  GPIO_SetBits(GPIOA, GPIO_Pin_2);
}

/*
程式名稱:nRF24L01傳送一次數據
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/1/7
程式修改日期:N/A
程式說明:
啟動NRF24L01發送一次數據
txbuf:待發送數據首地址
返回值:發送完成狀況
*/
uint8_t NRF24L01_TxPacket(uint8_t *txbuf){
    uint8_t status=0;
  
    /* CE Low */
  GPIO_ResetBits(GPIOA, GPIO_Pin_2);  
  NRF24L01_Write_Buf(W_TX_PAYLOAD, txbuf, TX_PLOAD_WIDTH);//寫數據到TX BUF 32個字節
    /* CE High */
  GPIO_SetBits(GPIOA, GPIO_Pin_2);
    
  while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3)!=0);//等待發送完成
    
  status = NRF24L01_Read_Reg(STATUS);//讀取狀態寄存器的值  
  NRF24L01_Write_Reg(W_REGISTER + STATUS, status);//清除TX_DS或MAX_RT中斷標誌 
    
    //達到最大重發次數
  if(status&STATUS_MAX_RT){
        NRF24L01_Write_Reg(FLUSH_TX, 0xff);//清除TX FIFO寄存器
    return STATUS_MAX_RT; 
  }
        
    //發送完成
    if(status&STATUS_TX_DS){
        return STATUS_TX_DS;
  }else{
    return 0xff;//其他原因發送失敗
    }
}

/*
程式名稱:nRF24L01接受一次數據
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/1/7
程式修改日期:N/A
程式說明:
啟動NRF24L01發送一次數據
rxbuf:待發送數據首地址
返回值:發送完成狀況
*/
uint8_t NRF24L01_RxPacket(uint8_t *rxbuf){
  uint8_t status=0;  
    
    status = NRF24L01_Read_Reg(STATUS);//讀取狀態寄存器的值
  NRF24L01_Write_Reg(W_REGISTER + STATUS, status);//清除TX_DS或MAX_RT中斷標誌
    //接收到數據
    if(status&STATUS_RX_DR){
        NRF24L01_Read_Buf(R_RX_PAYLOAD, rxbuf, RX_PLOAD_WIDTH);//讀取數據
    NRF24L01_Write_Reg(FLUSH_RX, 0xff);//清除RX FIFO寄存器
    return 0; 
    }else{      
        return 1;//沒收到任何數據
    }
}  

/*
程式名稱:nRF24L01檢查是否存在
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/1/7
程式修改日期:N/A
程式說明:
返回值:
0,成功
1,失敗 
*/
uint8_t NRF24L01_Check(void){
    uint8_t buf[5]={0XAA,0XAA,0XAA,0XAA,0XAA};
  uint8_t i=0;   
        
    NRF24L01_Write_Buf(W_REGISTER + TX_ADDR,buf, 5);
  NRF24L01_Read_Buf(TX_ADDR, buf, 5); 
  for(i=0; i<5; i++){
        if(buf[i]!=0XAA){
            break;  
        }
    }    
    
    if(i!=5){
        return 1;
    }else{
        return 0;
    }        
}

/*
程式名稱:nRF24L01接收Buffer
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/1/7
程式修改日期:N/A
程式說明:
在指定位置讀出指定長度的數據
reg: 寄存器(位置)
*pBuf: 數據指針
len: 數據長度
返回值,此次讀到的狀態寄存器值
*/
uint8_t NRF24L01_Read_Buf(uint8_t reg, uint8_t *pBuf, uint8_t len){
    uint8_t status=0,i=0;  
    
    /* NSS Low */
    GPIO_ResetBits(GPIOA, GPIO_Pin_4);         
  status = SPI1_ReadWriteByte(reg);  
  for(i=0; i<len; i++){
        pBuf[i] = SPI1_ReadWriteByte(0XFF);
    }
    /* NSS High */
    GPIO_SetBits(GPIOA, GPIO_Pin_4);        
  
  return status;       
}

/*
程式名稱:nRF24L01寫入Buffer
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/1/7
程式修改日期:N/A
程式說明:
在指定位置寫指定長度的數據
reg:寄存器(位置)
*pBuf:數據指針
len:數據長度
返回值,此次讀到的狀態寄存器值
*/
uint8_t NRF24L01_Write_Buf(uint8_t reg, uint8_t *pBuf, uint8_t len){
    uint8_t status=0,i=0;  
    
    /* NSS Low */
    GPIO_ResetBits(GPIOA, GPIO_Pin_4);              
  status = SPI1_ReadWriteByte(reg);
  for(i=0; i<len; i++){
        SPI1_ReadWriteByte(*pBuf++);
    }
    /* NSS High */
    GPIO_SetBits(GPIOA, GPIO_Pin_4);        
    
  return status;         
}

/*
程式名稱:nRF24L01 SPI寄存器寫入
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/1/7
程式修改日期:N/A
程式說明:
reg:寄存器位址
value:寫入寄存器的值
*/
uint8_t NRF24L01_Write_Reg(uint8_t reg, uint8_t value){
    uint8_t status=0; 
    
    /* NSS Low */
    GPIO_ResetBits(GPIOA, GPIO_Pin_4);                      
  status = SPI1_ReadWriteByte(reg);
  SPI1_ReadWriteByte(value);      
    /* NSS High */
    GPIO_SetBits(GPIOA, GPIO_Pin_4);          
    
  return status;                 
}

/*
程式名稱:nRF24L01 SPI寄存器讀取
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/1/7
程式修改日期:N/A
程式說明:
reg:寄存器位址
*/
uint8_t NRF24L01_Read_Reg(uint8_t reg){
    uint8_t reg_value=0; 
    
        /* NSS Low */
        GPIO_ResetBits(GPIOA, GPIO_Pin_4);           
        SPI1_ReadWriteByte(reg);   
    reg_value = SPI1_ReadWriteByte(0XFF);
        /* NSS High */
        GPIO_SetBits(GPIOA, GPIO_Pin_4);         
    
    return reg_value;           
}

在STM32F103_Configuration下新增gpio_config.c,

#include "gpio_config.h"

/*
程式名稱:LED配置初始化
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/1/7
程式修改日期:N/A
程式說明:

*/
void LED_ConfigInit(void){         
  GPIO_InitTypeDef  GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);    

  GPIO_ResetBits(GPIOC, GPIO_Pin_13);
}

/*
程式名稱:nRF24L01 CE配置初始化
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/1/7
程式修改日期:N/A
程式說明:
nRF24L01之CE功能
*/
void nRF24L01_CE_ConfigInit(void){         
  GPIO_InitTypeDef  GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);    
    /* CE Low */
  GPIO_ResetBits(GPIOA, GPIO_Pin_2);
}

/*
程式名稱:nRF24L01 IRQ配置初始化
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/1/7
程式修改日期:N/A
程式說明:
nRF24L01之IRQ功能
*/
void nRF24L01_IRQ_ConfigInit(void){         
  GPIO_InitTypeDef  GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(GPIOA, &GPIO_InitStructure);    
}

在STM32F103_Configuration下新增gpio_config.h,

#ifndef __GPIO_CONFIG_H
#define __GPIO_CONFIG_H

#include "main.h"

/* LED初始化 */
void LED_ConfigInit(void);
/* nRF24L01 CE配置初始化 */
void nRF24L01_CE_ConfigInit(void);
/* nRF24L01 IRQ配置初始化 */
void nRF24L01_IRQ_ConfigInit(void);
    
#endif 

在STM32F103_Configuration下新增spi1_config.c,

#include "spi1_config.h"

/* 結構變數SPI_1 */
_SPI_Type SPI_1;
/* 結構指標*SPI1_Ptr */
_SPI_Type *SPI1_Ptr=&SPI_1;

/*
程式名稱:SPI1配置初始化
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/1/7
程式修改日期:N/A
程式說明:

*/
void SPI1_ConfigInit(void){
    GPIO_InitTypeDef  GPIO_InitStructure;
    SPI_InitTypeDef   SPI_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1, ENABLE);
    
  //PA5.SPI1_SCK; PA7.SPI_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_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    //PA6.SPI_MISO;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);        
    
    /* NSS */ 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);    
    /* NSS High */
    GPIO_SetBits(GPIOA, GPIO_Pin_4);        

  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);    
}

/*
程式名稱:SPI1寫入Btye
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/1/7
程式修改日期:N/A
程式說明:

*/
uint8_t SPI1_ReadWriteByte(uint8_t TxData){         
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) {}             
  SPI_I2S_SendData(SPI1, TxData); 
  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET){}                               
  return SPI_I2S_ReceiveData(SPI1);         
}

在STM32F103_Configuration下新增spi1_config.h,

#ifndef __SPI1_CONFIG_H
#define __SPI1_CONFIG_H

#include "main.h"

#define BUFFERSIZE 255

/*
程式名稱:SPI1全域變數
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2017/11/9
程式修改日期:N/A
程式說明:

*/
typedef struct
{
    uint8_t aTxBuffer[BUFFERSIZE];
    uint8_t aRxBuffer[BUFFERSIZE];
    uint8_t ubRxIndex;
}_SPI_Type;
/* 結構變數SPI_1 */
extern _SPI_Type SPI_1;
/* 結構指標*SPI1_Ptr */
extern _SPI_Type *SPI1_Ptr;

 

/* SPI1配置初始化 */
void SPI1_ConfigInit(void);
/* SPI1寫入Btye */
uint8_t SPI1_ReadWriteByte(uint8_t TxData);

#endif 

4. 實驗結果

這次實驗需要兩組,一組負責發送,一組負責接收,負責發送部分需修改bsp.c main.c main.h,

bsp.c

#include "bsp.h"

/*
程式名稱:開發板全域變數初始化
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/3/6
程式修改日期:N/A
程式說明:

*/
void BSP_VariableInit(void){

}

/*
程式名稱:開發板整體系統初始化
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/3/6
程式修改日期:N/A
程式說明:

*/
void BSP_Init(void){
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    
    /* LED配置初始化 */
    LED_ConfigInit();

    /* nRF24L01 CE配置初始化 */
    nRF24L01_CE_ConfigInit();
    /* nRF24L01 IRQ配置初始化 */
    nRF24L01_IRQ_ConfigInit();        
    /* SPI1配置初始化 */
    SPI1_ConfigInit();
    /* nRF24L01傳送模式 */
    NRF24L01_TX_Mode();    

}

main.c

#include "main.h"

/*
程式名稱:主程式
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/1/6
程式修改日期:N/A
程式說明:

*/

int main(void){

    /* 開發板全域變數初始化 */
    BSP_VariableInit();
    /* 開發板整體系統初始化 */
    BSP_Init();
    
  /* Infinite loop */
  for(;;){
        

        /* nRF24L01傳送一次數據 */
        NRF24L01_TxPacket((uint8_t*)"ABCDEFGHIJKLMNOPQRSTUVWXYZ1234\r\n");

        
        if(GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_13)==0){
            GPIO_SetBits(GPIOC, GPIO_Pin_13);
        }else{
            GPIO_ResetBits(GPIOC, GPIO_Pin_13);
        }
        delay_ms(2000);
  }
}

#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)

  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

main.h

#ifndef __MAIN_H
#define __MAIN_H

#include "stm32f10x.h"
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <math.h> 
#include <stdlib.h>

/* STM32F429_Configuration */
#include "delay_config.h"
#include "gpio_config.h"
#include "spi1_config.h"
#include "uart3_config.h"

/* ExtDevices_Configuration */
#include "nrf24l01_config.h"

/* User */
#include "main.h"
#include "bsp.h"
#include "global_variable.h"

#endif

負責接收部分需修改bsp.c main.c

bsp.c

#include "bsp.h"

/*
程式名稱:開發板全域變數初始化
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/3/6
程式修改日期:N/A
程式說明:

*/
void BSP_VariableInit(void){

}

/*
程式名稱:開發板整體系統初始化
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/3/6
程式修改日期:N/A
程式說明:

*/
void BSP_Init(void){
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    
    /* LED配置初始化 */
    LED_ConfigInit();
    /* UART3配置初始化 */
    UART3_ConfigInit();

    /* nRF24L01 CE配置初始化 */
    nRF24L01_CE_ConfigInit();
    /* nRF24L01 IRQ配置初始化 */
    nRF24L01_IRQ_ConfigInit();        
    /* SPI1配置初始化 */
    SPI1_ConfigInit();
    /* nRF24L01接收模式 */
    NRF24L01_RX_Mode();

}

main.c

#include "main.h"

/*
程式名稱:主程式
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/1/6
程式修改日期:N/A
程式說明:

*/
uint8_t rxbuf[32];

int main(void){

    /* 開發板全域變數初始化 */
    BSP_VariableInit();
    /* 開發板整體系統初始化 */
    BSP_Init();
    
  /* Infinite loop */
  for(;;){

        /* nRF24L01接受一次數據 */
        if(NRF24L01_RxPacket(rxbuf)==0){
            UART3_Send(rxbuf, 32);
        }

        
        if(GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_13)==0){
            GPIO_SetBits(GPIOC, GPIO_Pin_13);
        }else{
            GPIO_ResetBits(GPIOC, GPIO_Pin_13);
        }
        delay_ms(2000);
  }
}

#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)

  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

實驗結果

1.JPG

arrow
arrow

    鄭智遠 發表在 痞客邦 留言(0) 人氣()