STM32单片机智能小车一PWM方式实现小车调速和转向

news2025/1/13 7:49:42

目录

1. 电机模块开发

2. 让小车动起来

3. 串口控制小车方向

4. 如何进行小车PWM调速

5. PWM方式实现小车转向


1. 电机模块开发

L9110s概述

接通VCC,GND 模块电源指示灯亮, 以下资料来源官方,具体根据实际调试

IA1输入高电平,IA1输入低电平,【OA1 OB1】电机正转;

IA1输入低电平,IA1输入高电平,【OA1 OB1】电机反转;

IA2输入高电平,IA2输入低电平,【OA2 OB2】电机正转;

IA2输入低电平,IA2输入高电平,【OA2 OB2】电机反转;

接线参考:

B-1A -- PA0

B-1B -- PB1

A-1A -- PA1

A-1B -- PB10 

2. 让小车动起来

代码实现:

motor.c

#include "motor.h"
void goForward(void)
{
    // 左轮
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET);
    // 右轮
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
}
void goBack(void)
{
    // 左轮
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET);
    // 右轮
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);
}
void goLeft(void)
{
    // 左轮
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET);
    // 右轮
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
}
void goRight(void)
{
    // 左轮
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET);
    // 右轮
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
}
void stop(void)
{
    // 左轮
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET);
    // 右轮
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
}

motor.h

#ifndef __MOTOR_H__
#define __MOTOR_H__
#include "main.h"
void goForward(void);
void goBack(void);
void goLeft(void);
void goRight(void);
void stop(void);
#endif

main.c

#include "motor.h"

//main函数的while循环部分:
while (1)
{
    goForward();
    HAL_Delay(1000);
    goBack();
    HAL_Delay(1000);
    goLeft();
    HAL_Delay(1000);
    goRight();
    HAL_Delay(1000);
    stop();
    HAL_Delay(1000);
}

3. 串口控制小车方向

  • 串口分文件编程进行代码整合——通过现象来改代码
  • 接入蓝牙模块,通过蓝牙控制小车
  • 添加点动控制,如果APP支持按下一直发数据,松开就停止发数据(蓝牙调试助手的自定义按键不 能实现),就能实现前进按键按下后小车一直往前走的功能

代码实现:

usart.c

#include "usart.h"

#include "string.h"
#include "stdio.h"
#include "motor.h"

//串口接收缓存(1字节)
uint8_t buf=0;

//定义最大接收字节数 200,可根据需求调整
#define UART1_REC_LEN 200

// 接收缓冲, 串口接收到的数据放在这个数组里,最大UART1_REC_LEN个字节
uint8_t UART1_RX_Buffer[UART1_REC_LEN];

//  接收状态
//  bit15,      接收完成标志
//  bit14,      接收到0x0d
//  bit13~0,    接收到的有效字节数目
uint16_t UART1_RX_STA=0;

#define SIZE 12

char buffer[SIZE];

// 接收完成回调函数,收到一个数据后,在这里处理
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	// 判断中断是由哪个串口触发的
	if(huart->Instance == USART1)
	{
		// 判断接收是否完成(UART1_RX_STA bit15 位是否为1)
		if((UART1_RX_STA & 0x8000) == 0)
		{
			// 如果已经收到了 0x0d (回车),
			if(UART1_RX_STA & 0x4000)
			{
				// 则接着判断是否收到 0x0a (换行)
				if(buf == 0x0a)
				{
					// 如果 0x0a 和 0x0d 都收到,则将 bit15 位置为1
					UART1_RX_STA |= 0x8000;

					// 灯控指令
					if(!strcmp(UART1_RX_Buffer, "M1"))
						goForward();
					else if(!strcmp(UART1_RX_Buffer, "M2"))
						goBack();
					else if(!strcmp(UART1_RX_Buffer, "M3"))
						goLeft();
					else if(!strcmp(UART1_RX_Buffer, "M4"))
						goRight();
					else
						stop();
					
					memset(UART1_RX_Buffer, 0, UART1_REC_LEN);
					UART1_RX_STA = 0;
				}
				else
					// 否则认为接收错误,重新开始
					UART1_RX_STA = 0;
			}
			else	// 如果没有收到了 0x0d (回车)
			{
				//则先判断收到的这个字符是否是 0x0d (回车)
				if(buf == 0x0d)
				{
					// 是的话则将 bit14 位置为1
					UART1_RX_STA |= 0x4000;
				}
				else
				{
					// 否则将接收到的数据保存在缓存数组里
					UART1_RX_Buffer[UART1_RX_STA & 0X3FFF] = buf;
					UART1_RX_STA++;
					
					// 如果接收数据大于UART1_REC_LEN(200字节),则重新开始接收
					if(UART1_RX_STA > UART1_REC_LEN - 1)
						UART1_RX_STA = 0;
				}
			}
		}
		// 重新开启中断
		HAL_UART_Receive_IT(&huart1, &buf, 1);
	}
}

