stm32 PID调速控制直流无刷电机+ 源码

笔记
 

具备知识,stm32基础,了解无刷直流电机原理,pid控制原理

 
工具:
 
  • 无刷直流电机:12v电源驱动,50HZ,占空比为5%的pwm波2秒以上解锁电调,再将占空比改为6%,则电机正常运行,改变占空比到9%接近全速转动。
  • (在网上摸索了一上午此信息,因为没有直接参考资料,标签都没有)
  • 电调:电调接收了pwm信号,根据信号控制电机的电压,由此控制转速。
  • 12v电源:供电
  • stm32单片机:输出pwm波
  • st-link调试模块:调试用,主要调pwm波和pid参数
  • usb转串口模块:可获取单片机打印的串口信息(可有可无)
  • 霍尔测速传感器:测转速,5v供电,信号线为方波,捕获单位时间方波个数可测转速,由于其他条件一定,方波频率与转速为线性关系,可直接用频率代替。
  • 检测设备:万能表或者示波器,主要检测pwm波和故障时候的电压。
 
步骤:
 
1,stm32中配置pwm,延时函数,外部中断(捕捉信号用),系统rtc时钟(用于较精确确定时间)等
 
2,电调接好电机和12v电源,电调信号接单片机,注意电调别用12v供电,所有设备共地,程序正常运行
 
3,若不转

则按以下方式调试,
 
1)用示波器或万能表检测单片机是否发出符合要求的pwm波。
 
2)检测连线是否正确,
 
3)测电机电压是否是12v左右。
 
4,若电机能转动,则可以在电机上安装霍尔传感器,离里面的磁铁大概1-2毫米,太远了测不到信号,(这个问题又摸索了半天)。
 
5,用示波器测霍尔传感器的信号,显示为方波,记录此时的频率
 
6,将霍尔传感器的信号线接到单片机的外部中断引脚上,捕获其频率。
 
此时电机配置及测速基本完成。
 
PID参数整定
 
具体原理可自行百度。说说个人的理解,比如给出pwm占空比为6%,此时测出频率稳定在600,我想让霍尔元件传回来的频率变为1000,当然是加大pwm的占空比,但是加大多少呢,其频率与占空比又不是线性关系,不能一次解决,但可以用差值逐次逼近,如
 
误差=设定速度(1000)-实际速度(600)
 
占空比=占空比+P*误差(400);
 
。。。。。。。
 
如此循环下去,会发现速度在1000左右抖动,而且从600到接近1000的这段时间比较长。因此加入积分,将每次的误差对时间积分,
 
 
Integral=Σ误差
 
则占空比更正为
 
占空比=占空比+P*误差+I*Σ误差;
 
但是还是有一定的震荡,当需要其平稳时,还需要加入误差的微分,阻止其超调的变化,有超前调节的作用。
 
 
占空比=占空比+P*误差+I*Σ误差+D*(本次误差-上次误差)
 
PID初步调试就到这里了,由于条件有限,我就没有继续整定PID的值。
 
err[0]=setv-v;//设定速度-当前速度
isum+=err[0]*0.2;//积分值
dd=err[0]-err[1];//微分  
pwm=p*err[0]+i*isum+d*dd;//计算变化值
currentpwm+=pwm;//换算成占空比
currentpwm=currentpwm>=1800?1800:currentpwm;//极限速度限制,测得高速运行时占空比为1800/20000=9%
err[1]=err[0];//保存本次误差,下次使用
 


修改野火的pwm程序,野火用了四个通道,我只用了TIM4的第一通道,程序如下:
 
#include "pwm_output.h"
void pwm_value(void)
{
TIM4->CCR1=1300;
}
/*
 * 函数名:TIM3_GPIO_Config
 * 描述  :配置TIM3复用输出PWM时用到的I/O
 * 输入  :无
 * 输出  :无
 * 调用  :内部调用
 */
static void TIM4_GPIO_Config(void) 
{
  GPIO_InitTypeDef GPIO_InitStructure;
 
/* TIM4 clock enable */
//PCLK1经过2倍频后作为TIM3的时钟源等于72MHz
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); 
  /*GPIOB clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); 
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;     // 复用推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; 
 
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  // 复位定时器。
  TIM_DeInit(TIM4);
}
 
/*
 * 函数名:TIM4_Mode_Config
 * 描述  :配置TIM3输出的PWM信号的模式,如周期、极性、占空比
 * 输入  :无
 * 输出  :无
 * 调用  :内部调用
 */
