前言

学校发的无刷电机:

我们准备的有刷电机:

带霍尔编码器!

电机参数:

名称:驰名电机(直流减速电机)

型号:JGA25-370

电压:12V

转数:1360r/min

做云台,核心是使用PID控制。PID以后再讲。

无刷or有刷?

无刷电机需要foc控制与SVPWM调制,算法较为繁琐。捣鼓期间也遇到不少bug,故舍弃无刷电机,选择有刷电机。为啥?代码简单呗!

(补充:若无刷电机用PWM而不是SVPWM,则会很烫很烫,烧起来也说不定~)

一、硬件准备

  • stm32F401/411开发版(SAST)
  • J-LINK/ST-LINK下载器
  • 直流有刷电机JGA25-370(带编码器
  • 电机驱动板L298N/TB6612
  • 12V锂电池

二、工程配置

新建stm32工程,这里采用的是cubmx+keil5方式。(不会还用人用标准库吧:-))

我用的是F411。

1、尝龟配置

使用外部高速晶振、Debug选Serial Wire。(我用的是J-LINK下载器)时钟树开HCLK为100MHz。(F411最大HCLK)

2、设置PWM输出

TIM5设置为内部时钟—CH3—PWM Generation。命名为PWM。

一般而言,给电机的PWM波大约20kHz

配置HCLK=100MHz(F411最大HCLK),PSC=50-1,ARR=100-1。

由频率计算公式可得:

$$

f=\frac{freq(HCLK)}{(PSC+1)(ARR+1)}=\frac{100,000,000}{50100}=20kHz

$$

其余默认配置即可。

别忘了在NVIC Settings使能中断。

3、设置两个IO口输出

用于控制电机转动方向,命名为DIR1和DIR2。

设置PA3—Output与PA4—Output。其余默认配置即可。

4、设置编码器模式

关于编码器模式,很多人可能不李姐。详细的会在以后的文章里写。这里先粗略写一下。

电机工作时,通过霍尔编码器输出AB相脉冲,单片机读取脉冲数以得到转速与角度等信息,我们还要对采集到的数据进行处理。而stm32定时器正好有个编码器模式,我们只需读取定时器计数值就能知道脉冲数为多少。

TIM2—Combined Channels—Encoder Mode

下面的都不用设置。

把图中的三个(TIM2_CH1和TIM2_CH2和PWM)Signal Pinning一下。

5、设置中断

打开一个定时器更新中断,在这个中断里我们处理编码器的数据以得到转速、角度等信息,并进行PID控制。

TIM4设置为内部时钟即可。

配置HCLK=100MHz(F411最大HCLK),PSC=1000-1,ARR=1000-1。

中断一般为100Hz

$$

f=\frac{freq(HCLK)}{(PSC+1)(ARR+1)}=\frac{100,000,000}{10001000}=100Hz

$$

别忘了在NVIC Settings使能中断。

6、打开一个串口

用于调试。

尝龟设置,设置设置MODE为异步通信(Asynchronous)。其余的默认即可。(波特率为115200)

别忘了在keil里写串口重定向。

7、生成keil工程

尝龟配置。

设置工程名称、路径(不要有中午路径),

配置IDE为MDK-ARM。代码生成配置勾选图中红框处。

点击GENERATE CODE生成工程!

8、keil配置

打开工程配置,勾选“use MicroLIB”,Debug选择J-LINK,并在Settings-Flash-Download勾选“Reset and Run”,然后编译一次。

接下来加上串口重定向:

先包含头文件#include<stdio.h>,在/* USER CODE BEGIN 4 // USER CODE END 4 */之间添加以下代码:

int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
return ch;
} int fgetc(FILE *f)
{
uint8_t ch = 0;
HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
return ch;
}

工程基本配置ok!

三、驱动板L298N/TB6612

电机驱动需要驱动板,直接用单片机驱动是不行的。我们比赛时用的是L298N。

1、L298N

L298N驱动模块,可以驱动2个直流电机,可分别实现正转,反转功能。

供电:L298N的12V和5V都接5V供电,GND不但要接驱动电源的GND。这里要和单片机连接在一起,要从这里再引出一根GND和单片机的GND相连(共地)。

