
专业版
2.4Ghz遥控小车
714
0
0
1
简介
该项目使用51单片机和STM32F103单片机分别作为小车主控和遥控器的主控,搭载NRF24L01、SG90舵机、N20减速马达等模块,能够遥控小车行进。
简介:该项目使用51单片机和STM32F103单片机分别作为小车主控和遥控器的主控,搭载NRF24L01、SG90舵机、N20减速马达等模块,能够遥控小车行进。开源协议
:GPL 3.0
创建时间:2025-09-06 12:45:24更新时间:2025-09-08 10:23:05
描述
视频链接:
项目简介
该项目使用51单片机和STM32F103单片机分别作为小车主控和遥控器的主控,搭载NRFL24L01、SG90舵机、N20减速马达等模块,能够遥控小车行进。
项目参数
- 本设计采用51单片机作为接收板的主控。
- 本设计采用NRF24L01作为2.4GHZ通信模块。
- 通过舵机和减速马达控制小车行进。
原理解析(硬件说明)
本项目由以下部分组成,电源部分、主控部分、通信部分、运动控制部分,本项目主要是接收遥控器发来的指令信号进行处理,进而控制小车行进。
电源电路:
采用7.4V的锂离子电池通过XH2.54接头供电,板子上有AM1117降压模块,能够把电压转化为5V。

舵机和减速电机:
通过使用SG90舵机和N20减速电机分别控制小车转向和行进,舵机可以直接用单片机的pwm信号驱动,而减速电机这需要用专门的驱动芯片进行驱动

