5207|4

1412

帖子

3

TA的资源

版主

楼主
 

【基于NUCLEO-F746ZG电机开发应用】12.参数配置-定时器TIM1配置 [复制链接]

    在伺服电机的控制过程中,使电机能够按照自己的想法转起来,一定要用到PWM输出控制,但是PWM该如何产生,频率如何控制,占空比如何调节?这就是我们今天要准备学习的部分:定时器产生PWM。

 

1.PWM的介绍

脉冲宽度调制(PWM),是英文Pulse Width Modulation的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽度的控制。PWM原理示意图如下:

图中就是一个简单的PWM 原理示意图。图中,我们假定定时器工作在向上计数PWM模式,且当CNT<CCRx 时,输出0,当CNT>=CCRx 时输出1。那么就可以得到如上的PWM示意图:当CNT 值小于CCRx 的时候,IO 输出低电平(0),当CNT 值大于等于CCRx 的时候,IO 输出高电平(1),当 CNT 达到 ARR 值的时候,重新归零,然后重新向上计数,依次循环。改变CCRx 的值,就可以改变PWM 输出的占空比,改变ARR 的值,就可以改变PWM 输出的频率,这就是PWM 输出的原理。

如果是产生简单的PWM波形,我们使用STM32F7的定时器(除了TIM6 7)均可以产生。但是我们在电机的控制中,不能使驱动电机的MOS管上下导通,必须产生互补的PWM波形才能满足要求,所以我们选用高级定时器来实现,在本开发板中使用定时器1来产生我们需要的波形。

 

2.定时器的简单介绍

高级定时器包含了通用定时器的基本功能外,还还会用到 4 个寄存器,来控制 PWM 。这四个寄存器分别是:捕获/比较模式寄存器TIMx_CCMR1/2)、捕获 /比较使能寄存器(TIMx_CCER)、捕获 /比较寄存器(TIMx_CCR1~4)和刹车和死区寄存器(TIMx_BDTR。我们要特别关注这四个寄存器,按照数据手册和自己的功能来进行配置。关于定时器的内容非常多,网上的资料也很多,在这里不在详细赘述。分享两个资料给大家参考:(1)电机控制基础——定时器基础知识与PWM输出原理(2)正点原子的资料: STM32F7开发指南-HAL库版本_V1.1.part1.rar (29.5 MB, 下载次数: 9)

STM32F7开发指南-HAL库版本_V1.1.part2.rar (28.92 MB, 下载次数: 9)

 

3.定时器配置

(1)初始化TIM1,设置TIM1 ARR PSC 等参数

定时器分频系数为2,计数模式为中心计数方式,PWM的频率为16KHz,不使用自动重装值。

  /* USER CODE END TIM1_Init 1 */
  htim1.Instance = TIM1;//定时器1
  htim1.Init.Prescaler = ((TIM_CLOCK_DIVIDER) - 1);//分频系数2-1
  htim1.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED1;//计数模式为中心计数
  htim1.Init.Period = ((PWM_PERIOD_CYCLES) / 2);//自动重装值108Mhz/16KHz
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV2;//定时器时钟2分频
  htim1.Init.RepetitionCounter = (REP_COUNTER);//更新事件延后了6个PWM周期
  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;//自动重装关闭
  if (HAL_TIM_Base_Init(&htim1) != HAL_OK)//初始化定时器
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)//初始化PWM
  {
    Error_Handler();
  }

在这里要特别注意一个定时器配置参数: htim1.Init.RepetitionCounter = (REP_COUNTER);

TIM_RepetitionCounter  的作用是在本次定时结束后,再重装载定时 1次,进入中断。因为是6路PWM,所以这里设置的参数是6次,也就是6次PWM产生完成了,才进行定时器中断。

 

(2)触发模式

设置主从的触发模式:从模式使用选择ITR1作为输入源。

  sSlaveConfig.SlaveMode = TIM_SLAVEMODE_TRIGGER;//选择从触发模式
  sSlaveConfig.InputTrigger = TIM_TS_ITR1;//输入触发:选择ITR1作为输入源
  if (HAL_TIM_SlaveConfigSynchro(&htim1, &sSlaveConfig) != HAL_OK)//初始化从模式
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;//失能定时器主模式输出触发配置
  sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;//从模式,设置是否使用定时器的被动触发
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }

 

(3)设置PWM 模式输出比较极性,比较值等参数

设置PWM为输出比较模式,互补输出极性,快速模式关闭。

  sConfigOC.OCMode = TIM_OCMODE_PWM1;//PWM1输出比较模式
  sConfigOC.Pulse = ((PWM_PERIOD_CYCLES) / 4);//设置电平跳变值108Mhz/16KHz
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;//输出比较极性
  sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;//互补输出比较极性
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;//输出比较快速失能
  sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;//选择空闲状态下非工作状态
  sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;//设置空闲状态下非工作状态
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)//PWM1通道1初始化
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)//PWM2通道1初始化
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)//PWM3通道1初始化
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM2;//PWM2输出比较模式
  sConfigOC.Pulse = (((PWM_PERIOD_CYCLES) / 2) - (HTMIN));//设置电平跳变值108Mhz/16KHz/2-1
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)//PWM4通道1初始化
  {
    Error_Handler();
  }

 

(4)刹车和死区时间配置

