ROS移动机器人——32电机驱动

news2024/11/22 16:29:03

驱动电机,我们在这里使用TB6612来驱动电机,同时,电机的内部我们有编码器进行计次

输出比较

 cnt,就是时基单元寄存器

ccr,在cnt下方,为捕获比较寄存器,cc是捕获比较的意思,r就是寄存器

他就可以在捕获与比较之间进行切换

cnt计数是自增的,CCR是我们给定的一个值,当cnt大于ccr 小于ccr 等于ccr时,CH1通道就会对应的置1 / 0 / 1 / 0,为我们需要用这个来输出PWM波形

PWM参数: 频率 = 1 / ts   占空比 = ton / ts   分辨率 = 占空比变化

 上图为输出控制OC输出PWM,相同的下面还有3个通道

我们可以控制大小,控制输出的REF的高低电平 

输出比较模式

 PWM的结构我们之前说过,就不过多介绍,看一张图我们就能明白

直流电机

有两个电极,正接正转,反接反转,我们看看TB6612电路

 

所以我们可以看出,想要驱动一个电机,我们需要配置3个IO口,一个PWM,两个AIN1/2 

TB6612.h

#ifndef TB6612_H
#define TB6612_H


#include "sys.h"


/*B0 口*/
#define AIN1_GPIO_PIN		GPIO_Pin_3
#define AIN1_GPIO_PORT	GPIOB
#define AIN1_GPIO_CLK		RCC_APB2Periph_GPIOB

/*输出高电平*/
#define AIN1_ON			GPIO_SetBits(AIN1_GPIO_PORT,AIN1_GPIO_PIN)
/*输出低电平*/
#define AIN1_OFF		GPIO_ResetBits(AIN1_GPIO_PORT,AIN1_GPIO_PIN)


/*B1口*/
#define AIN2_GPIO_PIN		GPIO_Pin_4
#define AIN2_GPIO_PORT	GPIOA
#define AIN2_GPIO_CLK		RCC_APB2Periph_GPIOA

/*高电平*/
#define AIN2_ON			GPIO_SetBits(AIN2_GPIO_PORT,AIN2_GPIO_PIN)
/*低电平*/
#define AIN2_OFF		GPIO_ResetBits(AIN2_GPIO_PORT,AIN2_GPIO_PIN)


/*B10口*/
#define BIN1_GPIO_PIN		GPIO_Pin_5
#define BIN1_GPIO_PORT	GPIOA
#define BIN1_GPIO_CLK		RCC_APB2Periph_GPIOA


#define BIN1_ON			GPIO_SetBits(BIN1_GPIO_PORT,BIN1_GPIO_PIN)

#define BIN1_OFF		GPIO_ResetBits(BIN1_GPIO_PORT,BIN1_GPIO_PIN)


/*B11口*/
#define BIN2_GPIO_PIN		GPIO_Pin_12
#define BIN2_GPIO_PORT	GPIOB
#define BIN2_GPIO_CLK		RCC_APB2Periph_GPIOB


#define BIN2_ON			GPIO_SetBits(BIN2_GPIO_PORT,BIN2_GPIO_PIN)

#define BIN2_OFF		GPIO_ResetBits(BIN2_GPIO_PORT,BIN2_GPIO_PIN)  


void AIN1_GPIO_Config(void);
void AIN2_GPIO_Config(void);
void PWMA_STOP(void);
void PWMA_Forward(int a);
void PWMA_Reverse(int a);
      
void BIN1_GPIO_Config(void);
void BIN2_GPIO_Config(void);
void PWMB_STOP(void);
void PWMB_Forward(int a);
void PWMB_Reverse(int a);

void TB6612_GPIO_Config(void);
void STOP(void);
void Forward(int a);
void Reverse(int a);
#endif

TB6612.c

#include "TB6612.h"
#include "base_generaltim.h"
#include "stm32f10x.h"


// 开启AIN1,GPIO
void AIN1_GPIO_Config(void)
{
	GPIO_InitTypeDef	GPIO_InitStruct;

	RCC_APB2PeriphClockCmd(AIN1_GPIO_CLK,ENABLE);
	
	GPIO_InitStruct.GPIO_Pin = AIN1_GPIO_PIN;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;//使用推挽输出
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(AIN1_GPIO_PORT,&GPIO_InitStruct);
}

// 开启AIN2
void AIN2_GPIO_Config(void)
{
	GPIO_InitTypeDef		GPIO_InitStruct;

	RCC_APB2PeriphClockCmd(AIN2_GPIO_CLK,ENABLE);
	
	GPIO_InitStruct.GPIO_Pin = AIN2_GPIO_PIN;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;//ÍÆÍìÊä³ö
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(AIN2_GPIO_PORT,&GPIO_InitStruct);
}

void BIN1_GPIO_Config(void)
{
	GPIO_InitTypeDef		GPIO_InitStruct;

	RCC_APB2PeriphClockCmd(BIN1_GPIO_CLK,ENABLE);
	
	GPIO_InitStruct.GPIO_Pin = BIN1_GPIO_PIN;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;//ÍÆÍìÊä³ö
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(BIN1_GPIO_PORT,&GPIO_InitStruct);
}

