一路PWM波程序的模块化设计

我们的设计中需要一个舵机用来模拟门禁的开关动作,舵机需要一路周期为50Hz,占空比为2.5%-12.5%之间的PWM波来控制,这在我们的设计中是一个比较简单的模块,我们显然希望在main.c中应用尽可能少的语句来实现它。我把我们程序中对舵机的控制稍微加了一点改动,做了这样一个实验。主函数可以通过调用定时器模块的两个函数:PWM波初始化函数,PWM波占空比修改函数,很简单地完成对舵机的控制。

实验目的:采用模块化的设计控制一路PWM波,改变它的占空比。

实验现象:控制舵机的PWM波占空比在4%和9%之间切换,每隔3秒切换一次。

创建工程

打开STM32CubeMX,创建一个新工程,RCC、SYS、Clock Configuration的配置同之前的几个实验。

1、 配置TIM1---选通道4输出

打开网易新闻 查看精彩图片

配置TIM1

选择Clock Source为Internal Clock;

选择Channel4为PWM Generation CH4;

打开网易新闻 查看精彩图片

TIM1配置完成后自动分配芯片的PWM输出引脚

这一步做完后系统会自动将PA11作为PWM波输出通道。

2.设置TIM1参数

打开网易新闻 查看精彩图片

TIM1参数配置

在Parameter Settings中

设置预分频Prescaler为7199;

设置计数值Counter Period为199;

设置auto-reload preload为Enable;

其他参数可以采用默认值

这样PWM的频率为72MHz/(7199+1)/(199+1)=50Hz;

如果要改变频率需要改变Prescaler和Counter Period的值。

3.修改管脚名称

打开网易新闻 查看精彩图片

修改管脚名称

为了与原理图匹配,我在GPIO的TIM找到PA11,将User Label修改为PWM。其实这里不改动也不太影响程序的可移植性。

4.生成模块化的工程文件

打开网易新闻 查看精彩图片

模块化工程选项

勾选Generated files的第一项后点击“Generate Code”。

功能代码

在tim.c里面添加:

/* USER CODE BEGIN 1 */

void PWM_Init(void)

HAL_TIM_Base_Start(&htim1);//打开定时器1

HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_4);//定时器1通道4输出PWM

void PWM_SetDuty(float dutycycle)

int duty=dutycycle*(htim1.Init.Period+1)/100;//根据占空比计算出比较值duty

__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_4,duty);

/* USER CODE END 1 */

在tim.h里面添加:

/* USER CODE BEGIN Prototypes */

void PWM_Init(void);

void PWM_SetDuty(float dutycycle);

/* USER CODE END Prototypes */

在main.c里面添加如下代码:

/* USER CODE BEGIN 2 */

PWM_Init();

/* USER CODE END 2 */

while (1)

/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */

PWM_SetDuty(4);

HAL_Delay(3000);

PWM_SetDuty(9);

HAL_Delay(3000);

/* USER CODE END 3 */

这里用到了两个函数,PWM_Init(void)可以打开定时器并开始输出PWM波,PWM_SetDuty(float dutycycle)可以改变PWM波的占空比,入口参数dutycycle是PWM波的占空比,它可以是小数,但由于计数值为199,所以PWM波的实际精度只能达到

1÷(199+1)*100%=0.5%,要提高精度需要提高计数值。

编译、下载、运行。将PA11连接到舵机的控制线上,可以看到舵机在两个位置间切换,转过的角度约为90°。