此时设置的死区时间为0,使能了刹车输入。

  //刹车和死区时间配置
  sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_ENABLE;//设置运行模式下非工作状态选项
  sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_ENABLE;//设置在空载下非工作状态选项
  sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_1; //锁电平参数
  sBreakDeadTimeConfig.DeadTime = 0;//死区时间
  sBreakDeadTimeConfig.BreakState = TIM_BREAK_ENABLE;//使能或失能TIMx刹车输入
  sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_LOW;//TIMx刹车输入管脚极性
  sBreakDeadTimeConfig.BreakFilter = 0;//指定中断输入过滤器
  sBreakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE;//定时器BREAK2失能
  sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_LOW;//定时器Break2 输入极性 
  sBreakDeadTimeConfig.Break2Filter = 0;
  sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;//失能自动输出功能
  if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)//初始化刹车死区时间参数
  {
    Error_Handler();
  }

 

4.软件代码

/**
  * @brief TIM1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM1_Init(void)
{

  /* USER CODE BEGIN TIM1_Init 0 */

  /* USER CODE END TIM1_Init 0 */

  TIM_SlaveConfigTypeDef sSlaveConfig = {0};//定时器从模式配置
  TIM_MasterConfigTypeDef sMasterConfig = {0};//定时器主模式配置
  TIM_OC_InitTypeDef sConfigOC = {0};//定时器比较模式配置
  TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};//定时器刹车和死区时间配置

  /* USER CODE BEGIN TIM1_Init 1 */

  /* USER CODE END TIM1_Init 1 */
  htim1.Instance = TIM1;//定时器1
  htim1.Init.Prescaler = ((TIM_CLOCK_DIVIDER) - 1);//分频系数2-1
  htim1.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED1;//计数模式为中心计数
  htim1.Init.Period = ((PWM_PERIOD_CYCLES) / 2);//自动重装值108Mhz/16KHz
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV2;//定时器时钟2分频
  htim1.Init.RepetitionCounter = (REP_COUNTER);//更新事件延后了6个PWM周期
  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;//自动重装关闭
  if (HAL_TIM_Base_Init(&htim1) != HAL_OK)//初始化定时器
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)//初始化PWM
  {
    Error_Handler();
  }
  sSlaveConfig.SlaveMode = TIM_SLAVEMODE_TRIGGER;//选择从触发模式
  sSlaveConfig.InputTrigger = TIM_TS_ITR1;//输入触发:选择ITR1作为输入源
  if (HAL_TIM_SlaveConfigSynchro(&htim1, &sSlaveConfig) != HAL_OK)//初始化从模式
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;//失能定时器主模式输出触发配置
  sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;//从模式,设置是否使用定时器的被动触发
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;//PWM1输出比较模式
  sConfigOC.Pulse = ((PWM_PERIOD_CYCLES) / 4);//设置电平跳变值108Mhz/16KHz
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;//输出比较极性
  sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;//互补输出比较极性
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;//输出比较快速失能
  sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;//选择空闲状态下非工作状态
  sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;//设置空闲状态下非工作状态
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)//PWM1通道1初始化
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)//PWM2通道1初始化
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)//PWM3通道1初始化
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM2;//PWM2输出比较模式
  sConfigOC.Pulse = (((PWM_PERIOD_CYCLES) / 2) - (HTMIN));//设置电平跳变值108Mhz/16KHz/2-1
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)//PWM4通道1初始化
  {
    Error_Handler();
  }
  //刹车和死区时间配置
  sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_ENABLE;//设置运行模式下非工作状态选项
  sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_ENABLE;//设置在空载下非工作状态选项
  sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_1; //锁电平参数
  sBreakDeadTimeConfig.DeadTime = 0;//死区时间
  sBreakDeadTimeConfig.BreakState = TIM_BREAK_ENABLE;//使能或失能TIMx刹车输入
  sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_LOW;//TIMx刹车输入管脚极性
  sBreakDeadTimeConfig.BreakFilter = 0;//指定中断输入过滤器
  sBreakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE;//定时器BREAK2失能
  sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_LOW;//定时器Break2 输入极性 
  sBreakDeadTimeConfig.Break2Filter = 0;
  sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;//失能自动输出功能
  if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)//初始化刹车死区时间参数
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM1_Init 2 */

  /* USER CODE END TIM1_Init 2 */
  HAL_TIM_MspPostInit(&htim1);

}

 

最新回复

学习了 感谢楼主 THXTHXTHXTHX THXTHXTHXTHXTHXTHXTHXTHX   详情 回复 发表于 2021-11-25 22:43
点赞 关注
个人签名

没有什么不可以,我就是我,不一样的烟火! 

 
 

回复
举报

6587

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

设置PWM为输出比较模式互补输出极性,快速模式关闭,可以理解为就是有死区时间的方式

 

点评

是的,就是这样的。所以死区时间参数设置为0  详情 回复 发表于 2021-10-12 08:37
 
 
 

回复

1412

帖子

3

TA的资源

版主

板凳
 
设置PWM为输出比较模式互补输出极性,快速模式关闭,可以理解为就是有死区时间的方式

&nbsp;

是的,就是这样的。所以死区时间参数设置为0
 
 
 

回复

8

帖子

0

TA的资源

一粒金砂(中级)

4
 

学习了 感谢楼主 THXTHXTHXTHX

THXTHXTHXTHXTHXTHXTHXTHX

点评

谢谢支持  详情 回复 发表于 2021-11-27 08:41
 
 
 

回复

1412

帖子

3

TA的资源

版主

5
 
pokmnjikm 发表于 2021-11-25 22:43 学习了 感谢楼主 THXTHXTHXTHX THXTHXTHXTHXTHXTHXTHXTHX

谢谢支持

个人签名

没有什么不可以,我就是我,不一样的烟火! 

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表