所需元件
  STM32F103开发板、L298N一个、带编码器的直流电机一个(如下图所示,淘宝上有很多)

系统框图

  通过系统框图,我们需要做两件事,一是要测速,二是要调节。测速目前流行的就是通过编码器测速,调节器我采用的时PI调节,PI调节器调节的参数少,而且能够消除静差,当然用PID调节器也行。
编码器
  编码器的结构简化如下图:

  在电机转轴上安装了一个磁环,在磁环的下方有一个霍尔传感器,在磁环转动过程中就在霍尔传感器的附近产生了变化的磁场,于是霍尔传感器就输出了脉冲信号。我所用的这个直流电机是1:48的减速电机,电机转轴每转动1圈,编码器输出13个脉冲信号,也就是说输出转轴转动1圈,编码器输出13x48=624个脉冲,再通过STM32编码器接口 4 倍频就是 624x4=2496 个脉冲信号,通过STM32定时器的计数值除以2496就是输出转轴转动的圈数。
  所谓4倍频,如下图:

  编码器中有两个线路,即A相和B相。我们以A相或B相为例,1个上升沿或者下降沿代表1个脉冲信号,由图中可知有2个上升沿或2个下降沿,即2个脉冲信号。而所谓的4倍频,就是把A、B相的上升沿和下降沿都加起来,一共8个,与之前的2个脉冲信号就是4倍,而所以要加起来做成4倍频,可以提高测量转速的精度。另外A、B相之间相差90度,从而可以判断电机的转向。如果电机正转,A相比B相先90度,也就是说A相已经上升沿了B还是低电平。
PI调节器
  关于PID算法,可参考STM32——PID恒温控制
  这里贴两张速度曲线图:
  1、

  2、

  图1中设定目标值为400,从图上可以看出超调量还是比较小的,调节时间也比较短,调节的效果还是可以的。图2中,目标值每隔一段时间增加100,加到400后又设为100,整体的调节效果还是蛮不错的。(我程序中的PID参数套用的时候可能达不到图中的效果,这与电机以及编码器之间的差别有关,可适当在做调节)
主要程序
TIM_Encoder.c

#include "TIM_Encoder.h"float RPM_1=0;            //存储上一次测速结果void TIM_Encoder_Init(void)
{TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;  TIM_ICInitTypeDef TIM_ICInitStructure;  GPIO_InitTypeDef GPIO_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);        //使能定时器4的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);       //使能PB端口时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;     //端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;       //浮空输入GPIO_Init(GPIOB, &GPIO_InitStructure);                     //根据设定参数初始化GPIOBTIM_TimeBaseStructInit(&TIM_TimeBaseStructure);TIM_TimeBaseStructure.TIM_Prescaler = 0x0;                  // 预分频器 TIM_TimeBaseStructure.TIM_Period = 65535;                   //设定计数器自动重装值TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;     //选择时钟分频:不分频TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数  TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//使用编码器模式3TIM_ICStructInit(&TIM_ICInitStructure);TIM_ICInitStructure.TIM_ICFilter = 10;TIM_ICInit(TIM4, &TIM_ICInitStructure);TIM_ClearFlag(TIM4, TIM_FLAG_Update);                       //清除TIM的更新标志位TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);//Reset counterTIM_SetCounter(TIM4,0);TIM_Cmd(TIM4, ENABLE);
}int GetTIMCounter(void)          //获取计数值
{int count=TIM_GetCounter(TIM4);return count;
}float GetRPM(int count)           //计算转速
{//   int RPM=count/2496*2000+0.5;//30ms计算一次(pid.T=30),60000ms为1min,也就是1min计算了2000次,2496=13*4*48表示转动一圈的脉冲数,48表示1:48的减速比float RPM=count*0.8f+0.5f;   //等同于上式,2000/2496约等于0.8if(RPM>1000)                 //过滤掉不合理的结果,仍然使用上次的速度,在按键设定速度的时候或者在减速为0时会有非常的大的错误测速结果,具体原因还未查清    {{return RPM_1;}RPM_1=RPM;                   //更新return RPM;
}

PID.c

#include "PID.h"PID pid;
//int time=0;void PID_Init()
{           pid.Sv=400;         //用户设定转速400pid.Kp=0.3;         //比例pid.Ki=0.015;       //积分pid.Kd=0;           //微分pid.pwmcycle=100;   //pwm周期100uspid.T=30;           //PID计算周期30mspid.OUT0=0;pid.C1ms=0;pid.SEk=0;pid.Ek=0;pid.Ek_1=0;pid.DelEk=0;pid.Dout=0;pid.Iout=0;pid.Pout=0;
}void PID_Calc(float data)        //pid计算
{float out;pid.Pv=data;pid.Ek=pid.Sv-pid.Pv;       //得到当前的偏差值pid.Pout=pid.Kp*pid.Ek;     //比例输出pid.SEk+=pid.Ek;            //历史偏差总和if(pid.SEk<(-50)){pid.SEk=(-50);}pid.DelEk=pid.Ek-pid.Ek_1;  //最近两次偏差之差pid.Iout=pid.Ki*pid.SEk;    //积分输出if(pid.Iout<(-10)){pid.Iout=(-10);}pid.Dout=pid.Kd*pid.DelEk;  //微分输出out= pid.Pout+ pid.Iout+ pid.Dout;if(out>pid.pwmcycle){pid.OUT=pid.pwmcycle;}else if(out<=0){pid.OUT=pid.OUT0; }else {pid.OUT=out+0.5f;       //四舍五入}pid.Ek_1=pid.Ek;            //更新偏差pid.C1ms=0;
}

