电机学习笔记 输出比较

本文详细介绍了如何在STM32中使用TIM8配置四个通道为PWM输出模式,通过设置不同的比较值实现不同频率和50%占空比的PWM信号。在中断回调函数中动态调整比较值,以实现PWM信号的连续输出。同时,讨论了中断处理过程,以及如何启动比较输出和使能中断。
摘要由CSDN通过智能技术生成

一、输入比较简介

在这里插入图片描述
输出比较就是通过定时器的外部引脚对外输出控制信号,有冻结、将通道 X(x=1,2,3,4)设置为匹配时输出有效电平、将通道 X 设置为匹配时输出无效电平、翻转、强制变为无效电平、强制变为有效电平、PWM1 和 PWM2 这八种模式,具体使用哪种模式由寄存器 CCMRx 的位 OCxM[2:0]配置。
其中 PWM 模式是输出比较中的特例,使用的也最多

在这里插入图片描述
当计数器 CNT 的值跟比较寄存器 CCR 的值相等的时候,输出参考信号 OCxREF 的信号的极
性就会改变,其中 OCxREF=1(高电平)称之为有效电平,OCxREF=0(低电平)称之为无效
电平,并且会产生比较中断 CCxI,相应的标志位 CCxIF(SR 寄存器中)会置位。然后 OCxREF
再经过一系列的控制之后就成为真正的输出信号 OCx/OCxN。

在这里插入图片描述简单来说就是

CNT的值与CCR1的值相等时,电平就翻转一下

通过不断修改CCR1的值

可以输出四路不同频率,占空比的50%的pwm

配置

在这里插入图片描述

内部时钟源也可以Disable

channel1到4都设置为 output compare ch

psc为167
period 为 0xffff

在这里插入图片描述生成代码后如下

/* TIM8 init function */
void MX_TIM8_Init(void)
{
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};
  TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};

  htim8.Instance = TIM8;
  htim8.Init.Prescaler = 167;
  htim8.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim8.Init.Period = 0xffff;
  htim8.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim8.Init.RepetitionCounter = 0;
  htim8.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim8) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim8, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_OC_Init(&htim8) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim8, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_TOGGLE;  /* PWM模式配置--这里配置为输出比较模式 */
  sConfigOC.Pulse = OC_Pulse_num_Channel1;  /* 比较输出的计数值 */
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;  /* 当定时器计数值小于CCR1_Val时为高电平 */
  sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;  /* 设置互补通道输出的极性 */
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;   /* 快速模式设置 */
  sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;  /* 空闲电平 */
  sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;  /* 互补通道设置 */
  if (HAL_TIM_OC_ConfigChannel(&htim8, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
	sConfigOC.Pulse = OC_Pulse_num_Channel2;
  if (HAL_TIM_OC_ConfigChannel(&htim8, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
  {
    Error_Handler();
  }
	sConfigOC.Pulse = OC_Pulse_num_Channel3;
  if (HAL_TIM_OC_ConfigChannel(&htim8, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
  {
    Error_Handler();
  }
	sConfigOC.Pulse = OC_Pulse_num_Channel4;
  if (HAL_TIM_OC_ConfigChannel(&htim8, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
  {
    Error_Handler();
  }
  sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
  sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
  sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
  sBreakDeadTimeConfig.DeadTime = 0;
  sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
  sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
  sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
  if (HAL_TIMEx_ConfigBreakDeadTime(&htim8, &sBreakDeadTimeConfig) != HAL_OK)
  {
    Error_Handler();
  }
  HAL_TIM_MspPostInit(&htim8);
	
	
}

这里设置每个通道默认的Pulse为

  
__IO uint16_t OC_Pulse_num_Channel1 = 25; /* 通道 1 的比较值 */
__IO uint16_t OC_Pulse_num_Channel2 = 51; /* 通道 2 的比较值 */
__IO uint16_t OC_Pulse_num_Channel3 = 77; /* 通道 3 的比较值 */
__IO uint16_t OC_Pulse_num_Channel4 = 103; /* 通道 4 的比较值 */

到这里我们还需要
启动比较输出并使能中断
使能比较通道

/* 启动比较输出并使能中断 */
HAL_TIM_OC_Start_IT(&htim8,TIM_CHANNEL_1);
HAL_TIM_OC_Start_IT(&htim8,TIM_CHANNEL_2);
HAL_TIM_OC_Start_IT(&htim8,TIM_CHANNEL_3);
HAL_TIM_OC_Start_IT(&htim8,TIM_CHANNEL_4);
/* 使能比较通道 */
TIM_CCxChannelCmd(TIM8,TIM_CHANNEL_1,TIM_CCx_ENABLE);
TIM_CCxChannelCmd(TIM8,TIM_CHANNEL_2,TIM_CCx_ENABLE);
TIM_CCxChannelCmd(TIM8,TIM_CHANNEL_3,TIM_CCx_ENABLE);
TIM_CCxChannelCmd(TIM8,TIM_CHANNEL_4,TIM_CCx_ENABLE);

重写中断回调函数

HAL_TIM_OC_DelayElapsedCallback

void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim) {
	 __IO uint16_t count;
		 /*获取当前计数*/
     count = __HAL_TIM_GET_COUNTER(htim);
		/*判断触发中断的输出通道并设置新的比较数值*/
  if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
  {
    __HAL_TIM_SET_COMPARE(htim, TIM_CHANNEL_1, count + OC_Pulse_num_Channel1);
  }
  if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
  {
    __HAL_TIM_SET_COMPARE(htim, TIM_CHANNEL_2, count + OC_Pulse_num_Channel2);
  }
  if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3)
  {
    __HAL_TIM_SET_COMPARE(htim, TIM_CHANNEL_3, count + OC_Pulse_num_Channel3);
  }
  if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4)
  {
    __HAL_TIM_SET_COMPARE(htim, TIM_CHANNEL_4, count + OC_Pulse_num_Channel4);
  }
}

CNT的值与CCR1的值相等时,电平就翻转一下,就产生一次中断

在中断中先获取当前计数假设是100
然后是通道1的发生的中断,
100+25 依次加25 当CNT的值与CCR1的值相等时,电平翻转产生中断
这样我们就获的到了一个50%的占空比
25/50 =0.5

因为每一次递增值为25(这里是通道1)所以,一个周期是25+25=50
所以1000000/50 = 20000hz

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值