OUT1、OUT2和OUT3、OUT4分别接两个直流电机Motor1两脚、Motor2两脚,IN1、IN2、IN3、IN4引脚从单片机接入控制电平,控制电机的正反转,ENA、ENB接控制使能端,控制电机调速,L298N控制逻辑关系图如下:

对于ENA通道使能引脚,若不考虑电机的转速,可接为高电平或低电平控制接通还是关断。

若需要控制电机的转速,则需要拔掉跳线帽,将其连接在单片机PWM输出上,通过调节PWM的占空比,以此来达到控制转速的目的。

转速控制原理:利用STM32 的IO输出不同占空比的脉冲信号来达到调速的过程,当占空比大的时候就表明在一个脉冲周期内高电平的时间越长,而脉冲信号输出频率极快,高电平的时间越长就表明在一段时间内IO口输出的控制电压越高,控制电压越高使得L298N输出的电压越高,这样就使得车轮的转速越快。

接线:

这里我们因为只要一个电机转,故OUT3、OUT4接电机的两脚,IN3、IN4分别接PA3、PA4控制转动方向,ENB接PA2输出PWM,12V供电脚和GND接12V锂电池,GND和单片机共地。

2、TB6612

原理、接线类似于L298N。此处不再赘述。

接下来是代码部分。

首先我们让电机转起来!

四、PWM控制

先写定时器PWM输出启动函数:

/* USER CODE BEGIN 2 */
HAL_TIM_PWM_Start(&htim5, TIM_CHANNEL_3);
/* USER CODE END 2 */

然后写一个PWM调制函数void set_pwm(int pwm);

int型变量pwm的范围应在-100~100之间(ARR设定的值为100),将它赋值给CRR(通过调节CRR的值来调节PWM波占空比,进而实现转速控制)。pwm的正负表示转动方向,分别使PA3和PA4输出不同电平来控制方向(见逻辑表)。

/* USER CODE BEGIN 4 */
void set_pwm(int pwm)
{
//限定pwm范围
if(pwm > 100)pwm = 100; if(pwm < -100)pwm = -100; //转速控制
if(pwm < 0)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, 1);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 0);
} if(pwm > 0)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, 0);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 1);
} //写CRR的值调节占空比
TIM5->CCR3 = (int)fabs((float)pwm); //记得#include<math.h>
}
/* USER CODE END 4 */

比如,输出一个占空比50%的PWM波控制电机正转:

set_pwm(50);

OK本期就到这里。往后还有电机控制part2、3,分别分享PID、编码器相关。还有MPU6050移植从入坑到入坟。

