文章目录
- 前言
- 一、STM32小车效果图
-
二、硬件设计
- 1.电机驱动对比
- 2.蓝牙模块
- 3.电机
- 三、部分代码
- 总结
前言
STM32小车一直以来都还是众多STM32爱好者的入门设计,门槛不高,值得玩一下。
一、STM32小车效果图
这是刚开始弄的印度风的小车,丑不拉几。
这个小车结构是:STM32C8T6为主控,12V电源,还有电源模块是12V—>5V、3.3V的,HC-05蓝牙模块,L298N电机驱动模块*2,亚克力板和4个电机加轮子。
这个小车是不满意上面那玩意改的,画了一个板子,主控依旧是STM32C8T6,有变动的是电机驱动模块改了,现在用的是DRV8833。外加了一个OLED作为人机交互页面,超声波测距,两个RGB转向。
二、硬件设计
1.电机驱动对比
L298N :集成双H桥、元器件多、体积大、发热比较明显
L298N有两个使能控制引脚可分别控制两个H桥是否使能。
DRV8833 :集成双H桥、体积小、发热情况良好、可以同时驱动两个直流电机或一个步进电机。
2.蓝牙模块
遥控小车用的是蓝牙透传,安卓手机的蓝牙app——传送门
蓝牙模块的前期调试,可用usb转ttl模块连接蓝牙模块,RXD-TX TXD-RX VCC-VCC GND-GND。
如果上电了,蓝牙指示灯默认是2s闪烁就是进入了AT指令模式,可通过上位机向蓝牙发送指令。如果上电不是AT指令模式,就摁着蓝牙的按键再上电。
AT指令集(建议改名字就好,密码不要改)
AT+NAME=Bluetooth-Master 蓝牙主机名称为Bluetooth-Master
AT+ROLE=1 蓝牙模式为主模式
AT+CMODE=0 蓝牙连接模式为任意地址连接模式
AT+PSWD=1234 蓝牙配对密码为1234
AT+UART=9600,0,0 蓝牙通信串口波特率为9600,停止位1位,无校验位
AT+RMAAD 清空配对列表
3.电机
实测:电机的比例越小跑得越快!
三、部分代码
电机控制
#include "bsp_usart.h"
#include "Delay.h"
#include "led.h"static void EXTI_NVIC_Config(void) //中断初始化
{
NVIC_InitTypeDef NVIC_InitStructure; //就用到一个中断,所以配置随便选
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //嵌套向量中断控制器的选择
NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ; //配置USART为中断源
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //子优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中断
NVIC_Init(&NVIC_InitStructure); //初始化配置NVIC
}static void USART_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
//配置中断优先级
EXTI_NVIC_Config();
/********* 初始化GPIO **********/
/* 开启串口GPIO的时钟 */
DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK,ENABLE);
/* 打开串口外设的时钟 */
DEBUG_USART_APBxClKCmd(DEBUG_USART_CLK,ENABLE);
/* 将USART Tx 的GPIO配置为推挽复用模式 */
GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN; //配置GPIO
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //推挽复用模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //配置速度
GPIO_Init(DEBUG_USART_TX_GPIO_POPT,&GPIO_InitStructure); //调用库函数 初始化GPIO/* 将USART Rx 的GPIO配置为浮空输入模式 */
GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN; //配置GPIO
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //推挽复用模式
GPIO_Init(DEBUG_USART_RX_GPIO_POPT,&GPIO_InitStructure); //调用库函数 初始化GPIO
/********* 配置串口的工作参数 **********/USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE; //配置波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //配置 针数据字长
USART_InitStructure.USART_StopBits = USART_StopBits_1; //配置停止位
USART_InitStructure.USART_Parity = USART_Parity_No; //配置校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//配置硬件流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//配置工作模式,收发一起
USART_Init(DEBUG_USARTx, &USART_InitStructure); //完成串口的初始化配置
USART_ITConfig(DEBUG_USARTx,USART_IT_RXNE,ENABLE);//使能串口接收中断USART_Cmd(DEBUG_USARTx,ENABLE);//使能串口
}void BASIC_USART_INIT(void) //初始化函数
{
USART_Config();
EXTI_NVIC_Config();
}void USART1_IRQHandler(void) //串口中断服务函数
{
u8 Rec;
if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)
{
Rec = USART_ReceiveData(USART1); //接收蓝牙传输过来的数据
switch(Rec)
{
case 0x05: //后退
TIM_SetCompare1(TIM4,90); //设置TIM4捕获比较寄存器值(控制速度)
TIM_SetCompare2(TIM4,0);
TIM_SetCompare3(TIM4,90);
TIM_SetCompare4(TIM4,0);
LED_L_G_OFF;
LED_R_G_OFF;
break;
case 0x03: //左转
TIM_SetCompare1(TIM4,0);
TIM_SetCompare2(TIM4,90);
TIM_SetCompare3(TIM4,90);
TIM_SetCompare4(TIM4,0);
LED_R_G_OFF;
LED_L_G_ON;
break;
case 0x04: //右转
TIM_SetCompare1(TIM4,90);
TIM_SetCompare2(TIM4,0);
TIM_SetCompare3(TIM4,0);
TIM_SetCompare4(TIM4,90);
LED_L_G_OFF;
LED_R_G_ON;
break;
case 0x02: //前进
TIM_SetCompare1(TIM4,0);
TIM_SetCompare2(TIM4,90);
TIM_SetCompare3(TIM4,0);
TIM_SetCompare4(TIM4,90);
LED_L_G_OFF;
LED_R_G_OFF;
break;
case 0x06: //停止
TIM_SetCompare1(TIM4,0);
TIM_SetCompare2(TIM4,0);
TIM_SetCompare3(TIM4,0);
TIM_SetCompare4(TIM4,0);
LED_L_G_OFF;
LED_R_G_OFF;
break;
default: //停止
TIM_SetCompare1(TIM4,0);
TIM_SetCompare2(TIM4,0);
TIM_SetCompare3(TIM4,0);
TIM_SetCompare4(TIM4,0);
break;
}
}
}
超声波测距
#include "SR05.h"
void HC_SR04_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //上拉输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period = 999;
TIM_TimeBaseInitStructure.TIM_Prescaler = 71;
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
TIM_ClearFlag(TIM3, TIM_FLAG_Update);
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
TIM_Cmd(TIM3,DISABLE);
}
static void CloseTimer(void)
{
TIM_Cmd(TIM3,DISABLE);
}static void OpenTimer(void)
{
TIM_SetCounter(TIM3,0);
TIM_Cmd(TIM3,ENABLE);
}uint32_t GetHC_Timer(void)
{
uint32_t temp=0;
temp = TIM_GetCounter(TIM3);//获取定时器采集的时间
TIM_SetCounter(TIM3,0); //将计数器清0
Delay_ms(20);
return temp;
}float Hcsr04GetLength(void)
{
uint32_t result = 0 ;
GPIO_SetBits(GPIOA,GPIO_Pin_5);//发送长达10us的高电平
Delay_us(20);
GPIO_ResetBits(GPIOA,GPIO_Pin_5);
while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6)==RESET);
OpenTimer();
while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6)==SET);
CloseTimer();
result = GetHC_Timer();
return result;
}文章来源:https://uudwc.com/A/V6zOp
总结
欢迎大家指正交流学习。文章来源地址https://uudwc.com/A/V6zOp