提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言一、原理图1.STM32F103C8T62.NRF24L01
二、Keil代码1.SPI_NRF2401.C2.SPI_NRF24L01.h3.Struct.h4.main.c
总结
前言
STM32下NRF24L01实现无线传输
一、原理图
1.STM32F103C8T6
2.NRF24L01
NRF24L01是 nordic 的无线通信芯片,它具有以下特点:
1) 2.4G 全球开放的 ISM 频段(2.400 - 2.4835GHz),免许可证使用; 2)最高工作速率 2Mbps,高校的 GFSK 调制,抗干扰能力强; 3) 125 个可选的频道,满足多点通信和调频通信的需要; 4)内置 CRC 检错和点对多点的通信地址控制; 5)低工作电压(1.9~3.6V),待机模式下状态为 26uA;掉电模式下为 900nA; 6)可设置自动应答,确保数据可靠传输; 7)工作于EnhancedShockBurst 具有Automatic packet handling,Auto packet transaction handling ,可以实现点对点或是 1 对 6 的无线通信,速度可以达到 2M(bps),具有可选的内置包应答机制,极大的降低丢包率。 8)通过 SPI 总线与单片机进行交互,最大通信速率为10Mbps;
二、Keil代码
1.SPI_NRF2401.C
#include "Struct.h"
#define NRF_CE_GPIO GPIOC
#define NRF_CE_Pin GPIO_Pin_14
#define NRF_CSN_GPIO GPIOC
#define NRF_CSN_Pin GPIO_Pin_13
#define NRF_IRQ_GPIO GPIOC
#define NRF_IRQ_Pin GPIO_Pin_15
#define NRF_CE_H NRF_CE_GPIO ->BSRR = NRF_CE_Pin
#define NRF_CE_L NRF_CE_GPIO ->BRR = NRF_CE_Pin
#define NRF_CSN_H NRF_CSN_GPIO->BSRR = NRF_CSN_Pin
#define NRF_CSN_L NRF_CSN_GPIO->BRR = NRF_CSN_Pin
#define NRF_IRQ_Read NRF_IRQ_GPIO->IDR & NRF_IRQ_Pin
uint8_t NRF24L01_RXDATA
[32];
uint8_t NRF24L01_TXDATA
[32];
static uint8_t TX_ADDRESS
[5]= {0x1A,0x2A,0x3A,0x4A,0x5A};
static uint8_t RX_ADDRESS
[5]= {0x1A,0x2A,0x3A,0x4A,0x5A};
static uint16_t Nrf_Erro
=0;
void SPI2_Init(void)
{
SPI_InitTypeDef SPI_InitStructure
;
GPIO_InitTypeDef GPIO_InitStructure
;
EXTI_InitTypeDef EXTI_InitStructure
;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB
| RCC_APB2Periph_GPIOC
| RCC_APB2Periph_AFIO
, ENABLE
);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2
, ENABLE
);
GPIO_InitStructure
.GPIO_Pin
= GPIO_Pin_13
|GPIO_Pin_14
|GPIO_Pin_15
;
GPIO_InitStructure
.GPIO_Speed
= GPIO_Speed_10MHz
;
GPIO_InitStructure
.GPIO_Mode
= GPIO_Mode_AF_PP
;
GPIO_Init(GPIOB
, &GPIO_InitStructure
);
GPIO_InitStructure
.GPIO_Pin
= NRF_CE_Pin
;
GPIO_InitStructure
.GPIO_Speed
= GPIO_Speed_10MHz
;
GPIO_InitStructure
.GPIO_Mode
= GPIO_Mode_Out_PP
;
GPIO_Init(NRF_CE_GPIO
, &GPIO_InitStructure
);
GPIO_InitStructure
.GPIO_Pin
= NRF_CSN_Pin
;
GPIO_InitStructure
.GPIO_Speed
= GPIO_Speed_10MHz
;
GPIO_InitStructure
.GPIO_Mode
= GPIO_Mode_Out_PP
;
GPIO_Init(NRF_CSN_GPIO
, &GPIO_InitStructure
);
GPIO_InitStructure
.GPIO_Pin
= NRF_IRQ_Pin
;
GPIO_InitStructure
.GPIO_Speed
= GPIO_Speed_50MHz
;
GPIO_InitStructure
.GPIO_Mode
= GPIO_Mode_IPU
;
GPIO_Init(NRF_IRQ_GPIO
, &GPIO_InitStructure
);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC
,GPIO_PinSource15
);
EXTI_InitStructure
.EXTI_Line
=EXTI_Line15
;
EXTI_InitStructure
.EXTI_Mode
=EXTI_Mode_Interrupt
;
EXTI_InitStructure
.EXTI_Trigger
=EXTI_Trigger_Falling
;
EXTI_InitStructure
.EXTI_LineCmd
=ENABLE
;
EXTI_Init(&EXTI_InitStructure
);
NRF_CSN_H
;
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(SPI2
, &SPI_InitStructure
);
SPI_Cmd(SPI2
, ENABLE
);
}
uint8_t
SPI_RW(uint8_t data
)
{
while (SPI_I2S_GetFlagStatus(SPI2
, SPI_I2S_FLAG_TXE
) == RESET
);
SPI_I2S_SendData(SPI2
, data
);
while (SPI_I2S_GetFlagStatus(SPI2
, SPI_I2S_FLAG_RXNE
) == RESET
);
return SPI_I2S_ReceiveData(SPI2
);
}
uint8_t
NRF_Write_Reg(uint8_t reg
, uint8_t value
)
{
uint8_t status
;
NRF_CSN_L
;
status
= SPI_RW(reg
);
SPI_RW(value
);
NRF_CSN_H
;
return status
;
}
uint8_t
NRF_Read_Reg(uint8_t reg
)
{
uint8_t reg_val
;
NRF_CSN_L
;
SPI_RW(reg
);
reg_val
= SPI_RW(0);
NRF_CSN_H
;
return reg_val
;
}
uint8_t
NRF_Write_Buf(uint8_t reg
, uint8_t
*pBuf
, uint8_t uchars
)
{
uint8_t i
;
uint8_t status
;
NRF_CSN_L
;
status
= SPI_RW(reg
);
for(i
=0; i
<uchars
; i
++)
{
SPI_RW(pBuf
[i
]);
}
NRF_CSN_H
;
return status
;
}
uint8_t
NRF_Read_Buff(uint8_t reg
, uint8_t
*pBuf
, uint8_t uchars
)
{
uint8_t i
;
uint8_t status
;
NRF_CSN_L
;
status
= SPI_RW(reg
);
for(i
=0; i
<uchars
; i
++)
{
pBuf
[i
] = SPI_RW(0);
}
NRF_CSN_H
;
return status
;
}
void NRF24L01_Check(void)
{
uint8_t buf
[5];
uint8_t i
;
NRF_Write_Buf(NRF_WRITE_REG
+TX_ADDR
,TX_ADDRESS
,5);
NRF_Read_Buff(TX_ADDR
,buf
,5);
for(i
=0;i
<5;i
++)
{
if(buf
[i
]!=TX_ADDRESS
[i
])
break;
}
}
static void NRF24L01_Set_TX(void)
{
NRF_CE_L
;
NRF_Write_Reg(NRF_WRITE_REG
+ CONFIG
,0x0E);
NRF_CE_H
;
}
static void NRF24L01_Set_RX(void)
{
NRF_CE_L
;
NRF_Write_Reg(NRF_WRITE_REG
+ CONFIG
,0x0F);
NRF_CE_H
;
}
void NRF_Send_TX(uint8_t
* tx_buf
, uint8_t len
)
{
NRF24L01_Set_TX();
NRF_CE_L
;
NRF_Write_Buf(WR_TX_PLOAD
, tx_buf
, len
);
NRF_CE_H
;
}
void NRF24L01_Init(uint8_t Chanal
,uint8_t Mode
)
{
NRF_CE_L
;
NRF_Write_Reg(FLUSH_TX
,0xff);
NRF_Write_Reg(FLUSH_RX
,0xff);
NRF_Write_Buf(NRF_WRITE_REG
+ TX_ADDR
, TX_ADDRESS
,5);
NRF_Write_Buf(NRF_WRITE_REG
+ RX_ADDR_P0
,RX_ADDRESS
,5);
NRF_Write_Reg(NRF_WRITE_REG
+ EN_AA
, 0x01);
NRF_Write_Reg(NRF_WRITE_REG
+ EN_RXADDR
, 0x01);
NRF_Write_Reg(NRF_WRITE_REG
+ SETUP_RETR
,0x1a);
NRF_Write_Reg(NRF_WRITE_REG
+ RF_CH
, Chanal
);
NRF_Write_Reg(NRF_WRITE_REG
+ RX_PW_P0
, 32);
NRF_Write_Reg(NRF_WRITE_REG
+ RF_SETUP
, 0x0f);
if(Mode
==TX
)
NRF_Write_Reg(NRF_WRITE_REG
+ CONFIG
,0x0E);
else if(Mode
==RX
)
NRF_Write_Reg(NRF_WRITE_REG
+ CONFIG
,0x0F);
NRF_CE_H
;
}
static void NRF24L01_Analyse(void)
{
uint8_t sum
= 0,i
;
uint8_t len
= NRF24L01_RXDATA
[3] + 5;
for(i
=3;i
<len
;i
++)
sum
^= NRF24L01_RXDATA
[i
];
if( sum
!=NRF24L01_RXDATA
[len
] ) return;
if( NRF24L01_RXDATA
[0] != '$' ) return;
if( NRF24L01_RXDATA
[1] != 'M' ) return;
if( NRF24L01_RXDATA
[2] != '>' ) return;
}
void NRF24L01_IRQ(void)
{
uint8_t status
= NRF_Read_Reg(NRF_READ_REG
+ NRFRegSTATUS
);
if(status
& (1<<RX_DR
))
{
uint8_t rx_len
= NRF_Read_Reg(R_RX_PL_WID
);
if(rx_len
==32)
{
NRF_Read_Buff(RD_RX_PLOAD
,NRF24L01_RXDATA
,rx_len
);
Nrf_Erro
= 0;
}
else
{
NRF_Write_Reg(FLUSH_RX
,0xff);
}
}
if(status
& (1<<MAX_RT
))
{
if(status
& (1<<TX_FULL
))
{
NRF_Write_Reg(FLUSH_TX
,0xff);
}
}
if(status
& (1<<TX_DS
))
{
NRF24L01_Set_RX();
}
NRF_Write_Reg(NRF_WRITE_REG
+ NRFRegSTATUS
, status
);
}
void Nrf_Connect(void)
{
Nrf_Erro
++;
if(Nrf_Erro
==1)
{
NRF24L01_Analyse();
}
if(Nrf_Erro
%50==0)
{
NRF24L01_IRQ();
}
if(Nrf_Erro
>=500)
{
Nrf_Erro
= 1;
}
}
2.SPI_NRF24L01.h
#ifndef _SPI_NRF24L01_H_
#define _SPI_NRF24L01_H_
#include "stm32f10x.h"
#define TX 1
#define RX 2
#define RX_DR 6
#define TX_DS 5
#define MAX_RT 4
#define TX_FULL 0
extern uint8_t NRF24L01_RXDATA
[32];
extern uint8_t NRF24L01_TXDATA
[32];
void SPI2_Init(void);
void NRF24L01_IRQ(void);
void NRF24L01_Check(void);
void NRF24L01_Init(uint8_t Chanal
,uint8_t Mode
);
void NRF_Send_TX(uint8_t
* tx_buf
, uint8_t len
);
void Nrf_Connect(void);
uint8_t
NRF_Read_Reg(uint8_t reg
);
uint8_t
NRF_Write_Reg(uint8_t reg
, uint8_t value
);
uint8_t
NRF_Read_Buff(uint8_t reg
, uint8_t
*pBuf
, uint8_t uchars
);
#define NRF_READ_REG 0x00
#define NRF_WRITE_REG 0x20
#define ACTIVATE 0x50
#define R_RX_PL_WID 0x60
#define RD_RX_PLOAD 0x61
#define WR_TX_PLOAD 0xA0
#define W_ACK_PAYLOAD 0xA8
#define FLUSH_TX 0xE1
#define FLUSH_RX 0xE2
#define REUSE_TX_PL 0xE3
#define NOP 0xFF
#define CONFIG 0x00
#define EN_AA 0x01
#define EN_RXADDR 0x02
#define SETUP_AW 0x03
#define SETUP_RETR 0x04
#define RF_CH 0x05
#define RF_SETUP 0x06
#define NRFRegSTATUS 0x07
#define OBSERVE_TX 0x08
#define CD 0x09
#define RX_ADDR_P0 0x0A
#define RX_ADDR_P1 0x0B
#define RX_ADDR_P2 0x0C
#define RX_ADDR_P3 0x0D
#define RX_ADDR_P4 0x0E
#define RX_ADDR_P5 0x0F
#define TX_ADDR 0x10
#define RX_PW_P0 0x11
#define RX_PW_P1 0x12
#define RX_PW_P2 0x13
#define RX_PW_P3 0x14
#define RX_PW_P4 0x15
#define RX_PW_P5 0x16
#define FIFO_STATUS 0x17
#define DYNPD 0x1C
#define FEATURE 0x1D
#endif
3.Struct.h
#ifndef _STRUCT_H_
#define _STRUCT_H_
#include "stm32f10x.h"
#include "Led.h"
#include "SPI_NRF24L01.h"
#include "Uart.h"
#endif
4.main.c
#include "Struct.h"
int main(void)
{
SPI2_Init();
NRF24L01_Init(35,TX
);
NRF24L01_Check();
PrintString("\r\n HEELO QST! \r\n");
}
总结
以上就是今天要讲的内容,本文仅仅简单介绍了基于STM32F103C8T6在Keil下编程实现NRF24L01实现无线传输的原理图和代码。