void BIN2_GPIO_Config(void)
{
	GPIO_InitTypeDef		GPIO_InitStruct;

	RCC_APB2PeriphClockCmd(BIN2_GPIO_CLK,ENABLE);
	
	GPIO_InitStruct.GPIO_Pin = BIN2_GPIO_PIN;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;//ÍÆÍìÊä³ö
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(BIN2_GPIO_PORT,&GPIO_InitStruct);
}

// 开启两个IO口,控制对应输出口
void TB6612_GPIO_Config(void)
{
   AIN1_GPIO_Config();
   AIN2_GPIO_Config();
   BIN1_GPIO_Config();
   BIN2_GPIO_Config();
}


void PWMA_STOP(void)//
{
	AIN1_OFF;
	AIN2_OFF;
	GENERAL_ccr1_Mode_Config(0); //PWM输出
//PWM的初始化,在前两个函数,放在了主函数
} 

void PWMA_Forward(int a)//01ΪÕýת
{
	AIN1_OFF;
	AIN2_ON;
	GENERAL_ccr1_Mode_Config(a);

}

void PWMA_Reverse(int a)//10Ϊ·´×ª
{
	AIN1_ON;
	AIN2_OFF;
	GENERAL_ccr1_Mode_Config(a);

}


void PWMB_STOP(void)//00Ϊֹͣ
{
	BIN1_OFF;
	BIN2_OFF;
	
	GENERAL_ccr2_Mode_Config(0);
}

void PWMB_Forward(int a)//01ΪÕýת
{
	BIN1_OFF;
	BIN2_ON;
	
	GENERAL_ccr2_Mode_Config(a);
}

void PWMB_Reverse(int a)//10Ϊ·´×ª
{
	BIN1_ON;
	BIN2_OFF;
	
	GENERAL_ccr2_Mode_Config(a);
}

void STOP(void)
{
	PWMA_STOP();
	PWMB_STOP();
}

void Forward(int a)
{
	PWMA_Forward(a);
	PWMB_Forward(a);
}

void Reverse(int a)
{
	PWMA_Reverse(a);
	PWMB_Reverse(a);
}


我们也可以直接配置,然后在Compare里面来进行设定空比(调速)

同时也要进行对电机内编码器的计算

开启IC输出比较,进行cnt计算编码器计次,通过清零读数来计算编码器脉冲,计算编码器最主要的用途是用于PID的使用,我们下一节再说明

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

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

相关文章

内存溢出问题排查

一、问题背景下午突发服务器CPU频繁撑爆,服务启动后不久就挂掉。一周前系统有一次投产,之后再没有更新过系统。同时在日志中看到大量的dubbo服务调用失败。二、排查问题产生原因1.查看JVM崩溃日志hs_err_pid.logJVM崩溃时会生成hs_err_pid_xxx.log日志文…

面经分享|2022年秋招斩获7个规控算法工程师offer

该面经来自深蓝学院用户投稿,作者为东北大学自动化专业硕士。 作者2022年秋招情况:投递的岗位包括决策规划,规划控制和控制岗位。本人累计投递70家自动驾驶公司,最终收获10多家公司的笔试或面试反馈。最终拿到的offer包括主机厂、…

抖音短视频运营中的六大定位法

抖音六大定位法 1年龄反转法年龄反转法的秘诀就是指,所设定的人物、性格与实际的年龄并不是特别符合,从而让用户产生比较强烈的差异感。比如之前很火的北海爷爷,是一位有着七十多岁高龄的先生,但他依然很有精神,举止优…

【Mybatis-plus 入门教程】

🌈博客主页:屠一乐的博客 📅 发文时间:2023.1.6 🎈 一定存在只有你才能做成的事 🌹 博主水平有限,如有错误,欢迎指正 欢迎各位👍收藏💎评论✉ MyBatisPlus …

舆情监测技术手段有哪些,网络舆情监测监测技术应用到哪些方面?

随着网络舆情的快速发展,舆情影响到方方面面,大多数企业将网络舆情监测纳入其日常工作。对于舆情监测上如何做到全面监测,那些技术上可以实现,接下来TOOM舆情监测小编带您简单了解舆情监测技术手段有哪些,网络舆情监测…

C语言 文件处理

文件操作 为什么使用文件 什么是文件 程序文件 数据文件 文件名 文件的打开和关闭 文件指针 只要没打开一个文件就会有一个文件信息区,只要一更改文件信息区也会跟着更改 **FILE *fopen( const char filename, const char mode ); filename 文件名 *char mode 打…

疑难杂症之vscode--During startup program exited with code 0xc0000139.--缺失重要文件(杂记)

问题展示在vscode中,只要用了STL容器,就会出现这样的提示发现自己的 vscode 不能运行带有部分 stl 库的程序,编译不会报错,运行也不会报错但是也没有结果,调试的话会有下图中报错。拿一个以前的程序做测试,…

