返回列表 发新帖我要提问本帖赏金: 20.00元(功能说明)

[AT32M412] 【AT-START-M412测评】+ 05 定时器3输出PWM控制电机

[复制链接]
 楼主| 聪聪哥哥 发表于 2025-6-21 10:13 | 显示全部楼层 |阅读模式
本帖最后由 聪聪哥哥 于 2025-6-21 14:27 编辑

在之前测试片的基础上,对单片机输出PWM做一些调试。一:PWM知识如下:
PWM(Pulse Width Modulation 脉宽调制)是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。它是一种对模拟信号电平进行数字编码的方法。是指在一定时间内波形的高电平(即 1 状态)所占用的时间比例。
通过高分辨率计数器的使用,方波占空比被调制用来对一个模拟信号的电平进行编码。PWM 信号任然是数字的,因为在给定的任何时刻,满幅值的直流供电要么完全有,要么完全无。比如我们的电压输出是 5V的,那么经过改变 PWM 的占空比,可以达到在一定时间内输出 3.3V 或者 1.3V 的效果。
这里我们对定时器输出脉冲的频率进行一个简单的测试
PWM是脉冲宽度调制,具有两个非常重要的参数:频率和占空比。
频率:PWM的频率是整个周期的倒数。
占空比:占空比是指一个周期内高电平所占的比例。

定时器的输出部分由比较器和输出控制构成,用于编程输出信号的周期、占空比、极性。高级定时器的输出部分在不同通道上有所不同。
高级定时器在通道1到通道4上拥有互补输出,且配备死区调节;通道1到通道4拥有刹车控制。通用定时器的输出部分没有上述功能,只配备了4个通道输出。基本定时器、通用定时器和高级定时器的具体功能差异可查看RM的TMR 章节。如下图为高级定时器通道1到3输出部分原理图:

一:软件配置:
04 time3.png 04 time3-2.png
这里我们配置输出为1Khz;
引脚配置:
04 time3-1.png
二:软件生成代码如下所示:
开启定时器外设时钟
配置输出管脚
配置定时器TMRX DIV寄存器和 TMRX_PR寄存器
配置定时器为向上计数方向
配置定时器输出通道为PWM 模式 B
开启定时器计数
初始化代码如下
  1.   /* add user code begin tmr3_init 0 */

  2.   /* add user code end tmr3_init 0 */

  3.   gpio_init_type gpio_init_struct;
  4.   tmr_output_config_type tmr_output_struct;

  5.   gpio_default_para_init(&gpio_init_struct);

  6.   /* add user code begin tmr3_init 1 */

  7.   /* add user code end tmr3_init 1 */

  8.   /* configure the tmr3 CH1 pin */
  9.   gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE6, GPIO_MUX_2);
  10.   gpio_init_struct.gpio_pins = GPIO_PINS_6;
  11.   gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
  12.   gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  13.   gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  14.   gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
  15.   gpio_init(GPIOA, &gpio_init_struct);

  16.   /* configure counter settings */
  17.   tmr_cnt_dir_set(TMR3, TMR_COUNT_UP);
  18.   tmr_clock_source_div_set(TMR3, TMR_CLOCK_DIV1);
  19.   tmr_period_buffer_enable(TMR3, FALSE);
  20.   tmr_base_init(TMR3, 999, 179);

  21.   /* configure primary mode settings */
  22.   tmr_sub_sync_mode_set(TMR3, FALSE);
  23.   tmr_primary_mode_select(TMR3, TMR_PRIMARY_SEL_RESET);

  24.   /* configure channel 1 output settings */
  25.   tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;
  26.   tmr_output_struct.oc_output_state = TRUE;
  27.   tmr_output_struct.occ_output_state = FALSE;
  28.   tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
  29.   tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH;
  30.   tmr_output_struct.oc_idle_state = FALSE;
  31.   tmr_output_struct.occ_idle_state = FALSE;
  32.   tmr_output_channel_config(TMR3, TMR_SELECT_CHANNEL_1, &tmr_output_struct);
  33.   tmr_channel_value_set(TMR3, TMR_SELECT_CHANNEL_1, 499);
  34.   tmr_output_channel_buffer_enable(TMR3, TMR_SELECT_CHANNEL_1, FALSE);

  35.   tmr_output_channel_immediately_set(TMR3, TMR_SELECT_CHANNEL_1, TRUE);

  36.   tmr_counter_enable(TMR3, TRUE);

在定时器初始化完成之后,需要使能输出就可以了:
  1.   /* add user code begin tmr3_init 2 */
  2. //  tmr_period_buffer_enable(TMR3, TRUE);
  3. tmr_output_enable(TMR3, TRUE);

  4.   //tmr_counter_enable(TMR3, TRUE);

  5.   /* add user code end tmr3_init 2 */
三:  实物测试图片:
3.png
下载验证:PA6引脚输出 1Khz的固定频率,而且很稳定。
可见使用work bench 一键配置定时器的底层很方便,在初始化完成之后,还有代码指导,对于开发者很方便。

后记:输出可变频率如下:
  1. void OutPutFre(int data )
  2. {
  3. tmr_base_init(TMR3, 1000000/data -1, 179);

  4. tmr_channel_value_set(TMR3, TMR_SELECT_CHANNEL_1, 500000/data-1);

  5. }
我们在函数中,直接给函数赋值就可以,需要修改占空比数据。

打赏榜单

ArteryMCU 打赏了 20.00 元 2025-07-04
理由:[M412开发板评测活动]内容优质

ZenithSeeker 发表于 2025-7-14 16:53 | 显示全部楼层
应该不止timer3能输出pwm吧,其他的都可以输出的。
 楼主| 聪聪哥哥 发表于 2025-7-15 08:27 | 显示全部楼层
啊啊 是的 当时调试用的定时器3
治愈糖果屋 发表于 2025-7-15 15:38 | 显示全部楼层
聪聪哥哥的分享非常详细,通过你的帖子我了解到PWM的基本概念和在单片机上的应用,感谢分享!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

85

主题

222

帖子

1

粉丝

85

主题

222

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部