ARM课作业五:timer定时器

一、引言

介绍

TIMER定时器是一种广泛应用于微控制器中的硬件模块,用于实现精确的时间测量和控制。定时器可以产生精确的延时、计数事件和定时中断,支持多种工作模式如单次、连续、PWM(脉宽调制)和捕获比较等。它们在控制系统中扮演着重要角色,被广泛应用于实时控制、信号生成、频率测量和事件计数等场景。

工作原理

TIMER定时器的工作原理是通过内部时钟源驱动一个计数器,根据预设的分频器将时钟频率分频后进行计数。当计数器达到预设的自动重载值时,会产生溢出事件或中断,触发相应的处理程序。定时器可以配置为向上计数、向下计数或双向计数模式,通过设定不同的计数值和触发条件,定时器可以实现精准的定时、PWM输出、输入捕获和输出比较等功能。

二、代码

1.main.c

GENERAL_TIMx_Configuration()用来初始化通用定时器,使其每1毫秒触发一次中断并执行中断服务函数(见tim.c)使timer_count+1

程序在主循环中不断检查timer_count的值,当timer_count达到500,即0.5s时,将其重置为0,并调用LED1_Turn()切换LED的状态,循环往复,则实现每0.5s切换一次LED的状态,实现LED的周期性闪烁

#include "stm32f10x.h"                  
#include "LED.h"
#include "tim.h"

__IO uint16_t timer_count=0;

int main(void)
{  
  /* 初始化板载LED灯 */  
   LED_Init();  
  
  /* 通用定时器初始化:1ms中断一次  */
  GENERAL_TIMx_Configuration();  
  
  /* 无限循环 */
  while (1)
  {
    if(timer_count==500)
    {
      timer_count=0;
      LED1_Turn();
    }
  }
}

2.tim.c

GENERAL_TIMx_NVIC_Configuration()用于中断优先级配置

GENERAL_TIMx_Configuration()用于初始化并配置定时器,使其每1毫秒触发一次中断

GENERAL_TIM_INT_FUN()是定时器的中断服务程序,当定时器产生更新事件(每1毫秒)时调用,用于使timer_count+1

具体请见代码旁的注释

#include "stm32f10x.h"  
#include "tim.h"

// 计数器变量,记录定时器中断次数
extern __IO uint16_t timer_count;

/**
  * 函数功能: 通用定时器 TIMx,x[2,3,4,5]中断优先级配置
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:配置定时器中断的优先级
  */
void GENERAL_TIMx_NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure; 

  /* 设置中断优先级分组 */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);		

  /* 设置中断来源为通用定时器的中断 */
  NVIC_InitStructure.NVIC_IRQChannel = GENERAL_TIM_IRQ;	

  /* 设置主优先级为 0 */
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;	 

  /* 设置抢占优先级为3 */
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;

  /* 使能定时器中断 */
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  /* 应用中断配置 */
  NVIC_Init(&NVIC_InitStructure);
}
 
/**
  * 函数功能: 通用定时器 TIMx,x[2,3,4,5]配置
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:初始化定时器,使其每1毫秒触发一次中断
  */
void GENERAL_TIMx_Configuration(void)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
 
  /* 开启TIMx的时钟,TIMx内部时钟CK_INT=72M */
  GENERAL_TIM_APBxClock_FUN(GENERAL_TIM_CLK, ENABLE);
  
  /* 配置定时器中断优先级 */
  GENERAL_TIMx_NVIC_Configuration();
  
  /* 设置自动重装载寄存器值(计数值) */
  TIM_TimeBaseStructure.TIM_Period = 1000 - 1;

  /* 设置预分频器,时钟分频为72(71 + 1),即定时器计数频率为1MHz */
  TIM_TimeBaseStructure.TIM_Prescaler = 71;

  /* 时钟分频因子(未使用) */
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

  /* 设置计数模式为向上计数 */
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 

  /* 初始化定时器TIMx */
  TIM_TimeBaseInit(GENERAL_TIMx, &TIM_TimeBaseStructure);
 
  /* 清除定时器更新中断标志位 */
  TIM_ClearITPendingBit(GENERAL_TIMx, TIM_IT_Update);

  /* 使能定时器更新中断 */
  TIM_ITConfig(GENERAL_TIMx, TIM_IT_Update, ENABLE);
 
  /* 启动定时器 */
  TIM_Cmd(GENERAL_TIMx, ENABLE); 
}

/**
  * 函数功能: 通用定时器中断处理函数
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:在定时器产生更新事件时调用,增加计数器timer_count
  */
void GENERAL_TIM_INT_FUN(void)
{
    /* 检查更新中断标志位是否置位 */
	if (TIM_GetITStatus(GENERAL_TIMx, TIM_IT_Update) != RESET) 
	{	
		/* 增加计数器timer_count */
		timer_count++;

		/* 清除定时器更新中断标志位 */
		TIM_ClearITPendingBit(GENERAL_TIMx, TIM_IT_Update);  		 
	}		 	
}

 3.tim.h

 配置通用定时器 TIM2,进行宏定义和函数声明。

#ifndef __TIM_H__
#define __TIM_H__
 
#include <stm32f10x.h>
#define GENERAL_TIMx                 TIM2
#define GENERAL_TIM_APBxClock_FUN    RCC_APB1PeriphClockCmd
#define GENERAL_TIM_CLK              RCC_APB1Periph_TIM2
#define GENERAL_TIM_IRQ              TIM2_IRQn
#define GENERAL_TIM_INT_FUN          TIM2_IRQHandler
 
void GENERAL_TIMx_Configuration(void);
void GENERAL_TIMx_NVIC_Configuration(void);
void GENERAL_TIM_INT_FUN (void);
#endif	

4.其他

LED.c和之前一样不用改

三、实验结果

每0.5s切换一次状态,每1秒实现一次亮灭

作业五

四、总结

这次作业让我更好地了解了TIMER定时器,在老师给的代码基础上进行修改,顺利完成了本次作业,锻炼了我的动手实践能力,拓展了专业知识,令我受益匪浅

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值