STM32F407单片机编程入门(六)定时器PWM波输出实战含源码

一.概要

脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用单片机数字输出(1或0)来对外部模拟电路进行控制的一种非常有效的技术。
在这里插入图片描述
PWM波主要应用场景:
电机控制
PWM信号可以用来控制直流电机的转速和位置,实现对电机的精确控制。在无刷直流电机(BLDC)和步进电机中,利用PWM调制可以充分发挥电子设备的精确度和能效。

LED灯光调光
PWM信号可用于调控LED灯的亮度。通过改变PWM信号的占空比(on-time和off-time的比值),可以实现对LED灯光的调光操作,达到节能和避免眩光的效果。

电源管理
采用PWM技术的开关稳压器(如降压转换器)在电源管理中具有广泛的应用。

音频放大器
在数字音频放大器中,PWM信号用于控制音频信号的放大和调制。

混合动力电动汽车(HEV)和电动汽车(EV)
PWM信号用于控制电池充放电和电动机的驱动管理,提高电池的使用性能和寿命。

伺服系统
在伺服系统中,PWM信号用于传输伺服电机的控制信号,实现对伺服电机的精确控制。

二.PWM产生框架图

定时器部分框图如下,其中PWM相关的主要是基本定时器和PWM输出控制部分,基本定时器主要控制PWM输出的频率,PWM控制部分主要控制PWM输出的占空比。

在这里插入图片描述
PWM输出控制部分信号流向
在这里插入图片描述
主要寄存器
1.TIMx_CCR1
捕获比较(值)寄存器(x=1,2,3,4):设置比较值。

2.TIMx_CNT
计数器值与捕获比较寄存器CCR1进行比较,通过比较结果输出有效电平和无效电平 。

3.TIMx_ARR
自动重装载寄存器,计数器(TIMx_CNT)开始计数,直到计数器(TIMx_CNT)达到TIMx_ARR中存放的值后,重新回到0,依次循环 。

在PWM工作模式下,引入一个寄存器CCRx,这个寄存器用于控制PWM输出波的有效电平长度(占空比),假定定时器工作在向上计数 PWM模式,且当 CNT<CCRx 时,输出 0,当 CNT>=CCRx 时输出 1。当 CNT 达到 ARR 值的时候,重新归零,然后重新向上计数,依次循环。改变 CCRx 的值,就可以改变 PWM 输出的占空比,改变 ARR 的值,就可以改变 PWM 输出的频率。

工作过程如下图所示
在这里插入图片描述

三.CubeMX配置一个TIME输出1KHZ,占空比50%PWM波例程

1.硬件准备

STLINK接STM32F407VET6开发板,STLINK接电脑USB口。
在这里插入图片描述

2.创建工程

打开STM32CubeMX软件,新建工程
在这里插入图片描述
Part Number处输入STM32F407VE,再双击就创建新的工程
在这里插入图片描述

配置下载口引脚
在这里插入图片描述

配置外部晶振引脚
在这里插入图片描述

配置系统主频168Mhz,使用外部晶振
在这里插入图片描述

在这里插入图片描述

配置TIM1,1ms定时器,TIM1内部时钟是168MHZ,168分频就是1MHZ,计数器计数到1000归零,这样计数时间就是1ms,脉冲宽度是500us,根据上述配置,PWM波频率就是1KHZ,占空比就是50%。

在这里插入图片描述

配置工程文件名,保存路径,KEIL5工程输出方式
在这里插入图片描述
生成工程
在这里插入图片描述
用Keil5打开工程
在这里插入图片描述

增加代码
在这里插入图片描述

主要代码如下

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();//8M外部晶振,168M主频

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM1_Init();//定时器1初始化
  /* USER CODE BEGIN 2 */
	if (HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2) != HAL_OK)//启动定时器1通道2,PA9引脚PWM输出
  {
    /* PWM generation Error */
    while(1);
  }
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

  }
  /* USER CODE END 3 */
}
void MX_TIM1_Init(void)
{
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};
  TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};

  htim1.Instance = TIM1;
  htim1.Init.Prescaler = 167;//PWM频率配置相关
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim1.Init.Period = 999;//PWM频率配置相关
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim1.Init.RepetitionCounter = 0;
  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 500;//如果要修改占空比,需这里改
  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_2) != 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(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
  {
    Error_Handler();
  }
  HAL_TIM_MspPostInit(&htim1);

}

3.测量波形结果

通过波形接收器测量PA9引脚
在这里插入图片描述

四.CubeMX工程源代码下载

通过网盘分享的文件:4.定时器PWM波输出(1KHZ).zip
链接: https://pan.baidu.com/s/1L7vcXXJ4tE10klwupt5THg 提取码: rv32
如果链接失效,可以联系博主给最新链接

程序下载下来之后解压就行

五.小结

脉冲宽度调制(PWM:Pulse Width Modulation)可以广泛应用于电机控制、灯光的亮度调节、功率控制等领域,所以在那些领域避免不了需要用到PWM输出技能。

参考资源链接:[Zemax教程:多模光纤耦合效率计算与几何图像分析应用](https://wenku.csdn.net/doc/3814m6bbby?utm_source=wenku_answer2doc_content) 在Zemax中,计算多模光纤的耦合效率和进行几何图像分析以优化光路设计,是一个涉及精确模拟和复杂计算的过程。这需要你具备物理光学的基本知识,熟悉Zemax软件的操作,以及对多模光纤的特性和应用有深入的理解。推荐参考《Zemax教程:多模光纤耦合效率计算与几何图像分析应用》来获取详细教程和案例。 首先,在Zemax中定义光纤模型时,你需要设置光纤核心的半径参数,确保这个半径足够大,以支持预期的横截面模式数量。使用浮动型的孔口设置,使得孔口大小可以动态地由图像表面的半径决定。对于多模光纤,通常需要至少10倍于工作长的直径,以支持多种模式的传播。 接下来,利用Zemax的物理光学模型,你可以导入或创建光源,并设置合适的光路条件,包括光束角度、发散度等参数。通过模拟光束在光纤中的传播路径,可以评估不同模式的耦合效率。Zemax的几何图像分析工具能够帮助你追踪光线路径,并计算光能分布。 优化光路设计时,你可以调整光源参数、光纤的位置和角度,甚至改变光纤的尺寸和形状,以获得最佳的耦合效率。在分析结果时,检查耦合到光纤内的光能比例,评估模式支持情况,并根据需要调整设计参数。 最后,通过迭代和优化这些参数,直至耦合效率达到设计要求。在这个过程中,参考《Zemax教程:多模光纤耦合效率计算与几何图像分析应用》中的方法和案例,可以提供直接的帮助和指导。 一旦你掌握了Zemax软件中多模光纤耦合效率的计算和几何图像分析,你将能够更有效地进行光路设计,实现更高性能的光纤通信系统。建议下载Zemax官方知识库提供的样本文件,这些文件不仅包了详细的操作步骤,还提供了实例,帮助你深入理解和实践理论知识。 参考资源链接:[Zemax教程:多模光纤耦合效率计算与几何图像分析应用](https://wenku.csdn.net/doc/3814m6bbby?utm_source=wenku_answer2doc_content)
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值