int fputc(int ch, FILE *f)
{      
	unsigned char temp[1]={ch};
	HAL_UART_Transmit(&huart1,temp,1,0xffff);  
	return ch;
}

4. 如何进行小车PWM调速

原理

全速前进是LeftCon1A = 0; LeftCon1B = 1;

完全停止是LeftCon1A = 0;LeftCon1B = 0;

那么单位时间内,比如20ms, 有15ms是全速前进,5ms是完全停止, 速度就会比5ms全速前进,15ms完全停止获得的功率多,相应的速度更快!

开发:借用PWM的舵机控制代码

将控制车轮的4个 GPIO 口配置修改如下,否则小车动不起来。

原因:L9110每个控制口需要一高一低才可以动起来,如果PWM有效电平为高电平,则另一个 GPIO口则需要输出低电平才可以驱动轮子。

代码实现:

main.c

// main函数里
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);
while (1)
{
    __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1, 8);
    __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2, 8);
    HAL_Delay(1000);
    __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1, 10);
    __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2, 10);
    HAL_Delay(1000);
    __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1, 15);
    __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2, 15);
    HAL_Delay(1000);
}

5. PWM方式实现小车转向

右转原理:

左轮速度大于右轮

左转原理:

右轮速度大于左轮

左右轮各自调速代码实现:

// main函数里
while (1)
{
    __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,8);
    __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,15);
    HAL_Delay(1000);
    __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,15);
    __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,8);
    HAL_Delay(1000);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1149538.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

销售流程管理实践及工具-Leangoo免费看板工具

销售管理既可以提高企业的销售业绩,又可以跟客户建立良好的关系。所以企业实施销售管理是非常有必要的。Leangoo免费看板不仅可以管理任务,它也可以成为一个绝佳的销售管理工具,帮助销售理清思路,达成目标。 首先在Leangoo中创建…

如何用加密狗保护工业软件核心技术?

工业软件的抄袭风险 1.1 反编译直窥软件的核心 工业软件代表着技术进步和创新,其中蕴含的算法、数据处理流程和功能模块往往是企业的核心竞争力。但随着技术的发展,反编译工具变得越来越先进,让不法分子可以“解剖”软件,看到它的…

Fegin ----微服务 SpringCloud

@FeignClient 是一个注解,用于创建一个声明式的 REST 客户端,用于访问其他服务的 REST API。通过 Feign Client,可以将远程服务的 API 当做本地服务进行调用,Feign Client 能够自动生成 API 客户端的实现类,在使用 API 时,只需要像调用本地方法一样调用即可。 @FeignClie…

Linux(Centos7)防火墙端口操作记录

1、nginx -t #Nginx配置文件检查 上述截图代表检查没问题 上述截图检查配置文件配置错误,并提示错误文件位置 2、systemctl restart nginx #重启Nginx 重启Nginx失败 3、systemctl status nginx.service #查看Nginx服务状态 80端口被占导致服务启动失败 4、n…

常见的22个软件测试面试题(含答案解析)

大家好,我是大圣。今天大圣给大家列举了API测试的22个面试题,快来看看吧。 1、什么是API? API是允许两个应用程序相互通信的代码。API使开发人员能够发出特定的调用或请求来发送或接收信息。 2、什么是以API为中心的应用程序? 以API为中心的应用程…

Java进阶(Set)——面试时Set常见问题解读 结合源码分析

前言 List、Set、HashMap作为Java中常用的集合,需要深入认识其原理和特性。 本篇博客介绍常见的关于Java中Set集合的面试问题,结合源码分析题目背后的知识点。 关于List的博客文章如下: Java进阶(List)——面试时L…

ssm+vue的孩童收养信息管理(有报告)。Javaee项目,ssm vue前后端分离项目。

演示视频: ssmvue的孩童收养信息管理(有报告)。Javaee项目,ssm vue前后端分离项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构,通过Spring …

FPGA时序分析与约束(9)——主时钟约束

