stm32f103步进电机S曲线计算

news2024/11/25 5:02:46

S曲线主要实现低速扭力大,更快更稳
https://zhuanlan.zhihu.com/p/396648926?utm_campaign=&utm_medium=social&utm_oi=1361101006265331712&utm_psn=1686906450235133952&utm_source=zhihu
可点击上面链接查看啤酒杯的运动动画

摘自一段知乎上一段关于S曲线方程的解释

首先说一下什么是S型曲线加速,为什么要S型曲线加速。S型曲线加速是指步进电机的启动速度按照S型曲线逐渐增加,以达到设定的最大速度。具体的S型曲线方程如下:
在这里插入图片描述

x取值-5~5的曲线图如下:
在这里插入图片描述

可以看到,刚开始加速和达到最大速度时加速比较缓慢,中间加速比较快。电机的转矩和转速的乘积的k倍等于功率,也就是说,功率一定的时候,转速与转矩成反比关系。所以,转速越低,转矩越大。当电机直接高速启动时,电机可能存在震动、丢步甚至启动不起来的情况。因此需要S型曲线加速,使电机能够缓慢启动。

程序实现控制电机的速度,其实就是控制PWM的输出频率。首先需要对S曲线方程进行一些变化,如下:

Fcurrent = Fmin + (Fmax-Fmin)/(1+exp( -Flexible(i - num )/num) )

Fcurrent为计算出的当前频率。
Fmin为加速的起始频率。
Fmax为加速的最大频率。
-Flexible*(i - num)/num是对S型曲线进行拉伸变化,其中Flexible代表S曲线区间(越大代表压缩的最厉害,中间加速度越大;越小越接近匀加速。理想的S曲线的取值为4-6)。
i是在循环计算过程中的索引,从0开始。
num为 加速脉冲数/2 大小。

S曲线加减算法计算

/*加速曲线计算*/
	for (i = 0; i < Motor_S_Type_ARRAY.step_accel; i++)
	{
		// F_current = F_min + (F_max - F_min) / (1 + exp(-flexible*(i-num)/num));
		F_current = (float)(Motor_S_Type_ARRAY.speed_min_frq + 
		(Motor_S_Type_ARRAY.speed_max_frq - Motor_S_Type_ARRAY.speed_min_frq) 
		/ (1 + exp(-FLEXIBLE*(i - (float)(Motor_S_Type_ARRAY.step_accel/2)) 
		/ (Motor_S_Type_ARRAY.step_accel/2))));
		
		speed_per = 1000000 / (F_current*2);//定时器分频后1M的频率,除以当前电平翻转的频率得重装载值。电平翻转的频率为电机频率的2倍
		MotorDataAlgorithm_Struct_Array.accel_array[i] = (uint16_t)speed_per;
	}
	
	/*减速曲线计算*/
    for (i = 0; i < Motor_S_Type_ARRAY.step_decel; i++)
	{
		// F_current = F_max - (F_max - F_min) / (1 + exp(-flexible*(i-num)/num));
		F_current = (float)(Motor_S_Type_ARRAY.speed_max_frq - 
		(Motor_S_Type_ARRAY.speed_max_frq - Motor_S_Type_ARRAY.speed_min_frq) 
		/ (1 + exp(-FLEXIBLE*(i - (float)(Motor_S_Type_ARRAY.step_decel/2))
		/ (Motor_S_Type_ARRAY.step_decel/2))));
		
		speed_per = 1000000 / (F_current*2);//定时器分频后1M的频率,除以当前电平翻转的频率得重装载值。电平翻转的频率为电机频率的2倍
		MotorDataAlgorithm_Struct_Array.decel_array[i] = (uint16_t)speed_per;
	}

程序设定的最小频率是2000,最大脉冲翻转频率根据需要设定,由于S曲线的计算需要占用比较多的时间,需要在电机运转前计算好存放于一个数组,提供给定时器中断服务程序使用。