static void TIM4_Mode_Config(void)
{
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_OCInitTypeDef  TIM_OCInitStructure;
 
/* PWM信号电平跳变值 */
u16 CCR1_Val =990;        
// u16 CCR2_Val = 375;
// u16 CCR3_Val = 250;
// u16 CCR4_Val = 125;    
 
/* -----------------------------------------------------------------------
    TIM3 Configuration: generate 4 PWM signals with 4 different duty cycles:
    TIM3CLK = 72 MHz, Prescaler = 0x0, TIM3 counter clock = 72 MHz
    TIM3 ARR Register = 999 => TIM3 Frequency = TIM3 counter clock/(ARR + 1)
    TIM3 Frequency = 72 KHz.
    TIM3 Channel1 duty cycle = (TIM3_CCR1/ TIM3_ARR)* 100 = 50%
    TIM3 Channel2 duty cycle = (TIM3_CCR2/ TIM3_ARR)* 100 = 37.5%
    TIM3 Channel3 duty cycle = (TIM3_CCR3/ TIM3_ARR)* 100 = 25%
    TIM3 Channel4 duty cycle = (TIM3_CCR4/ TIM3_ARR)* 100 = 12.5%
  ----------------------------------------------------------------------- */
 
  /* Time base configuration */  
  TIM_TimeBaseStructure.TIM_Period = 3999;       //当定时器从0计数到999,即为1000次,为一个定时周期
  TIM_TimeBaseStructure.TIM_Prescaler = 71;     //设置预分频:不预分频,即为72MHz
  TIM_TimeBaseStructure.TIM_ClockDivision = 0 ; //设置时钟分频系数:不分频
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //向上计数模式
  TIM_ARRPreloadConfig(TIM4, ENABLE); // 使能TIM4重载寄存器ARR
  TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
 
  TIM_OCStructInit(&TIM_OCInitStructure);
  /* PWM1 Mode configuration: Channel1 */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;     //配置为PWM模式1
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR1_Val;    //设置跳变值,当计数器计数到这个值时,电平发生跳变
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  //当定时器计数值小于CCR1_Val时为高电平
 
  TIM_OC1Init(TIM4, &TIM_OCInitStructure); //使能通道1
 
  TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);
 
  /* TIM3 enable counter */
  TIM_Cmd(TIM4, ENABLE);                   //使能定时器3
}
 
/*
 * 函数名:TIM3_PWM_Init
 * 描述  :TIM3 输出PWM信号初始化,只要调用这个函数
 *         TIM3的四个通道就会有PWM信号输出
 * 输入  :无
 * 输出  :无
 * 调用  :外部调用
 */
void TIM4_PWM_Init(void)
{
TIM4_GPIO_Config();
TIM4_Mode_Config();
}
 
/******************* (C) COPYRIGHT 2012 WildFire Team *****END OF FILE************/
 
当然,野火用的是TIM3,我用的是TIM4
主函数:
 
#include "stm32f10x.h"
#include "pwm_output.h"
 
/*
 * 函数名:main
 * 描述  :主函数
 * 输入  :无
 * 输出  :无
 */
int main(void)
{
  
while (1)
{}
}
 
这个程序编译的时候没出现问题,软件仿真的时候也能出现pwm波,下载到开发板上也成功了,但是电机就是不转,百思不得其解。
找学长看了一下,加了个延时函数,就成功了,说是电调初始化需要点时间,然后主函数改成了:
 
#include "stm32f10x.h"
#include "pwm_output.h"
 
/*
 * 函数名:main
 * 描述  :主函数
 * 输入  :无
 * 输出  :无
 */
int main(void)
{
   int i, j;
 
/* TIM3 PWM波输出初始化,并使能TIM3 PWM输出 */
TIM4_PWM_Init();
for( i=0;i<20000;i++)
{
for ( j=0;j<1000;j++)
{
}
}
pwm_value();
while (1)
{}
}
 
还是挺简单的嘛。
 

用户喜欢...

STM32H750B-DK开发套件产品信息和数据手册

STMicroelectronics STM32H750B-DK Discovery Kit是STM32H750XB MCU的完整演示和开发平台。这些MCU基于STMicroelectronics的ArmCortex-M7和-M4双核微控制器。在移植到最终产品之前,STM32H750B-DK套件用作用户应用程序开发...


STM32无刷电机驱动选型

STM32无刷电机驱动选型 - 案例:基于STM32的无刷电机的双闭环控制,硬件电路主要包括三部分:电源稳压、STM32控制部分、驱动部分。...


如何利用 GCP 和 STMicroelectronics 的 STM32F779 微控制器来设置和执行图像识别