【一】工程配置与电机控制part1的更多相关文章

  1. ios 工程配置统一增加类的前缀(知识点也只能算知识点)

    在前边的代码规范中提及:团队开发或者个人开发为了打包或者自己工程中避免创建新的类核第三方系统的重复增加类的统一前缀!!又很多人问我这种开发小技巧.下面我就普及一下: 1.首先选中你的工程配置 2.然后 ...

  2. 细聊 Cocoapods 与 Xcode 工程配置

    前言 文章比较长,所以在文章的开头我打算简单介绍一下这篇文章将要讲述的内容,读者可以选择通篇细度,也可以直接找到自己感兴趣的部分. 既然是谈 Cocoapods,那首先要搞明白它出现的背景.有经验的开 ...

  3. pcl1.7.2_vs2013_x64工程配置

    pcl1.7.2_vs2013_x64工程配置 C:\Program Files\PCL 1.7.2\include\pcl-1.7;C:\Program Files\PCL 1.7.2\3rdPar ...

  4. samba 基本配置及自定义控制

    Samba简介: Samba实现的是Linux和Windows之间的一种共享,为两种不同的操作系统架起了一座桥梁,使Linux系统和Windows系统之间能够实现互相通信,共享文件系统.打印机及其他资 ...

  5. 在web.xml中配置监听器来控制ioc容器生命周期

    5.整合关键-在web.xml中配置监听器来控制ioc容器生命周期 原因: 1.配置的组件太多,需保障单实例 2.项目停止后,ioc容器也需要关掉,降低对内存资源的占用. 项目启动创建容器,项目停止销 ...

  6. vs如何将工程配置,保存到属性表

    上次讲到新建一个opencv工程的配置过程,整个流程下来还是非常麻烦的.每次新建一个工程都要走这个流程的话就要疯了! 现在介绍一种将工程配置,保存到属性表的方法,那么下次新建工程时,只要添加这个属性表 ...

  7. TestDirector自定义管理:工程配置

    一.工程配置 1.进入工程配置界面 2.点击“customize project entities”弹出自定义字段对话框.(这里有六个表,每个表中的字段分为系统字段(system fields)和用户 ...

  8. IJ:工程配置Tomcat

    ylbtech-IJ:工程配置Tomcat 1.返回顶部 1. 1.2. 1.3. 1.4. 2. 2.返回顶部 1. 2. 3.返回顶部 1. 2. 4.返回顶部 0.修改文件位置 D:\work- ...

  9. 第一章节 BJROBOT ROS 网络配置及移动控制【ROS全开源阿克曼转向智能网联无人驾驶车】

    版权声明:该教程版权归北京智能佳科技有限公司所有,未经公司授权禁止引用.发布.转载等,否则将追究其法律责任. 使用前说明:本使用文档说明略微简明,请结合指导视频进行操作会更容易理解!! 第一章节 BJ ...

随机推荐

  1. VC 为程序创建唯一标识

    转载请注明来源:https://www.cnblogs.com/hookjc/ 应用: 一台机器上只许运行一个客户端 同一个账号只允许登陆一个客户端 BOOl m_IsRun=false; HANDL ...

  2. 认识BufferedReader的readLine、ready,以及InputStream的available

    最近,同学做实验的时候,在读取服务器端返回的时候,使用了BufferedReader类的readLine,他是这么写的,while(reader.ready()) {//执行读取操作,即readLin ...

  3. MyBatis加强(1)~缓存机制(一级缓存、二级缓存、第三方缓存技术redis、ehcache)

    一.缓存机制 使用缓存可以使应用更快地获取数据,避免频繁的数据库交互操作,尤其是在查询越多,缓存命中率越高 的情况下,缓存的作用就越明显. 1.缓存原理:Map ■ 查询时,先从缓存区查询:找到,返回 ...

  4. unittest基础篇1

    转自http://blog.csdn.net/huilan_same/article/details/52944782 unittest是xUnit系列框架中的一员,如果你了解xUnit的其他成员,那 ...

  5. Solution -「ExaWizards 2019 C」Snuke and Wizards

    \(\mathcal{Description}\)   Link.   给定一个长度为 \(n\) 的字符串 \(s\),每个字符上初始有一张卡片.\(q\) 次操作,每次指定 \(s\) 中字符为 ...

  6. ios开发 Rsa签名 base64转码

    因为公司要求做了一个加密  网上的资料少有可用的  于是我看到了一位大神的曙光 但是未介绍使用方法 然后另一位大神给予了使用方法 但是没有把库给出来   我整理了一下  希望大家看的有些启发 证书生成 ...

  7. 用实例带你深入理解Java内存模型

    摘要:本文的目的来理解 J V M 与我们的内存两者之间是如何协调工作的. 本文分享自华为云社区<一文带你图解Java内存模型>,作者: 龙哥手记 . 我们今天要特别重点讲的,也就是我们本 ...

  8. Wireshark教程之数据包操作

    实验目的 1.工具介绍 2.主要应用 实验原理 1.网络管理员用来解决网络问题 2.网络安全工程师用来检测安全隐患 3.开发人员用来测试执行情况 4.学习网络协议 实验内容 1.工具基本使用 2.快速 ...

  9. java 读取xlsx文件

    public class ReadExcel { public static void main(String[] args) { Workbook wb = null; Sheet sheet = ...

  10. redis主从复制,哨兵以及集群搭建部署

    redis主从复制 1.redis支持多实例的功能,一台机器上,可以运行多个单个的redis数据库 环境准备,运行3个redis数据库,达到 1主 2从的配置 主库 6379.conf port 63 ...