蓝桥杯嵌入式第四课--定时器
蓝桥杯对于定时器这部分的考察主要集中在定时器中断PWM输出以及输入捕获三个方面,本节课着眼于应用,介绍一下定时器的使用。
前言
蓝桥杯对于定时器这部分的考察主要集中在定时器中断、PWM输出以及输入捕获三个方面,本节课着眼于应用,介绍一下定时器的使用。
定时器中断
一、基础概念
对没接触过定时器的新手来说,如果想要快速上手定时器的使用,首先要先对定时器建立一个初步的印象。我们所说的定时器,从本质上看其实是一个计数器,可以从零开始计数,计到一个最大值,我们称其为 自动重装载值(ARR),然后清零,再重新开始计数,如此往复。这就是最基础也是最常用的向上计数模式,在此基础上,还有向下计数,和中央对齐计数(即从0到ARR,再从ARR到0)。
在计数器的基础上打个比方,如果我们需要定时10秒,我们只需让计数器每秒加1,加到10之后告诉我们时间到了,然后再从零开始即可。
针对上面的描述,我们又引出一个参数:定时器的频率。针对我们的比赛,计数器每计一个数需要消耗的时间 t = 系统时钟频率/预分频值。也就是:
f = 80Mhz/psc
并且,定时器到时间后还需要提醒我们,因此,每当计数值满了时(即溢出),都要产生一个定时器中断。
二、配置操作
一、CubeMx激活定时器
如上图所示:
选择一个定时器
选择定时器的时钟源
配置定时器的预分频系数 Prescaler、以及自动重装载值ARR
这里的重点在于Psc参数和ARR参数的设置。公式如下:
二、使能中断
我们使用定时器的更新中断作为实验的中断源。
三、编写代码
定时器中断主要添加两个函数即可:
HAL_TIM_Base_Start_IT(&htim1); //该函数开启定时器,置于main.c中定时器初始化代码之后
以及回调函数:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){ //置于main()函数之后
if(htim == &htim1) //判断中断是否来自于定时器1
{
代码;
}
}
这样当计数器溢出时,中断就会触发,并执行回调函数。
四、实验任务
如果你现在看到这了,请完成一个,每隔1s加一的计时器,并将结果显示在LCD上(5分钟即可解决,代码后续我会附上)。
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();
HAL_TIM_Base_Start_IT(&htim1); //启动计数
LCD_Init();
/* USER CODE BEGIN 2 */
char text[30];
/* Infinite loop */
/* USER CODE BEGIN WHILE */
LCD_Clear(White);
LCD_SetBackColor(Blue);
LCD_SetTextColor(Black);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
sprintf(text," t = %d ",i);
LCD_DisplayStringLine(Line4,(unsigned char *)text);
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if(htim == &htim1) //判断中断是否来自于定时器1
{
i++;
}
}
任意占空比PWM输出
一、基础概念
PWM输出其实是在定时器的基础上发展而来的一个外设。核心原理就是设置一个数,我们称之为CCR(比较寄存器),当我们的计数值CNT小于CCR时,输出高电平,大于CCR时,输出低电平,只要我们改变CCR的值就可以实现占空比可调的PWM波输出。
二、配置操作
选择输出管脚
像上面这种带N的和其它一些奇怪的都不要选择,我们可以选择TIM4_CH4作为输出PWM的定时器通道。
选择时钟源和输出模式
3.配置定时器的PSC和ARR
这两个参数对PWM的频率产生决定性的影响,需要好好计算一下,上面的参数配置了PWM的频率为1000Hz。
4.配置通道的参数
对于通道而言,这个的Mode选择PWM mode 1,并且,Pulse参数设置的是占空比,这里我们设置为零,这个参数在程序中可以通过函数进行实时设置。
三、编写代码
在代码中,需要补充如下函数:
1、HAL_TIM_PWM_Start;开启PWM输出
/**
* @brief Starts the PWM signal generation.
* @param htim TIM handle
* @param Channel TIM Channels to be enabled
* This parameter can be one of the following values:
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
* @arg TIM_CHANNEL_3: TIM Channel 3 selected
* @arg TIM_CHANNEL_4: TIM Channel 4 selected
* @arg TIM_CHANNEL_5: TIM Channel 5 selected
* @arg TIM_CHANNEL_6: TIM Channel 6 selected
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
与此对应还有
HAL_StatusTypeDef HAL_TIM_PWM_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
2、__HAL_TIM_SetCompare;设置占空比
__HAL_TIM_SetCompare(&htimx, TIM_CHANNEL_x, pwm_value);
3、_HAL_TIM_SET_AUTORELOAD;设置频率
__HAL_TIM_SET_AUTORELOAD(&htimx, prc_value);
小结
定时器最基本的两个应用就是定时器中断和PWM输出。定时器的配置过程为:
设置分频系数PSC与自动重装载值ARR,以确定定时器中断的触发时间
打开定时器中断
代码中启动定时器HAL_TIM_Base_Start_IT以及编写回调函数HAL_TIM_PeriodElapsedCallback
PWM的配置过程在前面基础上(可不开启中断):
配置PWM的模式,以及CCR寄存器值,以确定占空比
代码中启动PWM:HAL_TIM_PWM_Start,并且设置占空比__HAL_TIM_SetCompare与频率_HAL_TIM_SET_AUTORELOAD;
下一篇文章介绍输入捕获的配置!
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)