Java 集合系列:Vector源码深入解析

概论 学完ArrayList和LinkedList之后,我们接着学习Vector。学习方式还是和之前一样,先对Vector有个整体认识,然后再学习它的源码;最后再通过实例来学会使用它。 第1部分 Vector介绍 Vector简介 Vector 是矢量队列,…

java服装商城购物商场项目源码

简介 Java基于ssm开发的服装商城,用户可以浏览商品和特价商品,加入购物车,直接下单支付,在我的个人中心里可以管理自己的订单,收货地址,编辑资料等。管理员可以发布商品,上下架商品&#xff0c…

Neo4j详细介绍及使用教程

文章目录一、Neo4j介绍1.Neo4j简介2.图数据库简介3.Neo4j的优缺点4.Neo4j的常见应用场景二、使用教程1.下载安装2.数据插入和查询(1)基本概念(2)基本语法Ⅰ.CREATE操作——创建Ⅱ.MERGE——创建或更新Ⅲ.Match操作——查找指定的图数据Ⅳ.DELETE操作——删除节点3.JAVA实战一、…

FPGA之VGA/LCD数字时钟显示

文章目录前言一、LCD显示控制1.LCD显示一个字符2.LCD显示多个字符二、数字时钟输出1.数字时钟2.十进制数据拆分BCD码三、按键检测及LCD驱动1.按键检测2.LCD驱动四、总结前言 软件实现了在4.3寸LCD左上角显示一个数字时钟,效果如下图所示。本文针对VGA/LCD控制时许有…

leetcode:2103. 环和杆(python3解法)

难度:简单 总计有 n 个环,环的颜色可以是红、绿、蓝中的一种。这些环分布穿在 10 根编号为 0 到 9 的杆上。 给你一个长度为 2n 的字符串 rings ,表示这 n 个环在杆上的分布。rings 中每两个字符形成一个 颜色位置对 ,用于描述每个…

makefile 入门

make常用选项 # make 默认在当前目录中寻找GUNmakefile,makefile,Makefile的文件作为make的输入文件 # -f 可以指定默认的输入文件名,如: -f MyMakefile # -v 显示make版本号 # -n 只输出命令,但不执行,一般用于测试 # -s 只执行命令,但不显示具体命令,与在命令中使用作用一样…

第四十四讲:神州防火墙双机热备配置

两台防火墙硬件型号和软件版本都完全相同,为了避免防火墙不堪重负而宕机引起网络中断,可以考虑应用双机热备(HA)解决方案。双机热备能够把两台防火墙构成一个工作组,一主一备,保证数据通信畅通,…

【实际开发01】- 单元测试 ( 追求正确性 )

目录 0. 单元测试 概念 / 解析 1. 为什么要进行单元测试 1. JUnit ~ Test 2. IDEA 中使用 junit 单元测试 , 不能使用 Scanner 的解决方法 3. Junit 测试 Tutorial 1. daiding 4. Test 修饰的方法必须 public 1. validatePublicVoidNoArgMethods(Test.class, false, er…

功率二极管的损耗分析和选型原则

功率二极管的损耗分析和选型原则 tip:参考网上资料,学习为主 1.二极管的分类 2.二极管的损耗组成 3.二级管的损耗分析 4.应用实例1.Flyback电源电路二极管损耗计算 5.实例应用2.BOOST电路二极管损耗计算 6.实例应用3.大功率整流桥二极管参数计算 7.选型…

sqli-labs 5~6 多命通关攻略

sqli-labs 5~6 多命通关攻略描述判断注入类型正常输入不正常输入错误输入判断 SQL 查询结果的列数猜测 SQL 查询结果中的列数为两列猜测 SQL 查询结果中的列数为三列猜测 SQL 查询结果中的列数为四列爆破方式的可行性函数 UpdateXML()爆破(报错注入)爆破…

农业智能化进入“刚需时代 ” ,维视智造机器视觉实验室赋能新农科人才培养

1、传统农业数字化转型 新农科人才急需紧缺数千年来,农业是我国立国基础,农业兴衰关系到国家的命运。在大力推动乡村振兴的背景下,高校作为强农兴农的“国之重器”,在培育“农”的传人、新农科建设方面扮演着不可替代的角色。世界…

C++入门——内联函数、extern “C“

一. 内联函数 1.概念及分析 以inline修饰的函数叫做内联函数,编译时C编译器会在调用内联函数的地方展开,没有函数调 用建立栈帧的开销,内联函数提升程序运行的效率。 int Add(int a, int b) {int c a b;return c; }int main() {int re…

聚焦技术创新实力,时序数据库 TDengine 荣登中国技术先锋年度评选两大榜单

2023 年 1 月 5 日,中国技术先锋年度评选 | 2022 中国最受开发者欢迎的技术活动榜单正式发布。作为中国领先的新一代开发者社区,SegmentFault 思否依托社区活动板块及全站数百万开发者用户行为数据,及活动规模、内容好评度、行业综合影响力指…