24年电赛——自动行驶小车(H题)MSPM0G3507-编码电机驱动与通用PID

一、编码电机驱动

        编码电机的详情可以查看此篇文章:

stm32平衡小车--(1)JGB-520减速电机+tb6612(附测试代码)_jgb520-CSDN博客

        简单来说,编码电机的驱动主要是给一个 PWM 和一个正负级就能驱动。PWM 的大小决定转速快慢,电机的两个电源正负极不同决定了旋转的方向不同。

1、PWM设置:

        PWM 的值可以在图形化配置界面进行配置,同时也可以通过如下函数进行设置:第一个参数是定时器,第二个是捕获比较值,第三个是通道。

void DL_Timer_setCaptureCompareValue(GPTIMER_Regs *gptimer, uint32_t value, DL_TIMER_CC_INDEX ccIndex);

        如下是设置占空比的一个函数。第一个参数是捕获比较值,第二个参数是设置通道,我是用一个定时器输出两路 PWM,所以需要两个通道。因为设置的是下降沿触发,系统主频是80MHz,进行了10000分频,所以计数值就是8000。duty = 7999 - 7999 * (duty/3200.0);就可以将捕获比较值从8000映射到3200。然后下面 if 来判断设置PWM输出的通道。

// 设置电机PWM占空比,取值范围为3200~0,对应占空比为100%~0%
void Motor_SetPwm(float duty,uint8_t channel) {duty = 7999 - 7999 * (duty/3200.0);if(channel==0){DL_TimerA_setCaptureCompareValue(PWM_MOTOR_INST , duty, DL_TIMER_CC_0_INDEX );  // 设置定时器捕获比较值}else {DL_TimerA_setCaptureCompareValue(PWM_MOTOR_INST , duty, DL_TIMER_CC_1_INDEX );  // 设置定时器捕获比较值}
}

        PWM 图形化配置:

 2、电机方向设置

        此函数与上面的参数一致。这两个函数分别用来设置引脚低电平和高电平。

DL_GPIO_clearPins(GPIO_MOTOR_PIN_FL1_PORT, GPIO_MOTOR_PIN_FL1_PIN);
DL_GPIO_setPins(GPIO_MOTOR_PIN_FL2_PORT, GPIO_MOTOR_PIN_FL2_PIN);

        下面函数时根据驱动电机。duty 值为正,电机正转,duty 值为负,电机反转;channel 值为0,驱动右轮,channel 值为1,驱动左轮。

// 电机前进控制函数
void Set_Speed(float duty, uint8_t channel) {if(channel==0){     //判断左右轮if(duty>0){     //判断正反转Motor_SetPwm(duty,channel);DL_GPIO_clearPins(GPIO_MOTOR_PIN_FL1_PORT, GPIO_MOTOR_PIN_FL1_PIN);DL_GPIO_setPins(GPIO_MOTOR_PIN_FL2_PORT, GPIO_MOTOR_PIN_FL2_PIN);}else if(duty<0){Motor_SetPwm(-duty,channel);DL_GPIO_clearPins(GPIO_MOTOR_PIN_FL2_PORT, GPIO_MOTOR_PIN_FL2_PIN);DL_GPIO_setPins(GPIO_MOTOR_PIN_FL1_PORT, GPIO_MOTOR_PIN_FL1_PIN);}else {DL_GPIO_clearPins(GPIO_MOTOR_PIN_FL1_PORT, GPIO_MOTOR_PIN_FL1_PIN);DL_GPIO_clearPins(GPIO_MOTOR_PIN_FL2_PORT, GPIO_MOTOR_PIN_FL2_PIN);}}else {if(duty>0){Motor_SetPwm(duty,channel);DL_GPIO_clearPins(GPIO_MOTOR_PIN_FR1_PORT, GPIO_MOTOR_PIN_FR1_PIN);DL_GPIO_setPins(GPIO_MOTOR_PIN_FR2_PORT, GPIO_MOTOR_PIN_FR2_PIN);}else if(duty<0){Motor_SetPwm(-duty,channel);DL_GPIO_clearPins(GPIO_MOTOR_PIN_FR2_PORT, GPIO_MOTOR_PIN_FR2_PIN);DL_GPIO_setPins(GPIO_MOTOR_PIN_FR1_PORT, GPIO_MOTOR_PIN_FR1_PIN);}else {DL_GPIO_clearPins(GPIO_MOTOR_PIN_FR1_PORT, GPIO_MOTOR_PIN_FR1_PIN);DL_GPIO_clearPins(GPIO_MOTOR_PIN_FR2_PORT, GPIO_MOTOR_PIN_FR2_PIN);}}
}

二、通用PID

        其中增量式 PID 不需要初始阈值,其输出主要是与上次误差与上上次误差有关,适合调节稳定速度;

        位置式 PID 需要初始阈值,其输出的结果与历史的状态有关,适合将速度维持在某个定值。

pid.c

#include "pid.h"
#include <math.h>// 初始化PID结构体
void PID_Init(PID *s_PID, PID_VAR_TYPE set_point, PID_VAR_TYPE Proportion,PID_VAR_TYPE Integral, PID_VAR_TYPE Derivative)
{// 初始化PID参数s_PID->SetPoint = set_point;            // 设定目标值s_PID->Proportion = Proportion;         // 比例系数s_PID->Integral = Integral;             // 积分系数s_PID->Derivative = Derivative;         // 微分系数s_PID->Error = 0;                       // 当前误差s_PID->LastError = 0;                   // 上一次误差s_PID->PrevError = 0;                   // 上上次误差s_PID->SumError = 0;                    // 总误差s_PID->LastResult = 0;                  // 上一次计算结果s_PID->Result = 0;                      // 当前计算结果s_PID->OutMax = DEFAULT_PID_OUT_MAX;    // 输出上限s_PID->OutMin = DEFAULT_PID_OUT_MIN;    // 输出下限s_PID->IntegralMax = DEFAULT_PID_INTEGRAL_OUT_MAX;  // 积分输出上限s_PID->IntegralMin = DEFAULT_PID_INTEGRAL_OUT_MIN;  // 积分输出下限
}// 设置PID的目标值
void PID_SetPoint(PID *s_PID, PID_VAR_TYPE set_point)
{s_PID->SetPoint = set_point;
}// 设置PID的输出范围
void PID_SetOutRange(PID *s_PID, PID_VAR_TYPE outMax, PID_VAR_TYPE outMin)
{s_PID->OutMax = outMax;s_PID->OutMin = outMin;
}// 设置PID的积分输出范围
void PID_SetIntegralOutRange(PID *s_PID, PID_VAR_TYPE outMax, PID_VAR_TYPE outMin)
{s_PID->IntegralMax = outMax;s_PID->IntegralMin = outMin;
}// 增量型PID计算
PID_VAR_TYPE Increment_PID_Cal(PID *s_PID, PID_VAR_TYPE now_point)
{s_PID->LastResult = s_PID->Result;   // 保存上一次的计算结果// 计算误差s_PID->Error = s_PID->SetPoint - now_point;// PID计算s_PID->Result =s_PID->LastResult +s_PID->Proportion * (s_PID->Error - s_PID->LastError) +  // 比例项s_PID->Integral * s_PID->Error +                          // 积分项s_PID->Derivative * (s_PID->Error - 2 * s_PID->LastError + s_PID->PrevError);  // 微分项s_PID->PrevError = s_PID->LastError;   // 更新上上次误差s_PID->LastError = s_PID->Error;       // 更新上一次误差// 限制输出范围if (s_PID->Result > s_PID->OutMax)s_PID->Result = s_PID->OutMax;else if (s_PID->Result < s_PID->OutMin)s_PID->Result = s_PID->OutMin;return s_PID->Result;
}// 位置型PID计算
PID_VAR_TYPE Position_PID_Cal(PID *s_PID, PID_VAR_TYPE now_point)
{s_PID->LastResult = s_PID->Result;   // 保存上一次的计算结果// 计算误差s_PID->Error = s_PID->SetPoint - now_point;s_PID->SumError += s_PID->Error;    // 更新总误差// 限制积分输出范围PID_VAR_TYPE IOutValue = s_PID->SumError * s_PID->Integral;if (IOutValue > s_PID->IntegralMax)IOutValue = s_PID->IntegralMax;else if (IOutValue < s_PID->IntegralMin)IOutValue = s_PID->IntegralMin;// PID计算s_PID->Result =s_PID->Proportion * s_PID->Error +      // 比例项IOutValue +                            // 积分项s_PID->Derivative * (s_PID->Error - s_PID->LastError);  // 微分项s_PID->PrevError = s_PID->LastError;   // 更新上上次误差s_PID->LastError = s_PID->Error;       // 更新上一次误差// 限制输出范围if (s_PID->Result > s_PID->OutMax)s_PID->Result = s_PID->OutMax;else if (s_PID->Result < s_PID->OutMin)s_PID->Result = s_PID->OutMin;return s_PID->Result;
}// 综合型PID计算
PID_VAR_TYPE PID_Cal(PID *s_PID, PID_VAR_TYPE now_point)
{s_PID->LastResult = s_PID->Result;   // 保存上一次的计算结果// 计算误差s_PID->Error = s_PID->SetPoint - now_point;s_PID->SumError += s_PID->Error;    // 更新总误差// 限制积分输出范围PID_VAR_TYPE IOutValue = s_PID->SumError * s_PID->Integral;if (IOutValue > s_PID->IntegralMax)IOutValue = s_PID->IntegralMax;else if (IOutValue < s_PID->IntegralMin)IOutValue = s_PID->IntegralMin;// PID计算s_PID->Result =s_PID->Proportion * (s_PID->Error + IOutValue) +   // 比例项s_PID->Derivative * (s_PID->Error - s_PID->LastError);  // 微分项s_PID->PrevError = s_PID->LastError;   // 更新上上次误差s_PID->LastError = s_PID->Error;       // 更新上一次误差// 限制输出范围if (s_PID->Result > s_PID->OutMax)s_PID->Result = s_PID->OutMax;else if (s_PID->Result < s_PID->OutMin)s_PID->Result = s_PID->OutMin;return s_PID->Result;
}

pid.h

#ifndef __PID_H
#define __PID_H	  //PID输出范围宏定义
#define DEFAULT_PID_OUT_MAX               ( 3200)
#define DEFAULT_PID_OUT_MIN               (-3200)
//PID积分范围宏定义
#define DEFAULT_PID_INTEGRAL_OUT_MAX      ( 400)
#define DEFAULT_PID_INTEGRAL_OUT_MIN      (-400)//PID变量类型宏定义
#define PID_VAR_TYPE                            float     //int//定义结构体
typedef struct
{PID_VAR_TYPE SetPoint;      // 设定目标 PID_VAR_TYPE Proportion;    // 比例常数PID_VAR_TYPE Integral;      // 积分常数PID_VAR_TYPE Derivative;    // 微分常数 PID_VAR_TYPE SumError;      // 积分和PID_VAR_TYPE Error;         // 误差PID_VAR_TYPE LastError;     // 上次误差 PID_VAR_TYPE PrevError;     // 前一次误差   PID_VAR_TYPE LastResult;    // 上次计算结果PID_VAR_TYPE Result;        // 当前计算结果PID_VAR_TYPE OutMax;        // 输出限幅最大值PID_VAR_TYPE OutMin;        // 输出限幅最小值PID_VAR_TYPE IntegralMax;   // 积分限幅最大值PID_VAR_TYPE IntegralMin;   // 积分限幅最小值
} PID;extern void PID_Init(PID *s_PID, PID_VAR_TYPE set_point,PID_VAR_TYPE Proportion,PID_VAR_TYPE Integral,PID_VAR_TYPE Derivative);  //PID初始化extern void PID_SetOutRange(PID *s_PID, PID_VAR_TYPE outMax, PID_VAR_TYPE outMin);          //设置PID输出范围
extern void PID_SetIntegralOutRange(PID *s_PID, PID_VAR_TYPE outMax, PID_VAR_TYPE outMin);  //设置PID积分范围
extern void PID_SetPoint(PID *s_PID, PID_VAR_TYPE set_point);                               //设置目标值extern PID_VAR_TYPE Increment_PID_Cal(PID *s_PID, PID_VAR_TYPE now_point);  //增量式PID计算
extern PID_VAR_TYPE Position_PID_Cal(PID *s_PID, PID_VAR_TYPE now_point);   //位置式PID计算
extern PID_VAR_TYPE PID_Cal(PID *s_PID, PID_VAR_TYPE now_point);            //比例外置式PID#endif 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

9-springCloud集成nacos config

本文介绍spring cloud集成nacos config的过程。 0、环境 jdk 1.8maven 3.8.1Idea 2021.1nacos 2.0.3 1、项目结构 根项目nacos-config-sample下有两个module&#xff0c;这两个module分别是两个springboot项目&#xff0c;都从nacos中获取连接mysql的连接参数。我们开工。 …

羌活基因组--文献精读-36

The chromosome-scale assembly of the Notopterygium incisum genome provides insight into the structural diversity of coumarins 羌活&#xff08;Notopterygium incisum&#xff09;基因组的染色体级别组装为香豆素的结构多样性提供了新的见解 摘要 香豆素是由苯丙素途…

学生信息管理系统(Python+PySimpleGUI+MySQL)

吐槽一下 经过一段时间学习pymysql的经历&#xff0c;我深刻的体会到了pymysql的不靠谱之处&#xff1b; 就是在使用int型传参&#xff0c;我写的sql语句中格式化%d了之后&#xff0c;我在要传入的数据传递的每一步的去强制转换了&#xff0c;但是他还是会报错&#xff0c;说我…

决策树可解释性分析

决策树可解释性分析 决策树是一种广泛使用的机器学习算法&#xff0c;以其直观的结构和可解释性而闻名。在许多应用场景中&#xff0c;尤其是金融、医疗等领域&#xff0c;模型的可解释性至关重要。本文将从决策路径、节点信息、特征重要性等多个方面分析决策树的可解释性&…

k8s集群的资源发布方式(滚动/蓝绿/灰度发布)及声明式管理方法

目录 1.常见的发布方式 2.滚动发布 3.蓝绿发布 4.实现金丝雀发布&#xff08;Canary Release&#xff09; 5.声明式管理方法 1.常见的发布方式 蓝绿发布:两套环境交替升级&#xff0c;旧版本保留一定时间便于回滚优点&#xff1a;用户无感知&#xff0c;部署和回滚速度较…

如何通过前端表格控件实现自动化报表?

背景 最近伙伴客户的项目经理遇见一个问题&#xff0c;他们在给甲方做自动化报表工具&#xff0c;项目已经基本做好了&#xff0c;但拿给最终甲方&#xff0c;业务人员不太买账&#xff0c;项目经理为此也是天天抓狂&#xff0c;没有想到合适的应对方案。 现阶段主要面临的问…

chrome/edge浏览器插件开发入门与加载使用

同学们可以私信我加入学习群&#xff01; 正文开始 前言一、插件与普通前端项目二、开发插件——manifest.json三、插件使用edge浏览器中使用/加载插件chrome浏览器中使用/加载插件 总结 前言 chrome插件的出现&#xff0c;初衷可能是为了方便用户更好地控制浏览器&#xff0c…

C++ | 类和对象(下)(static成员、友元、内部类、匿名对象)

目录 ​编辑 static成员 static性质简介 static属于整个类&#xff0c;属于所有对象 static成员的声明与定义 static函数 友元friend 友元特性简介 友元关系讲解 内部类 特性一 特性二 匿名对象 结语 static成员 static性质简介 static成员在类里面是非常独特的…

Golang之OpenGL(一)

使用OpenGL实现窗口中绘制三角形&#xff08;纯色|彩色&#xff09;、正方形&#xff08;变色&#xff09; 一、简单实现窗口绘制三角形二、绘制的多颜色三角形&#xff08;基于 ‘ 简单实现窗口绘制三角形 ’ &#xff09;1、在顶点着色器和片段着色器中添加了颜色的输入和输出…

反制攻击者-蚁剑低版本

目录 安装 攻击者获取防守方的权限 防守方反制攻击者 防守方获取攻击者的shell权限 安装 安装蚁剑2.0.7版本 链接&#xff1a;https://pan.baidu.com/s/1t40UxkZ2XuSWG6VCdGzvDw?pwd8888 提取码&#xff1a;8888 下载好后先打开Loader文件夹下的.exe文件&#xff0c;打…

赛蓝企业管理系统 AuthToken/Index 身份认证绕过漏洞复现

0x01 产品简介 赛蓝企业管理系统是一款为企业提供全面管理解决方案的软件系统&#xff0c;它能够帮助企业实现精细化管理&#xff0c;提高效率&#xff0c;降低成本。系统集成了多种管理功能&#xff0c;包括但不限于项目管理、财务管理、采购管理、销售管理以及报表分析等&am…

【iOS】——GCD总结

同步和异步的区别 同步执行等待操作完成&#xff0c;而异步执行允许程序在操作完成前继续运行&#xff0c;提高了效率和响应性。这里的关键就是上一个操作需不需要等待当前操作的执行&#xff0c;如果需要就是同步&#xff0c;如果不需要就是异步。 异步有开启新线程的能力但…

合作伙伴中心Partner Center中添加了Copilot预览版

目录 一、引言 二、Copilot 功能概述 2.1 Copilot 简介 2.2 Copilot 的核心功能 2.3 Copilot 的访问和使用 三、Copilot 的使用方法 3.1 Copilot 功能区域 3.2 Copilot 使用示例 3.2.1 编写有效提示 3.2.2 使用反馈循环 四、负责任的人工智能 4.1 Copilot 结果的可…

Golang处理Word文档模板实现标签填充|表格插入|图标绘制和插入|删除段落|删除标签

本教程主要实现【Golang处理Word文档模板实现标签填充|表格插入|图标绘制和插入|删除段落|删除标签】。 本文源码&#xff1a;https://gitee.com/songfayuan/go-zero-demo 教程源码分支&#xff1a;master 分支&#xff08;_examples/word-template/fill-word-template.go&…

win 10 局域网共享

1&#xff0c;打开共享 控制面板\网络和 Internet\网络和共享中心\高级共享设置 &#xff08;在控制面板界面建议使用大图片或小图标容易找到目标&#xff09; 或者直接复制红色部分&#xff0c;然后打开此电脑&#xff0c;粘贴到地址栏直接回车即可直接到达几面 打开如下2个…

达梦数据库一体机在宜昌市财政局上线了!

财政作为国家治理的基础和重要支柱&#xff0c;其数字化转型已成为构建现代财政制度的必由之路&#xff0c;引领着财政管理体系向更高效、更智能的方向迈进。 达梦数据全面助力财政信息化转型与智能化发展&#xff0c;采用 DAMEGN PAI I 系列数据库一体机&#xff0c;为宜昌市财…

Unity Camera

课程目标 1. 了解摄像机&#xff08;camera&#xff09;不同视角的设计与实现&#xff1b;2. 感受在不同摄像机视角下观察虚拟场景。 喜欢玩游戏或者看3D动漫的朋友可以回忆在虚拟场景中摄像头的运动变化带来的视觉感受&#xff0c;例如&#xff1a;摄像头给场景中的主角来个…

马来西亚原生静态IP注册的账号稳定吗?

马来西亚作为东南亚重要的经济体之一&#xff0c;其网络基础设施和互联网服务水平在近年来有了显著提升。静态IP作为一种固定的互联网协议地址&#xff0c;对于某些特定的网络应用和需求非常重要。本文将围绕马来西亚原生静态IP注册的账号稳定性进行探讨&#xff0c;分析其在不…

【Python系列】Python 字典合并

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

pytorch基础模块:Tensorboard、Dataset、Transforms、Dataloader

Tensorboard、Dataset、Transforms、Dataloader 该文档主要参考【土堆】的视频教程&#xff1a;pytorch入门教程–土堆 一、Tensorboard 安装tensorboard&#xff1a;pip install tensorboard 使用步骤&#xff1a; 引入相关库&#xff1a;from torch.utils.tensorboard i…