关注分享主机优惠活动
国内外VPS云服务器

STM32遥控车下位机及硬件连接部分(Keil MDK5平台上C++编程)

总结:同时该模块包含小车加减速和小车转向功能。 在串口中断处理程序中,你设置的主机命令是以字节为单位的,所以当串口检测到接收到一个字节时,立即判断当前命令对应的动作。 命令与小车动作的对应关系请参考上位机的编写部分。

STM32蓝牙控制车介绍一、硬件概述1、L298N电机驱动模块2、JDY-31蓝牙模块3、电源配置4、单片机2、单片机程序概述1. main.c 文件 2. bluetooth.c 文件 3. motor.c 文件 4. speeder.c 文件 5. uart.c 文件 3. 概述

简介

暑假很无聊,。我手头还有另一个闲置的微控制器。 单片机被忽视了很长一段时间,只是想搭建一个遥控车,复习一下单片机的嵌入式编程。 这个遥控车项目参考了CSDN博主叫我李大帅的一篇文章。 STM32智能遥控车,很详细- 附带下载可以直接使用,双电源速度快。 。 在原文的基础上,我们添加了计算机控制并创建了定制的 Android 软件来控制汽车。 注:

本文所有代码均开源,可供学习。 源代码在这里:百度云盘链接(提取码:uh66)这篇文章是关于无线电遥控车的下位机部分。 PC上位机部分的实现请点击此处。 点击这里 1.硬件概述

最终实物图:

硬件配置和博主李大帅的差不多。 两个L298N电机驱动模块用于驱动四个电机,一个STM32开发板用于控制这两个电机驱动模块,一个透传模块通过JDY-31蓝牙连接到您的手机或电脑进行通信。 整体使用两个独立的电源分别为微控制器和L298N供电。

1. L298N电机驱动模块

该模块用于驱动电机一台L298N可以驱动两个电机。 有关 L298N 模块的说明,请观看视频 L298N 电机驱动模块、电机正反转和电机速度调节。 下图是L298N与单片机的连接示意图。

左L298N:右L298N 说明:

电机驱动模块L298N位于遥控车两侧。 左边的L298N控制左边的两个电机,右边的L298N控制右边的两个电机。 发动机。 微控制器PD12-PD15以PWM输出的形式控制电机的转速,PE7-PE14控制两个电机为一组的四个电机的转向。 2、JDY-31蓝牙模块

JDY-31蓝牙模块是透传模块。 这意味着您在使用时不必担心蓝牙协议的细节。 连接后可直接作为串口使用。 模块的RXD和TXD连接到单片机的UART接口。 连接图如下所示。 注意:连接蓝牙模块时,需要将JDY-31的RX接口连接到单片机的TX接口(我的单片机的RX采用P9复用)。 同时将JDY-31的TX接口连接到单片机的RX接口(这里RX采用P10复用)。 JDY-31的STATE接口与微控制器连接,用于检测蓝牙连接状态。 如果JDY-31与主机有蓝牙连接,则STATE置为高电平,否则为低电平。 3、电源配置

采用了两个独立的电源。 四节干电池产生 6.5 V 电压为微控制器供电。 我购买的单片机有一个DCDC降压芯片,可以将6.5V降压到3.3V,供单片机使用。 第二个独立电源由 12V 锂电池提供,为 L298N 供电。

6.5V供电:12V供电:

4、单片机

使用的单片机型号为STM32F407VET6。 这不是很重要。 您还可以使用其他微控制器型号来查找相应的固件库。 完成这个功能。

2、单片机程序介绍

接下来是程序中主要程序的介绍。 详细代码请参考百度网盘:【如下下载地址]。

程序结构目录如下:

1. main.c 文件

代码片段:

