一、NRF24L01简介
NRF24L01是一款由挪威Nordic Semiconductor公司生产的单芯片2.4GHz无线通信收发器,广泛用于短距离无线通信。
图1: NRF24L01+1100m
NRF24L01可应用于以下场景中:
无线遥控:如无线遥控玩具车、无人机等。
传感器网络:用于数据采集和监控系统,如温度、湿度传感器等。
家庭自动化:无线控制家中的智能设备,如灯光、窗帘等。
数据传输:用于短距离数据传输,如无线鼠标、键盘等。
工业控制:在工业环境中,用于设备间的无线通信。
个人健康监测:如无线心率监测器、血压计等。
NRF24L01种类很多,常规的NRF24L01即可满足普通的遥控器控制,本次遥控器使用的是NRF24L01+1100m,主要是实现远距离控制。
二、PCB电路
NRF24L01的接口较多,有8个接口,为了测试方便,使用嘉立创标准版打了一个遥控器的PCB板,并附加了几个按键,经过实测,大部分电路正常,只有**PB3的按键电路存在问题**,按键按下时没有反应,原因未知。 下图为自制的双轴遥控器PCB电路图,接收端的NRF24L01与发送端的NRF24L01的接口引脚一致。
图2:PCB原理图
图3 双轴遥控器实物图
后续优化方向,进一步缩小双轴遥控器的体积,仅保留有用的端口,进一步提高集成度,使用各类贴片元器件,减少遥控器体积。使用建模软件,为遥控器搭建一个外壳,增加充电电路,提高电池的利用率。
三、控制原理
NRF24L01通过SPI(串行外设接口)与微控制器或其他控制设备进行通信。SPI是一种常见的串行通信协议,由主设备控制从设备的时钟信号和数据交换。
stm32f103c8t6通过adc采集遥杆的值,原始值为0-4096,再将获取的ad值除8,处理后遥杆值为0-512。通过推杆值的变化,使NRF24L01发送不同的字符,接受端接受到这些字符后进行解析匹配,如果字符接收匹配成功,就会执行指令,可选择接收端的NRF24L01是否需要发送返回值。
根据实机验证,目前实现了用遥杆完成点灯。
图4 双机通讯实物 接受端(左)双轴遥控器(右)
四、发送端所需硬件及成本核算
遥杆模块*2:
18650锂电池:
18650电池座:
SS12D10开关
stm32f103c8t6:
665中二脚按键:
排母:
显示屏
NRF24L01+1100m*2
总成本大约(包括两个led灯和两个电阻)是88左右
五 发送端代码
nrf24l01.c
# include "NRF24L01.h"
#include "NRF24L01_Ins.h"
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "math.h"
/***************************************************************************
主要函数使用说明:
NRF24L01_Pin_Init() 引脚初始化, 无参数,无返回值,一般不调用,初始化直接调用NRF24L01_Init()即可
*---------------------------------------------------------------------------*
NRF24L01_Write_Reg(uint8_t Reg, uint8_t Value) 写NRF24L01寄存器
参数:Reg, 寄存器地址
Value:要写入的数据
返回值:状态值
*---------------------------------------------------------------------------*
NRF24L01_Read_Reg(uint8_t Reg) 读NRF24L01寄存器
参数:Reg:寄存器地址
返回值:状态值
*---------------------------------------------------------------------------*
NRF24L01_Read_Buf(uint8_t Reg, uint8_t *Buf, uint8_t Len) 一次读NRF24L01寄存器多个字节
参数:Reg:寄存器地址;*Buf:寄存器字节读出后存储的数组;Len:要读出的字节个数
返回值:状态值
*---------------------------------------------------------------------------*
NRF24L01_Write_Buf(uint8_t Reg, uint8_t *Buf, uint8_t Len) 一次写NRF24L01寄存器多个字节
参数:Reg:寄存器地址;*Buf:寄存器写入字节的存放数组;Len:要读出的字节个数
返回值:状态值
*---------------------------------------------------------------------------*
NRF24L01_GetRxBuf(uint8_t *Buf) 读出接收到的数据,为多个字节
参数:*Buf多个字节存放的数组
返回值:状态值
*---------------------------------------------------------------------------*
NRF24L01_SendTxBuf(uint8_t *Buf) 发送多个字节
参数:*Buf要发送的字节存放的数组
返回值:状态值
*---------------------------------------------------------------------------*
NRF24L01_Check(void) 检验NRF24L01是否存在
返回值:1:不存在,0:存在
*---------------------------------------------------------------------------*
NRF24L01_Init() NRF24L01初始化,包含检验NRF24L01是否存在、收发配置初始化,初始化直接调用该函数即可
*---------------------------------------------------------------------------*
NRF24L01_RT_Init(void) NRF24L01收发配置初始化
*---------------------------------------------------------------------------*
NRF24L01_SendBuf(uint8_t *Buf) NRF24L01发送多个字节数据
参数:要发送字节存放的数组
*---------------------------------------------------------------------------*
uint8_t NRF24L01_Get_Value_Flag() 获取中断标志,一旦接收到数据,返回0
返回值:0:接收到数据;1:未接收到数据
************************** By:普普通通Ordinary **********************************/
/*************** 记得三连支持一下哦!QAQ *******************************************/
#define TX_ADR_WIDTH 5 //5字节地址宽度
#define RX_ADR_WIDTH 5 //5字节地址宽度
#define TX_PLOAD_WIDTH 32 //32字节有效数据宽度
#define RX_PLOAD_WIDTH 32 //32字节有效数据宽度
const uint8_t TX_ADDRESS[TX_ADR_WIDTH]={0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
const uint8_t RX_ADDRESS[RX_ADR_WIDTH]={0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
void W_SS(uint8_t BitValue)
{
GPIO_WriteBit(CSN_Port, CSN_Pin, (BitAction)BitValue);
}
void W_CE(uint8_t BitValue)
{
GPIO_WriteBit(CE_Port, CE_Pin, (BitAction)BitValue);
}
void W_SCK(uint8_t BitValue)
{
GPIO_WriteBit(SCK_Port, SCK_Pin, (BitAction)BitValue);
}
void W_MOSI(uint8_t BitValue)
{
GPIO_WriteBit(MOSI_Port, MOSI_Pin,(BitAction)BitValue);
}
uint8_t R_MISO(void)
{
return GPIO_ReadInputDataBit(MISO_Port, MISO_Pin);
}
uint8_t R_IRQ(void)
{
return GPIO_ReadInputDataBit(IRQ_Port, IRQ_Pin);
}
void NRF24L01_Pin_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = CSN_Pin;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(CSN_Port, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = SCK_Pin;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(SCK_Port, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = MOSI_Pin;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(MOSI_Port, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = CE_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(CE_Port, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = MISO_Pin;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(MISO_Port, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = IRQ_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(IRQ_Port, &GPIO_InitStructure);
}
uint8_t SPI_SwapByte(uint8_t Byte)
{
uint8_t i;
for(i = 0; i < 8; i ++)
{
if((uint8_t)(Byte & 0x80) == 0x80)
{
W_MOSI(1);
}
else
{
W_MOSI(0);
}
Byte = (Byte << 1);
W_SCK(1);
Byte |= R_MISO();
W_SCK(0);
}
return Byte;
}
uint8_t NRF24L01_Write_Reg(uint8_t Reg, uint8_t Value)
{
uint8_t Status;
W_SS(0);
Status = SPI_SwapByte(Reg);
SPI_SwapByte(Value);
W_SS(1);
return Status;
}
uint8_t NRF24L01_Read_Reg(uint8_t Reg)
{
uint8_t Value;
W_SS(0);
SPI_SwapByte(Reg);
Value = SPI_SwapByte(NOP);
W_SS(1);
return Value;
}
uint8_t NRF24L01_Read_Buf(uint8_t Reg, uint8_t *Buf, uint8_t Len)
{
uint8_t Status, i;
W_SS(0);
Status =SPI_SwapByte(Reg);
for(i = 0; i < Len; i ++)
{
Buf[i] = SPI_SwapByte(NOP);
}
W_SS(1);
return Status;
}
uint8_t NRF24L01_Write_Buf(uint8_t Reg, uint8_t *Buf, uint8_t Len)
{
uint8_t Status, i;
W_SS(0);
Status = SPI_SwapByte(Reg);
for(i = 0; i < Len; i ++)
{
SPI_SwapByte(*Buf ++);
}
W_SS(1);
return Status;
}
uint8_t NRF24L01_GetRxBuf(uint8_t *Buf)
{
uint8_t State;
State = NRF24L01_Read_Reg(STATUS);
NRF24L01_Write_Reg(nRF_WRITE_REG + STATUS, State);
if(State & RX_OK)
{
W_CE(1);
NRF24L01_Read_Buf(RD_RX_PLOAD, Buf, RX_PLOAD_WIDTH);
NRF24L01_Write_Reg(FLUSH_RX, NOP);
W_CE(1);
Delay_us(150);
return 0;
}
return 1;
}
uint8_t NRF24L01_SendTxBuf(uint8_t *Buf)
{
uint8_t State;
W_CE(0);
NRF24L01_Write_Buf(WR_TX_PLOAD, Buf, TX_PLOAD_WIDTH);
W_CE(1);
while(R_IRQ() == 1);
State = NRF24L01_Read_Reg(STATUS);
NRF24L01_Write_Reg(nRF_WRITE_REG + STATUS, State);
if(State&MAX_TX)
{
NRF24L01_Write_Reg(FLUSH_TX, NOP);
return MAX_TX;
}
if(State & TX_OK)
{
return TX_OK;
}
return NOP;
}
uint8_t NRF24L01_Check(void)
{
uint8_t check_in_buf[5] = {0x11 ,0x22, 0x33, 0x44, 0x55};
uint8_t check_out_buf[5] = {0x00};
W_SCK(0);
W_SS(1);
W_CE(0);
NRF24L01_Write_Buf(nRF_WRITE_REG + TX_ADDR, check_in_buf, 5);
NRF24L01_Read_Buf(nRF_READ_REG + TX_ADDR, check_out_buf, 5);
if((check_out_buf[0] == 0x11) && (check_out_buf[1] == 0x22) && (check_out_buf[2] == 0x33) && (check_out_buf[3] == 0x44) && (check_out_buf[4] == 0x55))
{
return 0;
}
else
{
return 1;
}
}
void NRF24L01_RT_Init(void)
{
W_CE(0);
NRF24L01_Write_Reg(nRF_WRITE_REG+RX_PW_P0, RX_PLOAD_WIDTH);
NRF24L01_Write_Reg(FLUSH_RX, NOP);
NRF24L01_Write_Buf(nRF_WRITE_REG + TX_ADDR, (uint8_t*)TX_ADDRESS, TX_ADR_WIDTH);
NRF24L01_Write_Buf(nRF_WRITE_REG + RX_ADDR_P0, (uint8_t*)RX_ADDRESS, RX_ADR_WIDTH);
NRF24L01_Write_Reg(nRF_WRITE_REG + EN_AA, 0x01);
NRF24L01_Write_Reg(nRF_WRITE_REG + EN_RXADDR, 0x01);
NRF24L01_Write_Reg(nRF_WRITE_REG + SETUP_RETR, 0x1A);
NRF24L01_Write_Reg(nRF_WRITE_REG + RF_CH, 0);
NRF24L01_Write_Reg(nRF_WRITE_REG + RF_SETUP, 0x0F);
NRF24L01_Write_Reg(nRF_WRITE_REG + CONFIG, 0x0F);
W_CE(1);
}
void NRF24L01_Init()
{
NRF24L01_Pin_Init();
while(NRF24L01_Check());
NRF24L01_RT_Init();
}
void NRF24L01_SendBuf(uint8_t *Buf)
{
W_CE(0);
NRF24L01_Write_Reg(nRF_WRITE_REG + CONFIG, 0x0E);
W_CE(1);
Delay_us(15);
NRF24L01_SendTxBuf(Buf);
W_CE(0);
NRF24L01_Write_Reg(nRF_WRITE_REG + CONFIG, 0x0F);
W_CE(1);
}
uint8_t NRF24L01_Get_Value_Flag()
{
return R_IRQ();
}
void NRF24L01_SendString(char *String)
{
uint8_t Psign[32] = {0};
uint8_t SendBuf[33] = {0};
uint8_t TSign = 0;
for (uint8_t i = 0; i < 32; i ++)
{
if (String[i] != 0)
{
Psign[TSign] = i;
TSign ++;
}
}
if (TSign > 0)
{
TSign --;
}
SendBuf[0] = Psign[TSign] + 1;
for (uint8_t i = 0; i < SendBuf[0]; i ++)
{
SendBuf[i + 1] = String[i];
}
NRF24L01_SendBuf(SendBuf);
}
void NRF24L01_SendNum(uint32_t Num)
{
uint8_t SendBuf[11] = {0};
SendBuf[0] = 10;
for (uint8_t i = 0; i < 10; i ++)
{
SendBuf[i + 1] = Num / (uint32_t)pow(10, 9 - i) % 10;
}
NRF24L01_SendBuf(SendBuf);
}
uint32_t NRF24L01_GetNum(void)
{
uint32_t Num = 0;
uint8_t Buf[33] = {0};
NRF24L01_GetRxBuf(Buf);
for (uint16_t i = 0; i < 10; i ++)
{
Num += Buf[i + 1] * pow(10, 9 - i);
}
return Num;
}
nrf24l01.h
#ifndef __nRF24L01_API_H
#define __nRF24L01_API_H
#include "stm32f10x.h" // Device header
uint8_t SPI_SwapByte(uint8_t byte);
uint8_t NRF24L01_Write_Reg(uint8_t reg,uint8_t value);
uint8_t NRF24L01_Read_Reg(uint8_t reg);
uint8_t NRF24L01_Read_Buf(uint8_t reg,uint8_t *pBuf, uint8_t len);
uint8_t NRF24L01_Write_Buf(uint8_t reg, uint8_t *pBuf, uint8_t len);
uint8_t NRF24L01_GetRxBuf(uint8_t *rxbuf);
uint8_t NRF24L01_SendTxBuf(uint8_t *txbuf);
uint8_t NRF24L01_Check(void);
void NRF24L01_RT_Init(void);
void NRF24L01_Init(void);
void NRF24L01_SendBuf(uint8_t *Buf);
void NRF24L01_Pin_Init(void);
uint8_t NRF24L01_Get_Value_Flag(void);
void NRF24L01_SendString(char *String);
void NRF24L01_SendNum(uint32_t Num);
void NRF24L01_SendNum(uint32_t Num);
uint32_t NRF24L01_GetNum(void);
#endif
nrf24l01_ins,h
#ifndef __nRF24L01_H
#define __nRF24L01_H
/********** NRF24L01引脚定义 ***********/
#define IRQ_Port GPIOB
#define CE_Port GPIOB
#define CSN_Port GPIOA
#define SCK_Port GPIOA
#define MOSI_Port GPIOA
#define MISO_Port GPIOA
#define IRQ_Pin GPIO_Pin_1 //PB1
#define CE_Pin GPIO_Pin_0 //PB0
#define CSN_Pin GPIO_Pin_4 //PA4
#define SCK_Pin GPIO_Pin_5 //PA5
#define MOSI_Pin GPIO_Pin_7 //PA7
#define MISO_Pin GPIO_Pin_6 //PA6
/********** NRF24L01寄存器操作命令 ***********/
#define nRF_READ_REG 0x00
#define nRF_WRITE_REG 0x20
#define RD_RX_PLOAD 0x61
#define WR_TX_PLOAD 0xA0
#define FLUSH_TX 0xE1
#define FLUSH_RX 0xE2
#define REUSE_TX_PL 0xE3
#define NOP 0xFF
/********** NRF24L01寄存器地址 *************/
#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 STATUS 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
/****** STATUS寄存器bit位定义 *******/
#define MAX_TX 0x10 //达到最大发送次数中断
#define TX_OK 0x20 //TX发送完成中断
#define RX_OK 0x40 //接收到数据中断
#endif
ad代码:
#include "stm32f10x.h" // Device header
void AD_Init()
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //开启ADC1内部时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA内部时钟
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //12Mz, 配置ADC分频(*2、*4、6、8)
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入,ADC专属
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //工作模式,独立
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //数据对齐,右对齐
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //外部触发源选择,此处为不使用外部触发,使用软件触发
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //连续或单次模式,ENABLE为连续
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //扫描或单次,ENABLE为扫描
ADC_InitStructure.ADC_NbrOfChannel = 1; //0——16,通道数目
ADC_Init(ADC1, &ADC_InitStructure); //初始化ADC
ADC_Cmd(ADC1, ENABLE); //开启ADC电源
ADC_ResetCalibration(ADC1); //复位校准
while(ADC_GetResetCalibrationStatus(ADC1) == SET); //等待校准完成
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1) == SET);
}
uint16_t AD_GetValue(uint8_t ADC_Channel)
{
ADC_RegularChannelConfig(ADC1, ADC_Channel, 1, ADC_SampleTime_55Cycles5); //ADC_Channel_0,通道0,对应PA0, “1”代表序列1,ADC_SampleTime_55Cycles5代表采样时间55.5*ADCCLK(T)
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //软件触发ADC转换
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); //等待转换完成
return ADC_GetConversionValue(ADC1); //获取转换值
}
#ifndef __AD_H
#define __AD_H
void AD_Init();
uint16_t AD_GetValue(uint8_t ADC_Channel);
#endif
遥杆代码
#include "stm32f10x.h" // Device header
#include "AD.h"
void HW504_Init()
{
AD_Init();
RCC_APB1PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB, GPIO_Pin_12|GPIO_Pin_13);
}
uint8_t HW504_R_SW()
{
GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_13);
}
uint8_t HW504_L_SW()
{
GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12);
}
uint16_t HW504_R_X()
{
uint16_t DataX = AD_GetValue(ADC_Channel_0);
return DataX;
}
uint16_t HW504_R_Y()
{
uint16_t DataY = AD_GetValue(ADC_Channel_1);
return DataY;
}
uint16_t HW504_R_1()
{
uint16_t DataX = AD_GetValue(ADC_Channel_2);
return DataX;
}
uint16_t HW504_R_2()
{
uint16_t DataY = AD_GetValue(ADC_Channel_3);
return DataY;
}
#ifndef __HW504_H
#define __HW504_H
void HW504_Init();
uint8_t HW504_R_SW();
uint8_t HW504_L_SW();
uint16_t HW504_R_X();
uint16_t HW504_R_Y();
uint16_t HW504_R_1();
uint16_t HW504_R_2();
#endif
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "NRF24L01.h"
#include "Key.h"
#include "malloc.h"
#include "string.h"
#include "LED.h"
#include "HW504.h"
uint16_t LX, LY,RX, RY;
uint8_t LSW,RSW;
int main(void)
{
uint8_t Key = 0,Key2=0,Key3=0,Key4=0,Key5=0, TC = 0, RC = 0;
uint8_t RxBuf[1], ShowBuf[1], TxBuf[] = {"a"};
uint8_t RxBuf2[1], ShowBuf2[1], TxBuf2[] = {"b"};
uint8_t RxBuf3[1], ShowBuf3[1], TxBuf3[] = {"c"};
uint8_t RxBuf4[1], ShowBuf4[1], TxBuf4[] = {"d"};
uint8_t RxBuf5[1], ShowBuf5[1], TxBuf5[] = {"e"};
uint8_t RxBuf6[1], ShowBuf6[1], TxBuf6[] = {"f"};
uint8_t RxBuf7[1], ShowBuf7[1], TxBuf7[] = {"g"};
uint8_t RxBuf8[1], ShowBuf8[1], TxBuf8[] = {"h"};
uint8_t RxBuf9[1], ShowBuf9[1], TxBuf9[] = {"i"};
uint8_t RxBuf10[1], ShowBuf10[1], TxBuf10[] = {"z"};
uint8_t RxBuf11[1], ShowBuf11[1], TxBuf11[] = {"q"};
uint8_t RxBuf12[1], ShowBuf12[1], TxBuf12[] = {"r"};
uint8_t RxBuf13[1], ShowBuf13[1], TxBuf13[] = {"e"};
uint8_t RxBuf14[1], ShowBuf14[1], TxBuf14[] = {"t"};
uint8_t RxBuf15[1], ShowBuf15[1], TxBuf15[] = {"w"};
OLED_Init();
Key_Init();
LED_Init();
HW504_Init();
NRF24L01_Init();
my_mem_init(SRAMIN);
OLED_ShowString(1, 1, "LX:");//左遥杆
OLED_ShowString(1, 9, "RX:");//右遥杆
OLED_ShowString(2, 1, "LY:");//左遥杆
OLED_ShowString(2, 9, "RY:");//右遥杆
OLED_ShowString(3, 9, "R:");
OLED_ShowString(3, 1, "T:");
OLED_ShowString(4, 1, "TC:00 RC:00");
while (1)
{
//LED1_ON();
LX = HW504_R_1()/8;
LY = HW504_R_2()/8;
RX = HW504_R_X()/8;
RY = HW504_R_Y()/8;
OLED_ShowNum(1,4, LX, 3);
OLED_ShowNum(1,12, RX, 3);
OLED_ShowNum(2,4, LY, 3);
OLED_ShowNum(2,12, RY, 3);
Key = Key_GetNum();
Key2 = Key_GetNum2();
Key3 = Key_GetNum3();
Key4 = Key_GetNum4();
Key5 = Key_GetNum5();
if(LX<20)//左极限
{
TC ++;
NRF24L01_SendString((char *)TxBuf);
OLED_ShowString(3, 3, (char *)TxBuf);
OLED_ShowNum(4, 4, TC, 2);
}
if(LX>490)//右极限
{
TC ++;
NRF24L01_SendString((char *)TxBuf2);
OLED_ShowString(3, 3, (char *)TxBuf2);
OLED_ShowNum(4, 4, TC, 2);
}
if(LY<20)//下极限
{
TC ++;
NRF24L01_SendString((char *)TxBuf3);
OLED_ShowString(3, 3, (char *)TxBuf3);
OLED_ShowNum(4, 4, TC, 2);
}
if(LY>490)//上极限
{
TC ++;
NRF24L01_SendString((char *)TxBuf4);
OLED_ShowString(3, 3, (char *)TxBuf4);
OLED_ShowNum(4, 4, TC, 2);
}
if(RX<20)
{
TC ++;
NRF24L01_SendString((char *)TxBuf5);
OLED_ShowString(3, 3, (char *)TxBuf5);
OLED_ShowNum(4, 4, TC, 2);
}
if(RX>490)
{
TC ++;
NRF24L01_SendString((char *)TxBuf6);
OLED_ShowString(3, 3, (char *)TxBuf6);
OLED_ShowNum(4, 4, TC, 2);
}
if(RY<20)
{
TC ++;
NRF24L01_SendString((char *)TxBuf7);
OLED_ShowString(3, 3, (char *)TxBuf7);
OLED_ShowNum(4, 4, TC, 2);
}
if(RY>490)
{
TC ++;
NRF24L01_SendString((char *)TxBuf8);
OLED_ShowString(3, 3, (char *)TxBuf8);
OLED_ShowNum(4, 4, TC, 2);
}
if (Key)
{
TC ++;
NRF24L01_SendString((char *)TxBuf9);
OLED_ShowString(3, 3, (char *)TxBuf9);
OLED_ShowNum(4, 4, TC, 2);
/*for (uint16_t i = 0; i < sizeof(TxBuf) - 1; i ++)
{
TxBuf[i] ++;
}*/
}
if (Key2)
{
TC ++;
NRF24L01_SendString((char *)TxBuf10);
OLED_ShowString(3, 3, (char *)TxBuf10);
OLED_ShowNum(4, 4, TC, 2);
/*for (uint16_t i = 0; i < sizeof(TxBuf2) - 1; i ++)
{
TxBuf2[i] ++;
}*/
}
if (Key3)
{
TC ++;
NRF24L01_SendString((char *)TxBuf11);
OLED_ShowString(3, 3, (char *)TxBuf11);
OLED_ShowNum(4, 4, TC, 2);
/*for (uint16_t i = 0; i < sizeof(TxBuf2) - 1; i ++)
{
TxBuf2[i] ++;
}*/
}
if (Key4)
{
TC ++;
NRF24L01_SendString((char *)TxBuf12);
OLED_ShowString(3, 3, (char *)TxBuf12);
OLED_ShowNum(4, 4, TC, 2);
/*for (uint16_t i = 0; i < sizeof(TxBuf2) - 1; i ++)
{
TxBuf2[i] ++;
}*/
}
if (Key5)
{
TC ++;
NRF24L01_SendString((char *)TxBuf13);
OLED_ShowString(3, 3, (char *)TxBuf13);
OLED_ShowNum(4, 4, TC, 2);
/*for (uint16_t i = 0; i < sizeof(TxBuf2) - 1; i ++)
{
TxBuf2[i] ++;
}*/
}
/* if (!NRF24L01_Get_Value_Flag())
{
RC ++;
NRF24L01_GetRxBuf(RxBuf);
for (uint16_t i = 0; i < 32; i ++)
{
ShowBuf[i] = RxBuf[i + 1];
}
//ShowBuf[i]= '\0';
if (strcmp((char *)ShowBuf, "SendingNow!") == 0) // 字符串比较
{
LED1_ON();
}
if (strcmp((char *)ShowBuf, "forward") == 0) // 字符串比较
{
LED1_OFF();
}
OLED_ShowNum(1, 5, RxBuf[0], 2);
OLED_ShowNum(4, 10, RC, 2);
OLED_ShowString(2, 3, (char *)ShowBuf);
}*/
Delay_ms(10);
}
}
六接收端代码
接收端不需要ad和遥杆其他部分保持一致
接收端会比发送端发送的字符多一个“-”原因未知。
解析匹配部分即是字符串比较部分,根据自己的需要进行增删。
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "NRF24L01.h"
#include "Key.h"
#include "malloc.h"
#include "string.h"
#include "LED.h"
int main(void)
{
uint8_t Key = 0, TC = 0, RC = 0;
uint8_t RxBuf[1], ShowBuf[1], TxBuf[] = {"a"};
uint8_t RxBuf2[1], ShowBuf2[1], TxBuf2[] = {"b"};
OLED_Init();
Key_Init();
LED_Init();
NRF24L01_Init();
my_mem_init(SRAMIN);
OLED_ShowString(1, 1, "Len:");
OLED_ShowString(2, 1, "R:");
OLED_ShowString(3, 1, "T:");
OLED_ShowString(4, 1, "TC:00 RC:00");
while (1)
{
//LED1_ON();
Key = Key_GetNum();
if (Key)
{
TC ++;
NRF24L01_SendString((char *)TxBuf2);
OLED_ShowString(3, 3, (char *)TxBuf2);
OLED_ShowNum(4, 4, TC, 2);
for (uint16_t i = 0; i < sizeof(TxBuf2) - 1; i ++)
{
TxBuf2[i] ++;
}
}
if (!NRF24L01_Get_Value_Flag())
{
RC ++;
NRF24L01_GetRxBuf(RxBuf);
for (uint16_t i = 0; i < 1; i ++)
{
ShowBuf[i] = RxBuf[i + 1];
}
//ShowBuf[i]= '\0';
if (strcmp((char *)ShowBuf, "a-") == 0) // 字符串比较
{
LED1_ON();
}
if (strcmp((char *)ShowBuf, "b-") == 0) // 字符串比较
{
LED1_OFF();
}
OLED_ShowNum(1, 5, RxBuf[0], 2);
OLED_ShowNum(4, 10, RC, 2);
OLED_ShowString(2, 3, (char *)ShowBuf);
}
Delay_ms(10);
}
}
总代码
链接:https://pan.baidu.com/s/1zNs5V7AUEIYOCsQJ9v6Bgw
提取码:fufu
版权归原作者 时风 所有, 如有侵权,请联系我们删除。