软件代码
接收端代码
#include
#define uchar unsigned char
#define TX_ADR_WIDTH 5 // 5 字节宽度的发送 / 接收地址
#define TX_PLOAD_WIDTH 4 // 数据通道有效数据宽度
uchar code TX_ADDRESS[TX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x01}; // 定义一个静态发送地址
uchar RX_BUF[TX_PLOAD_WIDTH];
uchar TX_BUF[TX_PLOAD_WIDTH];
uchar flag;
uchar DATA = 0x01;
uchar bdata sta;
sbit RX_DR = sta^6;
sbit TX_DS = sta^5;
sbit MAX_RT = sta^4;
sbit MOTOR_A0=P2^6;
sbit MOTOR_A1=P2^5;
sbit Sevro_moto_pwm=P2^0; // 舵机信号线(橙色)
uchar pwm_val = 0;// 变 量 定 义
uchar push_val = 12;//舵 机 归 中 , 产 生 约 ,1.5MS 信 号
void init_io()
{
CE = 0; // 待机
CSN = 1; // SPI禁止
SCK = 0; // SPI时钟置低
IRQ = 1; // 中断复位
}
void delay_ms(uchar x)
{
uchar i, j;
i = 0;
for(i=0; i0;c--)
for(b=50;b>0;b--)
for(a=2;a>0;a--);
}
//舵机方向控制
void time1()interrupt 3 using 2
{
TH1=(65536-100)/256; //100US定时
TL1=(65536-100)%256;
pwm_val++;
if(pwm_val<=push_val)
Sevro_moto_pwm=1; //PWM信号高电平时间
else
Sevro_moto_pwm=0; //PWM信号低电平时间
if(pwm_val>=100)
pwm_val=0;
}
void time0()
{
TMOD=0X10;
TH1=(65536-100)/256; //100US定时
TL1=(65536-100)%256;
TR1= 1;
ET1= 1;
EA = 1;
push_val=12; //舵机归中,机器执行指令有周期,所以PWM信号有误差
delay1ms(1000); //延时1s让舵机转到其位置,停留一下
}
void main()
{
uchar sta;
init_io(); // 初始化I0
time0();
delay_ms(100);
RX_Mode(); // 设置为接收模式
push_val=12;
while(1)
{
sta = SPI_Read(STATUS); // 读状态寄存器
if((sta & 0x40)!=0) //判断是否接受到数据
{
SPI_Read_Buf(RD_RX_PLOAD, RX_BUF, TX_PLOAD_WIDTH); // RXD FIFO读出数据
}
switch(RX_BUF[0]) //控制舵机和马达根据指令做出相应的运动
{
case 0x23:
MOTOR_A0=1,MOTOR_A1=0; push_val=12;
break;
case 0x24:
MOTOR_A0=0,MOTOR_A1=1; push_val=12;
break;
case 0x25:
MOTOR_A0=0,MOTOR_A1=0; push_val=7;
break;
case 0x26:
MOTOR_A0=0,MOTOR_A1=0;push_val=18;
break;
case 0x27:
MOTOR_A0=1,MOTOR_A1=0; push_val=7;
break;
case 0x28:
MOTOR_A0=1,MOTOR_A1=0; push_val=18;
break;
case 0x29:
MOTOR_A0=0,MOTOR_A1=1; push_val=7;
break;
case 0x30:
MOTOR_A0=0,MOTOR_A1=1; push_val=18;
break;
case 0X31:
MOTOR_A0=0,MOTOR_A1=0; push_val=12;
break;
default:
break;
}
RX_BUF[0]=0x00;
SPI_RW_Reg(FLUSH_RX,0xff);
SPI_RW_Reg(WRITE_REG + STATUS, sta);
delay_ms(100);
}
}
发送端代码
#include "stm32f10x.h"
#include "API.h"
#include "sbit.h"
#include "Delay.h"
#define uchar unsigned char
#define TX_ADR_WIDTH 5 // 5 字节宽度的发送 / 接收地址
#define TX_PLOAD_WIDTH 4 // 数据通道有效数据宽度
uchar TX_ADDRESS[TX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x01}; // 定义一个静态发送地址
uchar RX_BUF[TX_PLOAD_WIDTH];
uchar TX_BUF1[TX_PLOAD_WIDTH]={0x23,0x23,0x23,0x23};
uchar TX_BUF2[TX_PLOAD_WIDTH]={0x24,0x24,0x24,0x24};
uchar TX_BUF3[TX_PLOAD_WIDTH]={0x25,0x25,0x25,0x25};
uchar TX_BUF4[TX_PLOAD_WIDTH]={0x26,0x26,0x26,0x26};
uchar TX_BUF5[TX_PLOAD_WIDTH]={0x27,0x27,0x27,0x27};
uchar TX_BUF6[TX_PLOAD_WIDTH]={0x28,0x28,0x28,0x28};
uchar TX_BUF7[TX_PLOAD_WIDTH]={0x29,0x29,0x29,0x29};
uchar TX_BUF8[TX_PLOAD_WIDTH]={0x30,0x30,0x30,0x30};
uchar TX_BUF9[TX_PLOAD_WIDTH]={0x31,0x31,0x31,0x31};
uchar flag;
uchar DATA = 0x01;
uchar sta;
void init()
{
GPIO_InitTypeDef GPIO_InitStructure;//定义一个结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //使能时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9|GPIO_Pin_8|GPIO_Pin_7|GPIO_Pin_6|GPIO_Pin_5|GPIO_Pin_4 ; //要用到的引脚
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //电平翻转速度50MHZ
GPIO_Init(GPIOB,&GPIO_InitStructure); //初始化引脚
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11|GPIO_Pin_10|GPIO_Pin_1|GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
GPIO_Init(GPIOB ,&GPIO_InitStructure);
}
void init_io(void)
{
CE = 0; // 待机
CSN = 1; // SPI禁止
SCK = 0; // SPI时钟置低
IRQ = 1; // 中断复位
MISO=1;
}
uchar SPI_RW(uchar byte)
{
uchar i;
for(i=0; i<8; i++) // 循环8次
{
MOSI = (byte & 0x80)>>7; //byte最高位输出到MOSI
byte=(byte)<< 1; //低一位移位到最高位
SCK = 1; //拉高SCK,nRF24L01从MOSI读入1位数据,同时从MISO输出1位数据
delay_us(10);
byte |= MISO; //读MISO到byte最低位
SCK = 0; // SCK置低
delay_us(10);
}
return(byte); // 返回读出的一字节
}
uchar SPI_RW_Reg(uchar reg, uchar value)
{
uchar status;
CSN = 0; // CSN置低,开始传输数据
delay_us(10);
status = SPI_RW(reg); // 选择寄存器,同时返回状态字
SPI_RW(value); // 然后写数据到该寄存器
CSN = 1; //CSN拉高,结束数据传输
delay_us(10);
return(status); //返回状态寄存器
}
uchar SPI_Read(uchar reg)
{
uchar reg_val;
CSN = 0; // CSN置低,开始传输数据
delay_us(10);
SPI_RW(reg); //选择寄存器
reg_val = SPI_RW(0); // 然后从该寄存器读数据
CSN = 1; // CSN拉高,结束数据传输
delay_us(10);
return(reg_val); //返回寄存器数据
}
uchar SPI_Read_Buf(uchar reg, uchar * pBuf, uchar bytes)
{
uchar status, i;
CSN = 0; // CSN置低,开始传输数据
delay_us(10);
status = SPI_RW(reg); // 选择寄存器,同时返回状态字
for(i=0; i
设计图
未生成预览图,请在编辑器重新保存一次BOM
暂无BOM
克隆工程添加到专辑
0
0
分享
侵权投诉
工程成员
知识产权声明&复刻说明
本项目为开源硬件项目,其相关的知识产权归创作者所有。创作者在本平台上传该硬件项目仅供平台用户用于学习交流及研究,不包括任何商业性使用,请勿用于商业售卖或其他盈利性的用途;如您认为本项目涉嫌侵犯了您的相关权益,请点击上方“侵权投诉”按钮,我们将按照嘉立创《侵权投诉与申诉规则》进行处理。
请在进行项目复刻时自行验证电路的可行性,并自行辨别该项目是否对您适用。您对复刻项目的任何后果负责,无论何种情况,本平台将不对您在复刻项目时,遇到的任何因开源项目电路设计问题所导致的直接、间接等损害负责。


评论