需求描述
用寄存器实现。输出5个周期的PWM波,频率2Hz,观察发光二极管闪烁5次,或者用示波器观察波形。
需求实现思路:使用高级定时器的重复计数器,当计数器溢出时,在溢出中断中停止定时器工作。重复计数器寄存器的值设置为4,即可输出5个周期的PWM波,发光二极管会闪烁5次。
使用到的寄存器
设置重复计数器

主输出使能


寄存器实现
tim1.h
#ifndef __TIM1_H
#define __TIM1_H
#include "stm32f10x.h"
#include <stdio.h>
void TIM1_Init(void);
// 将定时器的开关包装成函数
void TIM1_Start(void);
void TIM1_Stop(void);
#endiftim1.c
#include "tim1.h"
void TIM1_Init(void)
{
// 1. 开启时钟
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
// 2. GPIO工作模式,PA8:复用推挽输出 CNF-10,MODE-11
GPIOA->CRH |= GPIO_CRH_MODE8;
GPIOA->CRH |= GPIO_CRH_CNF8_1;
GPIOA->CRH &= ~GPIO_CRH_CNF8_0;
// 定时器配置
// 3. 时基部分
// 3.1 预分频值 7199,得到 10000 Hz
TIM1->PSC = 7199;
// 3.2 重装载值,4999,每0.5s产生一次溢出
TIM1->ARR = 4999;
// 3.3 计数方向
TIM1->CR1 &= ~TIM_CR1_DIR;
// 3.4 重复计数
TIM1->RCR = 4;
// 4. 输出通道部分
// 4.1 配置通道1为输出模式
TIM1->CCMR1 &= ~TIM_CCMR1_CC1S;
// 4.2 配置通道1为 PWM1 模式,OC1M - 110
TIM1->CCMR1 |= TIM_CCMR1_OC1M_2;
TIM1->CCMR1 |= TIM_CCMR1_OC1M_1;
TIM1->CCMR1 &= ~TIM_CCMR1_OC1M_0;
// 4.3 配置CCR,占空比50%
TIM1->CCR1 = 2500;
// 4.4 配置极性
TIM1->CCER &= ~TIM_CCER_CC1P;
// 4.5 产生一个更新事件,刷新寄存器的值
TIM1->CR1 |= TIM_CR1_URS;
TIM1->EGR |= TIM_EGR_UG;
// TIM1->SR &= ~TIM_SR_UIF;
// 4.6 通道1使能
TIM1->CCER |= TIM_CCER_CC1E;
// 4.7 主输出使能
TIM1->BDTR |= TIM_BDTR_MOE;
// 5. 中断功能
// 5.1 更新中断使能
TIM1->DIER |= TIM_DIER_UIE;
// 5.2 NVIC配置
NVIC_SetPriorityGrouping(3);
NVIC_SetPriority(TIM1_UP_IRQn, 3);
NVIC_EnableIRQ(TIM1_UP_IRQn);
}
// 将定时器的开关包装成函数
void TIM1_Start(void)
{
TIM1->CR1 |= TIM_CR1_CEN;
}
void TIM1_Stop(void)
{
TIM1->CR1 &= ~TIM_CR1_CEN;
}
// 中断服务程序
void TIM1_UP_IRQHandler(void)
{
printf("into interrupt...\n");
// 清除中断标志位
TIM1->SR &= ~TIM_SR_UIF;
// 停掉定时器
TIM1_Stop();
}main.c
#include "usart.h"
#include "tim1.h"
#include "delay.h"
int main(void)
{
// 初始化
USART_Init();
TIM1_Init();
printf("Hello, world!\n");
// 开启定时器
TIM1_Start();
while (1)
{
}
}HAL库实现
HAL库配置



tim.c
/* USER CODE BEGIN 1 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
/* 关闭计数器 */
if (htim->Instance == TIM1)
{
//HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);
TIM1->CCER &= ~TIM_CCER_CC1E;
TIM1->BDTR &= ~TIM_BDTR_MOE;
htim->Instance->CR1 &= ~TIM_CR1_CEN;
}
}
/* USER CODE END 1 */main.c
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM1_Init();
MX_USART1_UART_Init();
/*初始化的时候 UG已经被置位. 先清除中断标志位,防止一启动就进入中断 */
__HAL_TIM_CLEAR_IT(&htim1, TIM_IT_UPDATE);
/* 启用更新中断 */
__HAL_TIM_ENABLE_IT(&htim1, TIM_IT_UPDATE);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
while (1)
{
}
}