void motor_prog(void)
{
	static uint8_t i=0,j=0;
	MA_STEP_LEVEL = !MA_STEP_LEVEL;
	Motor_S_Type_ARRAY.step_counter ++;

	if(Motor_S_Type_ARRAY.step_counter < Motor_S_Type_ARRAY.step_num)//还没达到最大步数,即还没运行完
	{
		if(Motor_S_Type_ARRAY.step_counter < Motor_S_Type_ARRAY.step_accel*ACCEL_DECEL_MULTIPLE)//加速过程中
		{
			i++;
			if(i==ACCEL_DECEL_MULTIPLE)
			{
				i=0;
				MotorTimArrUpdate(*MA_accel_data_p++);
			}
		}
		else if(Motor_S_Type_ARRAY.step_counter == Motor_S_Type_ARRAY.step_accel)//刚好加速完成
		{
			MotorTimArrUpdate(Motor_S_Type_ARRAY.step_per);
		}
		else if((Motor_S_Type_ARRAY.step_num - Motor_S_Type_ARRAY.step_counter) //减速过程中
				< Motor_S_Type_ARRAY.step_decel*ACCEL_DECEL_MULTIPLE)
		{
			j++;
			if(j==ACCEL_DECEL_MULTIPLE)
			{
				j=0;
				MotorTimArrUpdate(*MA_decel_data_p++);
			}
		}
        
        MotorStartStopClk(ENABLE);//启动定时器
	}
    
        if(Motor_S_Type_ARRAY.step_counter >= Motor_S_Type_ARRAY.step_num){//已达到最大步数
            
            MotorHalfCurrent(HalfEn);//半流锁开启
            MotorStartStopClk(DISABLE);//关闭定时器
            Motor_S_Type_ARRAY.run_state = STOP;//运行状态为停止
		
            /*电机位置信息更新*/
            if(Motor_S_Type_ARRAY.motor_dir != config_get_ptr()->rst_dir)
            {
                if( Location_Last + Motor_S_Type_ARRAY.step_counter/2 < MOTOR_LIMIT )
                    Location_Last = Location_Last + Motor_S_Type_ARRAY.step_counter/2;
                else
                    Location_Last = MOTOR_LIMIT;
            }
            else
            {
                if( Location_Last > Motor_S_Type_ARRAY.step_counter/2 ) 
                    Location_Last = Location_Last - Motor_S_Type_ARRAY.step_counter/2;
                else
                    Location_Last = 0;
            }
	}
	
}

计算完成后的S曲线交由给中断服务程序处理,主要实现设置定时器重载值与实现IO翻转实现产生PWM

在这里插入图片描述

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

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

相关文章

html div span 容器元素

html div && span 容器元素 div 标签定义 HTML 文档中的一个分隔区块或者一个区域部分, 标签常用于组合块级元素&#xff0c;以便通过 CSS 来对这些元素进行格式化 span 用于对文档中的行内元素进行组合 标签提供了一种将文本的一部分或者文档的一部分独立出来的方式 &…

【ELFK】之zookeeper

一、Zookeeper是什么&#xff1f; zooleeper是一个分布式服务管理框架。存储业务服务节点元数据及信息&#xff0c;并复制&#xff1b;通知客户端在zookeeper上注册的服务节点状态&#xff0c;通过文件系统通知机制 1、Zookeeper工作机制 Zookeeper从设计模式角度来理解 是…

Java——文件操作IO

一 、文件File 狭义的文件&#xff1a; 指硬盘上的 文件 和 目录 。 广义的文件&#xff1a; 泛指计算机中的很多软硬件资源。 针对硬盘这种持久化存储的I/O设备&#xff0c;当我们想要进行数据保存时&#xff0c; 往往不是保存成一个整体&#xff0c;而是独立成一个个的单位…

C/C++简单计算器 2019年12月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析

目录 C/C简单计算器 一、题目要求 1、编程实现 2、输入输出 二、解题思路 1、案例分析 三、程序代码 四、程序说明 五、运行结果 六、考点分析 C/C简单计算器 2019年12月 C/C编程等级考试一级编程题 一、题目要求 1、编程实现 一个最简单的计算器&#xff0c;支持…

Hadoop NameNode执行命令工作流程

Hadoop NameNode执行命令工作流程 客户端API或者CLI与NameNode的交互命令数据的格式(1) 预处理流程(2) 创建NameNode与NameNodePrcServer流程(3) HDFS API以及CLI的命令到NameNode的工作执行流程(4) 执行命令的参数流动 客户端API或者CLI与NameNode的交互命令数据的格式 hadoop…

读高性能MySQL(第4版)笔记10_查询性能优化(上)

1. 三管齐下 1.1. 不做、少做、快速地做 1.2. 如果查询太大&#xff0c;服务端会拒绝接收更多的数据并抛出相应错误 1.3. 如果查询写得很糟糕&#xff0c;即使库表结构再合理、索引再合适&#xff0c;也无法实现高性能 1.4. 查询优化、索引优化、库表结构优化需要齐头并进&…

JS的WebAPI

WebAPI背景知识 什么是 WebAPI 前面学习的 JS 分成三个大的部分 ECMAScript: 基础语法部分 DOM API: 操作页面结构 BOM API: 操作浏览器 WebAPI 就包含了 DOM BOM. 什么是 API API 是一个更广义的概念. 而 WebAPI 是一个更具体的概念, 特指 DOMBOM&#xff0c;所谓的 API …