本文将探讨嵌入式开发人员如何利用 GCP 和STMicroelectronics的STM32F779微控制器来设置和执行图像识别。 机器视觉简介 识别图像中的对象并加以标识,这一功能见诸于各类广泛应用中,包括自主驾...


基于STM32的高性能低功耗人机界面系统设计

本文选用了意法半导体公司基于ARM最新Cortex—M3内核的STM32F103RB作为主控芯片,通过选择合适的液晶模块,构建了一个高性能低功耗的中文人机界面系统。 1、系统的工作原理 本系统以STM32F1...


stm32之时钟控制

• 时钟系统与总线矩阵 • SysTick系统定时器 • RTC实时时钟 • 看门狗定时器 • 通用定时器 一、时钟系统与总线矩阵 stm32F4的时钟树如下图所示: 在STM32中,有五个时钟源,为HSI、HSE、LSI、...


STM32之TFT-LCD液晶学习

TFT-LCD即薄膜晶体管液晶显示器。其英文全称为:Thin Film Transistor-Liquid Crystal Display。TFT-LCD与无源TN-LCD、STN-LCD的简单矩阵不同,它在液晶显示屏的每一个象素上都设置有一个薄膜晶体管(TFT)...


详解STM32的PWM输出及频率和脉宽(占空比)的计算——寄存器配置六步曲!

一、stm32的pwm输出引脚是使用的IO口的复用功能。 二、T2~T5这4个通用定时器均可输出4路PWM——CH1~CH4。 三、我们以tim3的CH1路pwm输出为例来进行图文讲解(其它类似),并在最后给出tim3的ch1和ch...


STM32网络通信之DM9000A电路设计

DM9000A的PHY 能够以10BASE-T 的标准在UTP3\4\5或者以100BASE-T的标准在UTP5上接口通信。它的自动协商功能是够自动配置DM9000A最大地发挥出自身性能。它同时支持IEEE 802.3X全双工数据流通信。 2、结构...


STM32H7 的 FMC 外设在 DCACHE 使能 时运行不正常

前段时间接到一个客户的问题。客户描述在使用 STM32H7 的 FMC 时,如果使能了 DCACHE,就运行不正常。数据没有写到 FMC 外部的存储器里,测量 FMC 接口也没有波形跳变。而不使能 DCACHE 工作就是...


利用STM32外部中断驱动四路数字触摸感应传感器模块

STM32中,每一个GPIO都可以触发一个外部中断,但是,GPIO的中断是以组位一个单位的,同组间的外部中断同一时间只能使用一个。比如说,PA0,PB0,PC0,PD0,PE0,PF0,PG0这些为1组,如果我们使...


STM32 的高速 USB 信号质量测试实现

STM32 提供了丰富的接口资源,其中包括 USB FS、USB HS、OTG FS 和 OTG HS。对于高速 USB,由于信号速率相对较高。在开发过程中,会对高速 USB 信号质量进行测试,例如运用广泛的眼图测试。STM32...


在FreeRTOS嵌入式操作系统中,如何设置STM32 Cortex M3和M4系列MCU的中断优先级

前言 本文将说明在FreeRTOS嵌入式操作系统中,如何设置STM32 Cortex M3和M4系列MCU的中断优先级。 总结 【1】STM32L1系列,STM32F1系列,STM32F4系列,设置NVIC时需要使用 NVIC_PriorityGroup_4 。 【2】抢占优...


当STM32遇到串口RS485双机通信,这样处理最便捷

RS485通信想必大家都知道,在学习RS232时,都会拿485(RS485下文就用485代替)和其作对比。485优缺点不说,网上有。 我用的是STM32库函数学的485通信,所以接下来就讲讲STM32串口实现485双机通信的...


STM32单片机USB传输数据时出现卡顿现象

这几个客户问题现象基本差不多,采用 STM32 作为 Device 设备,在与上位机或者 PC 端双向通讯一段时间后,从 Device 端到 Host 端的数据能够正常,而从 Host 端到 Device 端的数据异常,也就是说,...


STM32处理器的AD难点整理

STM32的AD转换,可以将转换任务组织为两个组:规则组和注入组。 在任意多个通道上以任意顺序进行的一系列转换构成成组转换。 例如,可以如下顺序完成转换:通道3、通道8、通道2、通道...


发现 STM32 防火墙的安全配置

STM32 防火墙(Firewall)能够构建一个与其它代码隔离的带有数据存储的可信任代码区域,结合 RDP、WRP 以及 PCROP,可用来保护安全敏感的算法。在 STM32 Cube 固件库参考代码里提供了几个不同的...