一、时序约束 时序引擎能够正确分析4种时序路径的前提是,用户已经进行了正确的时序约束。时序约束本质上就是告知时序引擎一些进行时序分析所必要的信息,这些信息只能由用户主动告知,时序引擎对有些信息可以自动推断,但是推断得到…

文件正在使用,操作无法完成。windows查看占用文件的程序

查看占用 tasklist /m IDMShellExt64.dll 映像名称 PID 模块explorer.exe 7452 IDMShellExt64.dll杀死进程 taskkill /f /PID 7452 成功: 已终止 PID 为 7452 的进程。重启explorer explorer

建筑能源管理(7)——建筑节能诊断内容

1、节能诊断简介 1.1、节能诊断目的 建筑节能诊断是一种建筑节能的科学管理和服务方法,其主要内容是对建筑能源使用的效率、消耗水平和能源利用的经济性进行客观考察,对建筑能源利用状况进行定量分析,对建筑能源利用效率、消耗水平、能源经…

媒介易再进化,6.0国际版新老用户必看

时隔一年,媒介易平台又双叒叕更新版本了!这一次,我们带来了全新的6.0国际版,为大家提供更优质、更便捷的服务。 自2019年以来,平台不断推陈出新,优化用户体验,媒介易团队以“内容更新、视觉提升…

Linux高级命令(扩展)

一、find命令 1、find命令作用 在Linux操作系统中,find命令主要用于进行文件的搜索。 2、基本语法 # find 搜索路径 [选项 选项的值] ... 选项说明: -name :根据文件的名称搜索文件,支持*通配符 -type :f代表普通文…

CleanMyMac2024永久免费版Mac系统磁盘清理工具

Cleanmymac对很多用户来说已经非常熟悉了,因为在网上如果你搜寻有关清理mac系统方面的软件时,占比非常多的会是cleanmymac的相关消息。许多刚从Windows系统转向Mac系统怀抱的用户,一开始难免不习惯,因为Mac系统没有像Windows一样的…

【Linux】Centos 8 服务器部署:阿里云域名注册、域名解析、个人网站 ICP 备案详细教程

目录 一、背景信息 二、操作步骤 (1)查询域名 (2)加入域名清单 (3)确认订单信息 (4)支付 (5)等待域名实名认证通过 三、域名注册成功 四、查看域名…

学会吃亏,也是善良

《六祖坛经》上说:一切福田,都离不开心地。 心田上播下善良的种子,总有一天,会开花结果。 所以,心地善良是一种福祉,是对生命最好的感恩与回报,心存善念,便是最好的修行!…

C#学习相关系列之多线程---ConfigureAwait的用法

一、ConfigureAwait的作用 ConfigureAwait方法是Task类中的一个实例方法,它用于配置任务的运行上下文。运行上下文指的是任务在执行期间所处的环境,包括线程、同步上下文等。ConfigureAwait方法接受一个布尔值参数,用于决定是否捕获上下文。当…

SHCTF2023-校外赛道WP部分

SHCTF2023-校外赛道WP部分 前言:Web:MISC:[WEEK1]签到题:[WEEK1] 真的签到:[WEEK1]可爱的派蒙捏:[WEEK1]也许需要一些py:[WEEK1]Jaeger lover:[WEEK1]message:[WEEK2]远在天边近在眼…

JAVA中的垃圾回收器(3)----ZGC

一)ZGC介绍:ZGC停顿时间不超过了1ms,且不会随着堆的增加而增加 如果堆空间越来越大,那么垃圾回收的造成的STW的时间会呈现线性的增长 堆空间分页模型:小页面优先回收,大页面尽量不回收 ZGC本身只是支持三种页面,分别是小页面&…

frp-内网穿透部署-ubuntu22服务器-windows server-详细教程

文章目录 1.下载frp2.配置服务器2.1.配置frps.ini文件2.2.设置服务文件2.3.设置开机自启和服务操作2.4.后台验证2.5.服务器重启 3.配置本地window3.1.frpc配置3.2.添加开机计划启动3.3.控制台启动隐藏窗口 4.centos防火墙和端口3.1.开放端口3.2.查看端口 5.关闭进程5.1.杀死进程…

NSS刷题 js前端修改 os.path.join漏洞

打算刷一遍nssweb题(任重道远) 前面很简单 都是签到题 这里主要记录一下没想到的题目 [GDOUCTF 2023]hate eat snake 这里 是对js的处理 有弹窗 说明可能存在 alert 我们去看看js 这里进行了判断 如果 getScore>-0x1e9* 我们结合上面 我觉得是6…