工程链接
链接:https://pan.baidu.com/s/1dSXgPf0gzSvTdjlMHyOZ7w
提取码:f8h1

  PID调参比较麻烦,这里推荐一个ST官方的软件StmStdio,这个软件网上有很多教程,使用也比较简单。
链接:https://pan.baidu.com/s/1etsrBL80rCe_LouNEE1XEg
提取码:ckve

STM32——直流电机PI调速相关推荐

  1. 基于L298N的STM32的直流电机PWM调速控制

    这两天研究了一下基于L298N与stm32的直流电机调速,实验结果良好,可以根据调节STM32的PWM占空比来进行直流电机的调速.实验系统图如下: 首先整个PWM实验选用的是stm32f103系列,驱 ...

  2. 基于stm32与l298n的直流电机pwm调速(二)

    在上一博文中说了直流电机驱动板的电路原理,现在具体说一下直流电机的调速原理以及代码实现,亲测调速有效. 首先说一下接线,l298n可以控制两路直流电机,在这里仅测试一路,看一下l298n的控制逻辑以及 ...

  3. 基于STM32单片机的直流电机PWM调速(Proteus仿真+程序)

    编号:9 基于STM32单片机的直流电机PWM调速 功能描述: 由 STM32单片机+液晶1602显示模块+键盘模块+L298N电机驱动模块+直流电机 1.采用STM32F103单片机为主控制器 2. ...

  4. 计算机控制直流电机闭环调速实验,最小拍控制系统及直流电机闭环调速控制系统设计和实现实验报告...

    最小拍控制系统及直流电机闭环调速控制系统设计和实现实验报告 最小拍控制系统及 直流电机闭环调速控制系统设计和实现 实验报告班级: xx 姓名: xx 学号: xx 时间: 第16周周日9-12节 指导 ...

  5. pwmc语言调速程序_51单片机的直流电机PWM调速系统设计,正转反转,加减速,急停等,仿真和代码...

    设计思路 直流电机PWM控制系统的主要功能包括:实现对直流电机的加速.减速以及电机的正转.反转和急停,并且可以调整电机的转速,能够方便的实现电机的智能控制. 主体电路:即直流电机PWM控制模块.这部分 ...

  6. 基于51单片机直流电机PWM调速设计

    具体实现功能 系统由STC89C52单片机.LCD1602液晶显示屏.霍尔测速传感器.3V直流电机.按键模块构成. 具体功能: 1.采用霍尔传感器非接触式测电机转速: 2.LCD1602液晶显示当前的 ...

  7. PIC16 F887 单片机 直流电机PWM调速 PID调速 PID算法

    直流电机PWM调速:使用将直流电机转速转换为脉冲频率,测量出电机的转速,与写入到单片机的EEPROM里的脉冲设定值进行比较产生偏差,若偏差为正值则电机减速,偏差为负值则加速,并在LCD上显示电机的转速 ...

  8. 【Proteus仿真】51单片机+直流电机PWM调速实验

    [Proteus仿真]51单片机+直流电机PWM调速实验 Proteus仿真 采用L293驱动直流电机 -PWM是采用定时器中断实现 /******************************** ...

  9. 51单片机的直流电机PWM调速控制系统(附Proteus仿真+C程序等全套资料)

    设计思路 直流电机PWM控制系统的主要功能包括:很实现对直流电机的加速.减速以及电机的正转.反转和急停,并且可以调整电机的转速,能够方便的实现电机的智能控制. 主体电路:即直流电机PWM控制模块.这部 ...

最新文章

  1. “万能数据库查询分析器” 5.03发布,访问EXCEL将自动为表名前后加上中括弧
  2. linux i2c编程
  3. 2010年 Web的五项技术和五个趋势
  4. python 读写 json文件
  5. vivox50pro鸿蒙系统,钱包卡包都承包 vivo X50 Pro+多功能NFC玩法多
  6. Visual Studio 2019 C# 断点调试 凯撒密码,单码密码实现
  7. python学习 day2
  8. vue 显示led数码字体
  9. 高性能mysql第一章——架构
  10. C语言必背18个经典程序
  11. goland 注释模板_Java程序员简历模板,怎样才是一份好的技术简历
  12. HART协议命令与UART串口解析
  13. 【从嵌入式视角学习香山处理器】一、如何开始?(开发环境搭建)
  14. 互联网周刊咋么了呢?
  15. 泛微OA-流程存储数据说明(表单主表+明细表)
  16. 【PHP】极速分销裂变,疯狂砍价活动
  17. 相亲APP开发功能及解决方案
  18. 音曼Omnos 5.1全景声音响全网首评 声音惊艳
  19. 升级ios16后iphone无法识别SIM?一招解决这个问题!
  20. cdc有哪些rapper_获谢帝推荐,合作Higher Brothers,CDC的rapper里竟还藏着这样一位狠角色...

热门文章

  1. web项目上之深入理解Java国际化
  2. 对比特币勒索病毒进行批量安装永恒之蓝补丁
  3. 【踩坑速记】开源日历控件,顺便全面解析开源库打包发布到Bintray/Jcenter全过程(新),让开源更简单~...
  4. linux特殊权限之访问权限
  5. servlet的由来
  6. [DIV/CSS] 【译】60个有用CSS代码片段
  7. KMP POJ 2752 Seek the Name, Seek the Fame
  8. EL与JSTL注意事项汇总
  9. html script 放置位置,script标签应该放在HTML哪里,总结分享
  10. Linux下BitNami Redmine的插件安装与更新