STM32蓝牙遥控小车

文章目录

  • 前言
  • 一、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://blog.csdn.net/m0_65106089/article/details/129017189

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请联系站长进行投诉反馈,一经查实,立即删除!

h
上一篇 2023年09月23日 22:35
数学建模之插值法
下一篇 2023年09月23日 22:40