使用 Elasticsearch、OpenAI 和 LangChain 进行语义搜索

在本教程中&#xff0c;我将引导您使用 Elasticsearch、OpenAI、LangChain 和 FastAPI 构建语义搜索服务。 LangChain 是这个领域的新酷孩子。 它是一个旨在帮助你与大型语言模型 (LLM) 交互的库。 LangChain 简化了与 LLMs 相关的许多日常任务&#xff0c;例如从文档中提取文本…

服务网格和CI/CD集成:讨论服务网格在持续集成和持续交付中的应用。

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

混淆矩阵细致理解

1、什么是混淆矩阵 混淆矩阵&#xff08;Confusion Matrix&#xff09;是深度学习和机器学习领域中的一个重要工具&#xff0c;用于评估分类模型的性能。它提供了一个清晰的视觉方式来展示模型的预测结果与真实标签之间的关系&#xff0c;尤其在分类任务中&#xff0c;帮助我们…

浅谈应急照明系统在民用建筑的设计应用与产品选型

贾丽丽 安科瑞电气股份有限公司 上海嘉定 201801 【摘要】应急照明分为备用照明、安全照明及疏散照明。文章介绍了应急照明系统的设计、灯具选择、灯具布置、配电等要求。并结合实例进行疏散照明的计算&#xff0c;以指导应急照明系统的设计与应用。 【关键词】照度&#xf…

大数据学习1.4-xShell配置Hadoop

1.创建hadoop目录 mkdir /usr/local/hadoop 2.切换到hadoop中 cd /usr/local/hadoop/ 3.将hadoop直接拖到xShell中 4.解压hadoop tar -zxvf hadoop-2.7.1.tar.gz 5.配置环境变量 vi /etc/profile export PATH$PATH:/usr/local/hadoop/hadoop-2.7.1/bin 6.加载配置文件(不能…

【刷题】蓝桥杯

蓝桥杯2023年第十四届省赛真题-平方差 - C语言网 (dotcpp.com) 初步想法&#xff0c;x y2 − z2&#xff08;yz)(y-z) 即xa*b&#xff0c;ayz&#xff0c;by-z 2yab 即ab是2的倍数就好了。 即x存在两个因数之和为偶数就能满足条件。 但时间是&#xff08;r-l&#xff09;*x&am…

Mybatis学习笔记8 查询返回专题

1.返回实体类 2.返回List<实体类> 3.返回Map 4.返回List<Map> 5.返回Map<String,Map> 6.resultMap结果集映射 7.返回总记录条数 新建模块 依赖 目录结构 1.返回实体类 如果返回多条,用单个实体接收会出异常 2.返回List<实体类> 即使返回一条记…

【软考】系统集成项目管理工程师(四)项目管理一般知识

一、 项目 1、 项目的定义 为大到特定的目的、使用一定的资源、在确定的期间内、为特定发起人而提供独特的产品、服务或成果而进行的一次性努力。 2、项目目标 分类描述成果性目标项目目标&#xff1a;满足客观要求的产品、系统、服务或者成果&#xff1b;例&#xff1a;①…

删除链表中所有含有val的节点

给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,6,3,4,5,6], val 6 输出&#xff1a;[1,2,3,4,5] 思路1&#xff1a;遍历查找&#xf…

大数据学习1.1-Centos8网络配置

1.查看虚拟网卡 2.配置网络信息 打勾处取消 记住箭头的数字 3.修改 网络连接 4.进入虚拟网络 5.进入属性 6.修改IPv4 5.将iIP和DNS进行修改 6.配置网络信息-进入修改网络配置文件 # 进入root用户 su root # 进入网络配置文件 cd /etc/sysconfig/network-scripts/ # 修改网络配…

C. Beautiful Sets of Points(找规律杂题)

解析&#xff1b; 由于坐标必须为整数&#xff0c;并且距离不能为整数&#xff0c;则同行同列不能存在多个“好点”。 则每行每列只能放一个点&#xff0c;所以最多的点数量即为 min&#xff08;n&#xff0c;m&#xff09;1 #include<bits/stdc.h> using namespace std…

以数据为中心的安全市场快速增长

根据Adroit Market Research的数据&#xff0c;2021年全球以数据为中心的安全市场规模估计为27.6亿美元&#xff0c;预计到2030年将增长至393.48亿美元&#xff0c;2021年至2030年的复合年增长率为30.9%。 研究人员表示&#xff0c;以数据为中心的安全强调保护数据本身&#x…

arcgis栅格按某列属性导出

栅格属性如下 可以看出栅格对应很多属性值&#xff0c;我们要按其中一个属性值作为栅格值 操作如下 只需将栅格值赋值为所需属性数据