硬件开发板:STM32G0B1RET6
软件平台:cubemax+keil+VScode
1 新建cubemax工程
1.1 配置系统时钟RCC
1.2 配置定时器
选择高级定时器TIM1
,使用内部时钟源,通道1输出,预分频系数为64000-1
,重装载值为1000-1
,此时PWM信号周期为1s
,占空比为500(50%))
,对应的芯片引脚是PA8
使能中断
2 代码
2.1 定义变量
/* USER CODE BEGIN PV */
uint16_t RCR_num; //写入重复计数器RCR的计数值
/* USER CODE END PV */
2.2 PWM指定个数输出函数
/* USER CODE BEGIN 0 */
/*设置PWM输出个数*/
void PWM_num_Set(uint16_t pwm_num)
{
__HAL_TIM_ENABLE_IT(&htim1, TIM_IT_UPDATE); /*使能定时器更新中断*/
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); /*开启PWM输出*/
if(pwm_num == 0)
return; //返回
else
{
RCR_num = pwm_num; //赋值给重复计数器
HAL_TIM_GenerateEvent(&htim1, TIM_EVENTSOURCE_UPDATE); //通过软件启动更新事件
__HAL_TIM_ENABLE(&htim1); //启动计数器
}
}
/* USER CODE END 0 */
2.3 回调函数
重复定时器工作原理:
计数器每次溢出都能使重复计数器减一,减到0时,再发生溢出就会产生更新事件
/* USER CODE BEGIN 4 */
/*更新中断回调函数*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim == &htim1)
{
if(RCR_num) //判断设置的pwm数量
{
TIM1->RCR = RCR_num-1; //要想产生N个pwm将N-1放入RCR寄存器中
HAL_TIM_GenerateEvent(&htim1, TIM_EVENTSOURCE_UPDATE); //通过软件启动更新中断将设定值放入影子寄存器中
__HAL_TIM_ENABLE(&htim1); //使能计数器产生进行PWM输出
RCR_num = 0; //清零;若不清零,会持续输出PWM
}
else
{
TIM1->CR1 &= ~(1 << 0); //关闭计数器
}
}
}
/* USER CODE END 4 */
关闭计数器的注意事项
之所以通过寄存器操作TIM1->CR1 &= ~(1 << 0);
来关闭计数器,而不使用__HAL_TIM_DISABLE(&htim1);
,是因为__HAL_TIM_DISABLE(&htim1);
需要判断输出通道TIM_CCER_CCxE_MASK
和互补输出通道TIM_CCER_CCxNE_MASK
是否关闭,只有两个通道关闭后才能正常关闭计数器,代码如下:
故直接寄存器操作关闭计数器更方便
2.4 main函数
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();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_TIM1_Init();
/* USER CODE BEGIN 2 */
PWM_num_Set(3); /*设置输出3个PWM*/
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
3 实验现象
用杜邦线连接PA8
和pa5
,就可以利用输出的PWM驱动LED,根据LED亮灭情况,可判断PWM的输出情况