IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> STM32实现步进电机S型加减速 -> 正文阅读

[嵌入式]STM32实现步进电机S型加减速

第一部分 定时器输出频率可变的PWM信号
1.首先来看一下定时器输出PWM的几种模式
定时器输出模式
此处我们采用011翻转模式,该模式下当TIMx_CCR1=TIMx_CNT时翻转电平,经常用来调节占空比。此处我们可以不断地跟换TIMx_CNT,来产生PWM波。也可以产生一个固定频率的中断。由于作者一块芯片上驱动很多电机,所以采用同一个定时器来作为PWM输出和作为频率调整的定时器。如图所示
在这里插入图片描述

如上图,我们将ARR设置为最大65536,通过不断地修改CCRx的值进行电平翻转,然后实现修改频率。

2.程序相关配置,以STM32F407的TIM13为例

	TIM_TimeBaseStructure.TIM_Prescaler=83; //1Mhz 
    TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; 
    TIM_TimeBaseStructure.TIM_Period=65535;   //
    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
    TIM_TimeBaseInit(TIM13,&TIM_TimeBaseStructure);
    //TIM11 Channel1 PWM模式
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; //翻转模式
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; 
    TIM_OCInitStructure.TIM_OutputNState= TIM_OutputNState_Disable;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
    TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
    TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;

    TIM_OC1Init(TIM13, &TIM_OCInitStructure);  //TIM13 OC1
    TIM_OC1PreloadConfig(TIM13, TIM_OCPreload_Disable);

设置计数周期为1M,这里可以自己修改。由于有计步需求和频率调整,我开启了比较中断和更新中断(用作计算加减速的频率),初始化未开启PWM输出,在需要的时候开启输出

 	TIM_ITConfig(TIM13,TIM_IT_CC1|TIM_IT_Update,ENABLE );
    NVIC_InitStructure.NVIC_IRQChannel = TIM8_UP_TIM13_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    TIM_Cmd(TIM13, ENABLE);  //TIM13
    TIM_CCxCmd(TIM13,TIM_Channel_1,TIM_CCx_Disable);

以上是定时器的配置和中断配置。接下来就是CCRx值得修改,计算CCRx值应该是多少。根据以上配置计数周期是1Mhz,例如我们需要产生一个10khz的PWM,就是1M/10k,一个周期两次翻转,就是1M/10k/2.所以CCRx就等于上次的CCRx值加上计算的比较值几:CCRx=CCRx+1M/10k/2。以下就是中断里边的计算操作

	if(TIM_GetITStatus(TIM13, TIM_IT_CC1) != RESET)
    {
            MCR.count++;
            if(MCR.count>=MCR.trip)
            {
                TIM_CCxCmd(TIM13,TIM_Channel_1,TIM_CCx_Disable);//关闭PWM
            }			
            parr=1000000/MCR.Nspeed/2;
            TIM_ClearITPendingBit(TIM13,TIM_IT_CC1);
            TIM13->CCR1 = TIM13->CCR1+parr;
        }
        else
            TIM_ClearITPendingBit(TIM13,TIM_IT_CC1);
    }
在中断里边不断地更新TIM13->CCR1的值。并进行计步,行程结束就停止输出。

第二部分 加减速曲线
这里采用的是S型加减速,
此处算法参考https://wenku.baidu.com/view/86c9fc305c0e7cd184254b35eefdc8d376ee14ae.html
这里作者采用的是直接在中断里边计算当前速度,强烈建议没有硬件FPU的话或者调节速度更快的话,最好将速度计算好放进数组进行调用。
规定加减速的几种状态

enum motor_run_state
{
  SPEED_INCREASE=0,//加速阶段
  SPEED_STABLE, //匀速阶段
  SPEED_DECREASE,//减速阶段
  DISENABLE_SPEED//不起用加减速
} ;

在中断里边不断地计算调整速度

	if(TIM_GetITStatus(TIM13,TIM_IT_Update)!=RESET)//0.016
    {
            if(MCR[Motor_PushCardX].speed_state==SPEED_INCREASE)
            {
                MCR.runCount++;
                if((MCR.Nspeed>=(MCR.Target_speed-50))&&(MCR.speed_state==SPEED_INCREASE))
                {
                    MCR.runCount=0;
                    MCR.speed_state=SPEED_STABLE;
                    MCR.Nspeed=MCR.Target_speed;
                }
                else
                {
                    MCR.Nspeed=(int)MCR.Target_speed/(1.0+exp((0-(14.0/MCR.speedUpCount)*MCR.runCount+7)))+MCR.incminspeed;
                }
            }
            else if(MCR.speed_state==SPEED_DECREASE)
            {
                MCR.runCount++;
                if((MCR.Nspeed<=(MCR.decminSpeed+50))&&(MCR.speed_state==SPEED_DECREASE))
                {
                    MCR.runCount=0;
                    MCR.speed_state=SPEED_STABLE;
                    MCR.Nspeed=MCR.decminSpeed;
                }
                else
                {
                    MCR.Nspeed=(int)MCR.Target_speed/(1.0+exp(-(0-(14.0/MCR.slowCount)*MCR.runCount+7)));
                }
            }
        }
        TIM_ClearITPendingBit(TIM13,TIM_IT_Update);
    }

MCR.Nspeed:当前速度 MCR.Target_speed目标速度
MCR.speedUpCount加速到目标速度需要的次数
MCR.slowCount 减速到最小速度的次数。

以上仅供参考

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-04-26 11:55:20  更:2022-04-26 11:57:52 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 2:28:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码