立即注册 找回密码

微雪课堂

搜索
微雪课堂 STM32 STM32CubeMX系列教程 查看内容

STM32CubeMX系列教程4:PWM

2016-5-3 11:32| 发布者: MyMX1213| 查看: 124381| 评论: 16|原作者: MyMX1213

摘要: 上一章我们讲解了定时器的基本应用,以及定时器中断。这一章我们讲解通过定时器控制管脚输出PWM信号,控制LED1亮度渐变闪烁。
1.PWM简介
       脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调试。是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。广泛应用在从测量、通信到功率控制与变换的许多领域中。

例如上图中,图b)是微处理输出的数字信号,实际上他接到电机等功率设备上时,效果相当于图a)。这就是PWM调制。例如输出占空比为50%,频率为10Hz的脉冲,高电平为3.3V.则其输出的模拟效果相当于输出一个1.65V的高电平。脉冲调制有两个重要的参数,第一个就是输出频率,频率越高,则模拟的效果越好。第二个就是占空比。占空比就是改变输出模拟效果的电压大小。占空比越大则模拟出的电压越大。
2.stm32cube配置和说明
        打开STM32CubeMX新建工程,选择STMF746IGT6芯片,选择外部高速晶振(HSE)。LED1管脚PB6配置为定时器4的通道1输出。同时TIM4的通道1配置为PWM。
脉冲宽度调制模式可以生成一个信号,该信号频率由自动重载寄存器(TIMx_ARR)寄存器值决定,其占空比则捕获/比较寄存器(TIMx_CCRx) 寄存器值决定。
在 PWM 模式下,计数器寄存器(TIMx_CNT )总是与捕获/比较寄存器(TIMx_CCRx )进行比较,以确定是TIMx_CCRxTIMx_CNT 还是 TIMx_CNTTIMx_CCRx(取决于计数器计数方向)。
下图为PWM边沿对齐模式(递增计数配置)。图中CCRx为捕获/比较寄存器,OCxREF为输出比较信号,CCxIF为中断状态标识位。
当CCRX=4时,当捕获/比较寄存器(TIMx_CCRx)比计数器小时,输出高电平,反之则输出低电平。

下图为PWM中心对齐模式。

配置系统时钟为216MHz。由上一章可知,定时挂载到APB1,时钟频率为108MHz。此处设置为1080分频。经过分频后的时钟频率为100000Hz,若要设置PWM周期为20ms,则计数器的值为2000-1。其他参数为默认不用修改。其中Pulse的为设置脉宽,即为捕获/比较寄存器(TIMx_CCRx)。通过修改它的值可以修改占空比。

生成报告,以及生成代码,编译程序。
3.添加应用程序
在tim.c文件中我们找到刚才的定时器初始化函数。
/* TIM4 init function */
void MX_TIM4_Init(void)
{
  TIM_MasterConfigTypeDef sMasterConfig;
  TIM_OC_InitTypeDef sConfigOC;
 
  htim4.Instance = TIM4;
  htim4.Init.Prescaler = 1080-1;
  htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim4.Init.Period = 2000-1;
  htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  HAL_TIM_PWM_Init(&htim4);
 
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig);
 
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_1);
 
  HAL_TIM_MspPostInit(&htim4);
 
}

刚才说到的,设置Pulse的值可以修改脉宽。这里我们在main.c文件中添加一个用户PWM设置函数,函数的参数为修改的值。
/* USER CODE BEGIN 4 */
void user_pwm_setvalue(uint16_t value)
{
    TIM_OC_InitTypeDef sConfigOC;
 
    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = value;
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
    HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_1);
    HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1);   
}
/* USER CODE END 4 */


在把main()函数中添加HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1)开启定时器PWM输出。在while循环中不断修改脉宽,实现LED亮度渐变。Pulse的值最大为2000,从0开始,每100ms增加100,当增加到2000时,又逐渐递减到0。

  /* USER CODE BEGIN 2 */
    HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1);
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
  /* USER CODE END WHILE */
 
  /* USER CODE BEGIN 3 */
    HAL_Delay(100);  
    if(pwm_value == 0) step = 100;
    if(pwm_value == 2000) step = -100;
    pwm_value += step;
    user_pwm_setvalue(pwm_value);
  }
  /* USER CODE END 3 */

在main.c函数前面声明pwm_value,step变量,user_pwm_setvalue()函数.编译程序下载。按复位后可以看到LED1亮度渐变闪烁。

1346

顶一下

刚表态过的朋友 (1346 人)

相关阅读

发表评论

最新评论

引用 游客 2019-6-16 13:09
Internal Clock 不需要配置么
引用 游客 2019-3-16 18:49
库函数的结构体最好参数都写全,谁它的处理有没有关联,有就呵呵了
引用 游客 2019-2-20 16:32
是不是写错了,应该是每1ms增加100吧?
引用 游客 2018-8-23 10:44
peter58: 如果这里写成这样TIMx->CCRx = pwm_value,那么這个函数就没什么用了 void user_pwm_setvalue(uint16_t value)  {    TIM_OC_InitTypeDef sConfigOC;      sConf ...
你把最后三行注释掉?
引用 游客 2018-8-17 09:11
: 在main.c函数前面声明pwm_value,step变量,,, 能说明一下吗,u8 报错啊
u8最大值255,不够用
引用 游客 2018-8-10 10:41
楼上洛神正解
引用 peter58 2018-2-27 11:19
如果这里写成这样TIMx->CCRx = pwm_value,那么這个函数就没什么用了
void user_pwm_setvalue(uint16_t value)

{
   TIM_OC_InitTypeDef sConfigOC;

    sConfigOC.OCMode = TIM_OCMODE_PWM1;

    sConfigOC.Pulse = value;

    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
       

   /* HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2);

    HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);  

}*/
根本就没调用
引用 游客 2018-2-8 09:43
教程写的有些简陋
引用 游客 2017-11-22 21:37
uint16_t pwm_value=0;
int step=0;
引用 游客 2017-8-22 08:39
: 在main.c函数前面声明pwm_value,step变量,,, 能说明一下吗,u8 报错啊
uint8_t
引用 游客 2017-8-21 14:45
在main.c函数前面声明pwm_value,step变量,,, 能说明一下吗,u8 报错啊
引用 游客 2017-6-29 17:52
量过波形就发现不对,在高电平的地方由有很多半波组成,建议还是直接TIMx->CCRx = pwm_value来调节PWM
引用 游客 2017-3-7 23:23
:   洛神: 把main程序while循环中的 user_pwm_setvalue(pwm_value);  替换为 TIM4->CCR1 = pwm_value; ...
引用 Ezio_神仙醋 2017-1-19 15:04
study
引用 游客 2016-12-4 21:48
[quote]洛神: 把main程序while循环中的 user_pwm_setvalue(pwm_value);  替换为 TIM4->CCR1 = pwm_value; ...
引用 洛神 2016-12-3 10:40
把main程序while循环中的 user_pwm_setvalue(pwm_value);  替换为 TIM4->CCR1 = pwm_value; 就简洁多了。

查看全部评论(16)

CubeMX教程

微雪官网|产品资料|手机版|小黑屋|微雪课堂. ( 粤ICP备05067009号 )

GMT+8, 2024-11-22 01:52 , Processed in 0.019028 second(s), 21 queries .

返回顶部