int main(void){ // 设置外部中断的优先级组 NVIC_PriorityGroupConfig (NVIC_PriorityGroup_2); //初始化各部分 uart_init (9600); lay_init(168);LED_Init();Bluetooth_Init();MTR_GPIOInit();LED0 = 1;//主程序 while(1){if(BLUTOOTH_STATE){ LED0 = 0;lay_ms(100 ); 1;delay_ms(100); }else {LED0 = 0;MTR_CarBrakeAll();}}}

代码解释:

main函数主要执行各个硬件部分,初始化JDY-31蓝牙和主机主程序。 如果成功连接到主机,LED0将持续闪烁。 如果没有连接主机,LED0 保持点亮。 2. bluetooth.c 文件

代码片段:

#include "bluetooth.h"#include "lay.h" void Bluetooth_Init(void){ GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);//GPIOE 时钟Enable GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //STATE连接引脚PE0 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; //普通输入模式tructure.GPIO_Speed = GPIO_Speed_100MHz;//100M GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//下拉 GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE}

说明:

该模块用于检测连接用于蓝牙状态。 因此,Bluetooth_Init函数只需要初始化PE0即可。 同时在bluetooth.h头文件中定义了变量BLUTOOTH_STATE来查询蓝牙是否连接,如下所示。 #define BLUTOOTH_STATE GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_0)//PE0 3.motor.c 文件

代码片段:

#include "motor.h"//Brake void MTR_CarBrakeAll(void){MTR1_BRAKE;MTR2_BRAKE;MTR3_BRAKE; MTR4_BRAKE;}//前进 void MTR_CarGo(void){MTR1_ROTA_F;MTR2_ROTA_F;MTR3_ROTA_F;MTR4_ROTA_F;}//后退 void MTR_CarBack(void){MTR1_ROTA_B;MTR2_ROTA_B;MTR3_ROTA_B;MTR4_ROTA_B;}//顺时针转动 void MTR_CarCW (无效){MTR1_ROTA_F ;MTR2_ROTA_F;MTR3_ROTA_B;MTR4_ROTA_B;}//逆时针转动 void MTR_CarCCW(void) ){MTR 1_ROTA_B;MTR2_ROTA_B ;MTR3_ROTA_F ;MTR4_ROTA_F;}//电机驱动控制初始化 void MTR_GPIOInit(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_AHB1PeriphClockCmd(MTR1_GPIO_CLK|MTR2_GPIO_CLK|MTR3_GPIO_CLK|MTR4_GPIO_CLK,ENABLE);//时钟 GPIO_InitStructure.GPIO_Speed GPIO_Speed_100MHz;GPIO_InitStructure.GPIO_OType = GPIO _ OType_PP;GPIO_InitStru cture.GPIO_PuPd = GPIO_PuPd_NOPULL;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//推- // 电机1GPIO_InitStructure.GPIO_Pin = MTR1_GPIO_PIN;GPIO_Init(MTR1_GPIO_PORT, &GPIO_InitStructure);//电机2GPIO_InitStructure.GPIO_Pin = MTR2_GPIO_PIN;GPIO_Init(MTR2_GPIO_PORT, &GPIO_InitStructure);//电机3GPIO_Init.GPIO_ Pin = MTR3_GPIO_ PIN;GPIO_Init(MTR3_GPIO_PORT, &GPIO_InitStructure ) ;//电机4GPIO_InitStructure .GPIO_Pin = MTR4_GPIO_PIN;GPIO_Init(MTR4_GPIO_PORT, &GPIO_InitStructure);//汽车刹车 MTR_CarBrakeAll();}

说明:

该模块主要控制PE7-PE14执行刹车功能实现向前、向后和旋转。 例如,MTR1_ROTA_F 为 2。每个引脚分别分配值 1 和 0,但 MTR1_BRAKE 为两个引脚分配值 0。 4.speeder.c文件

代码片段:

#include "sys.h"#include "speeder.h"u16 SPEED_LEVEL = SPEED_LEVEL1;u8 CAR_STATE = STRAIGHT_STATE;//GPIO初始化 static void SPEEDER_GPIO_Init(void ) {GPIO_InitTypeDef GPIO_InitStructure;RCC_AHB1PeriphClockCmd(SPEEDER_GPIO_CLK,ENABLE);//时钟GPIO_InitStructure.GPIO_Speed GPIO_Speed_100MHz;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_PuPd = GPIO_P u Pd_DOWN;GPIO_InitS tructure.GPIO_Mode = GPIO_Mode_AF;//推挽输出//初始化GPIO该引脚将被重复使用并绑定到相应的定时器。 GPIO_InitStructure.GPIO_Pin = SPEEDER_GPIO_PIN;GPIO_Init(SPEEDER_GPIO_PORT, &GPIO_InitStructure);GPIO_PinAFConfig(SPEEDER_GPIO_PORT,GPIO_PinSource12,GPIO_AF_TIM4);GPIO_PinAFConfig(SPEEDER_GPIO_PORT,GPIO_PinSource13,GPIO_AF_TIM) 4) ;GPIO_PinAFConfig(SPEEDER_ GPIO_端口,GPIO_PinSource14,GPIO_AF_TIM4);GPIO_PinAFConfig(SPEEDER_GPIO_PORT,GPIO_PinSource15,GPIO_AF_TIM4);}//定时器初始化 static void SPEEDER_TIM_Init(void){TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_OCInitTypeDeflock TIM_OCInitStructure;RCC_APB1PeriphC GENERAL_TI );/*---[ k4 ]---------------- 时间BASE 结构初始化 --------------[k4 ] [ k4 ]---------*/TIM_TimeBaseStructure.TIM_Period=GENERAL_TIM_Period;//自动重载值 TIM_TimeBaseStructure.TIM_Prescaler= GENERAL_TIM_Prescaler ; //预分频器value TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上计数 TIM_TimeBaseStructure.TIM_RepetitionCounter=0;//初始化定时器 TIM_TimeBaseInit(GENERAL_TIM, &TIM_TimeBaseStru)图像);/*--------------- ----- 初始化输出比较结构 ---------[ k4] [ k4]--------*/TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; // 如果 PWM2 模式计数器值大于 occr,则有效 设置信号 TIM_OCInitStructure来输出。 TIM_OutputState = TIM_OutputState_Enable;//输出使能 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//输出通道电平极性设置使能信号为高电平 TIM_OCInitStructure.TIM_Pulse = SPEED_LEVEL;//比较值:0TIM_OC1Init(GENERAL_TIM, &TIM_OCInitS structure ); //输出比较频道1TIM_OC1PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable);TIM_OCInitStructure.TIM_Pulse = SPEED_LEVEL;TIM_OC2Init(GENERAL_TIM, &TIM_OCInitStructure);//输出比较通道 2TIM_OC2PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable);TI M_OCInit Structure.TI M_Pulse = SPEED_LEVEL;TIM_OC3Init(GENERAL_TIM,&TIM_OCInitStructure);//输出比较通道 3TIM_OC3PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable);TIM_OCInitStructure.TIM_Pulse = SPEED_LEVEL;TIM_OC4Init(GENERAL_TIM, &TIM_OCInitStructure);//输出比较通道 4TIM_OC4PreloadConfig(GENERAL_TIM), T IM_OCPreload_Enable);TIM_ARRPreloadConfig(GENERAL_TIM,ENABLE);TIM_Cmd( GENERAL_TIM , ENABLE);//使能定时器}//全部使能 void SPEEDER_Init(void){SPEEDER_GPIO_Init();SPEEDER_TIM_Init();CAR_STATE = STRAIGHT_STATE;}//右转 void SET_RIGHT_TURN(void){CAR_STATE = RIGHT_STATE ;TIM_SetCompare1(GENERAL_TIM) , SPEED_LEVEL);TIM_SetCompare2(GENERAL_TIM,SPEED_LEVEL);TIM_SetCompare3(GENERAL_TIM,0);TIM_SetCompare4(GENERAL_TIM,0);}//左转 void SET_LEFT_TURN(void){CAR_STATE = E;TIM_SetCompare1(GENERAL_TIM,0 );TIM_SetCompare 2(一般_TIM ,0);TIM_SetCompare3(GENERAL_TIM,SPEED_LEVEL);TIM_SetCompare4(GENERAL_TIM,SPEED_LEVEL);TIM_SetCompare4(GENERAL_TIM,SPEED_LEVEL)RAL_TIM,SPEED_LEVEL);}//无效RESET_DIRECTION(void){CAR_STATE = STRAIGHT_STATE;TIM_SetCompare1(GENERAL_TIM,SPEED_LEVEL);TIM_SetCompare2(GENERAL_TIM,SPEED_LEVEL);TIM_SetCompare3(GENERAL_TIM,SPEED_LEVEL);TIM_Set Compare4(GEN ERAL_TIM,SPEED_LEVEL) ;}/ / 根据当前车况将当前速度级别分配给相应的定时器。 static void RESET_SPEED_LEVEL(void){switch(CAR_STATE){case STRAIGHT_STATE:RESET_DIRECTION();break;case LEFT_STATE:SET_LEFT_TURN();break;case RIGHT_STATE:SET_RIGHT_TURN();break;}}//速度变化:加速度 void SPEED_UP( void ){开关(SPEED_LEVEL){case SPEED_LEVEL0:SPEED_LEVEL = SPEED_LEVEL1;break;case SPEED_LEVEL1:SPEED_LEVEL = SPEED_LEVEL2;break;case SPEED_LEVEL2:SPEED_LEVEL = SPEED_LEVEL3;break;case SPEED_LEVEL3:SPEED_LE VEL = SPEED _LEVEL3;break;}RESET_SPEED _LEVEL ( ); }//速度:减速度 void SPEED_DOWN(void){switch(SPEED_LEVEL){case SPEED_LEVEL0:SPEED_LEVEL = SPEED_LEVEL0;break;case SPEED_LEVEL1:SPEED_LEVEL = SPEED_LEVEL0;break;case SPEED_LEVEL2:SPEED_LEVEL = SPEED_LEVEL1;break;case SPEED_LEVEL3:SPEED_LEVEL = SPEED_LEVEL2;break;}RESET_SPEED_LEVEL();}

说明:

这个模块主要实现PD12-PD15的PWM输出,实现控制小车速度的功能。 同时该模块还包括汽车加减速和汽车转向功能。 在加速函数(减速函数)中,首先使用switch语句检查小车当前的速度状态,然后将SPEED_LEVEL更改为相应的较高(较低)速度档位,然后通过RESET_SPEED_LEVEL()函数更改使用更改的速度。 速度齿轮。 该位值被分配给相应的定时器比较值。 5. uart.c文件

代码部分:

void USART1_IRQHandler(void) //串口1中断服务程序 {uint8_t CMD = 0;//收到命令 if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET ){USART_ClearFlag(USART1,USART_FLAG_RXNE);USART_ClearITPendingBit(USART1,USART_IT_RXNE);CMD = USART_ReceiveData(USART1);//读字节开关(CMD){case 0x00:RESET_DIRECTION();MTR_CarGo();printf("forward /r/ n");Break;案例 0x01:RESET_DIRECTION();MTR_CarBack();printf("返回/r/n");break;case 0x02:SET_RIGHT_TURN();printf("右转/r/n");break;case 0x03:SET_LEFT_TURN();printf("左转/ r/n ");break;case 0x04:MTR_CarCW();printf("右 CW/r/n");break;case 0x05:MTR_CarCCW();printf("左 CW/r/n");break;案例 0x06: //==================SPEED_UP();printf("加速/r/n");Break;案例 0x07://==== = ==============减速SPEED_DOWN();printf("减速/r/n");break;case 0x0a:RESET_DIRECTION();printf("重置直线/r/ n " ") ;break;case 0xff:MTR_CarBrakeAll();printf("stop/r/n");break;case 0x1f://================= 测试connection printf("连接成功");break;}}}

说明:

该文件主要包含uart串口模块的初始化部分和串口的串口中断处理程序的写入部分初始化部分,为了方便,我使用了卖家提供的ucos初始化代码。在串口中断处理程序中,我设置的命令是以字节为单位的,所以当它检测到当前命令的接收时,我无法理解细节。 ,立即判断当前命令对应的动作。命令与小车动作的映射请参考上位机编写部分,可移植到单片机。源码可在百度云盘获取。点击这里(提取码:uh66)这篇文章是关于无线电遥控车的下位机部分。 计算机部分在PC上的实现参见这里。 单击此处查看全文说明。 如果您有任何疑问,可以发表评论。 我会时不时地检查一下。

未经允许不得转载:主机频道 » STM32遥控车下位机及硬件连接部分(Keil MDK5平台上C++编程)

评论 抢沙发

评论前必须登录!