首页 > 代码库 > 第八章:STM32定时器
第八章:STM32定时器
时间:2014年8月15日
一、定时器种类:
1、四个可同步运行的通用定时器(TIM2~TIM5),每个均有一个16位的自动加载递增/递减计数器、一个16位预分频器和4个独立的通道。
2、两个16位高级控制定时器(TIM1和TIM8)
特点:由一个可编程预分频器驱动的16为自动装载 计数器组成,与通用定时器有共同处,但功能更强大。
3、两个基本定时器(TIM6和TIM7)
特点:主要用于产生DAC触发信号,也可以当作通用的16为时基计数器
4、实时时钟RTC
特点:能提供日历/时钟、数据存储等功能。常用作各种计算机系统的时钟信号源和参数设置存储电路。计算准、体积小功耗低。
5、看门狗(Watchdog)
特点:用于出错矫正。
6、SysTick时钟(位于CM3内核)
特点:24位递减计数器,计数到0,自动重装,同时内部COUNTFLAG标志置位。
二、通用定时器TIMx的功能(略)
2.1、时钟源选择
计数器时钟可由下列时钟源提供:内部时钟(CK_INT)、外部时钟模式1(输入脚TIx)、外部时钟模式2(外部触发输入ETR)、内部触发(ITRx,一个定时器可作为另外一个定时器的预分频器)
2.2、时基单元
包括计数器寄存器(TIMx_CNT)、预分频寄存器(TIMx_PSC)和自动装载寄存器(TIMX_ARR)等。
初始化相关数据结构:
typedef struct
{
u16 TIM_Prescaler; //预分频因子
u16 TIM_CounterMode ; //定时器模式
u16 TIM_Period; //定时器周期个数
u16 TIM_ClockDivision; // 定时器分频因子
u8 TIM_RepetitionCounter;
} TIM_TimeBaseInitTypeDef;
注:1、TIM_Prescaler:写入预分频器中。a、新的参数要在下一次更新时间来临时被采用。b、计数器由预分频器的时钟输出CK_CNT驱动,需要设置计数器TIMx_CR1中的计数器使能位。
2、TIM_TimeBaseInitTypeDef:设置干扰的频率限制,对应TIMx_CR1中的第八和第9位的CKD[1:0]
2.3、计数器模式(略)
2.4、定时时间计算
T=(TIM_Prescaler+1)X(TIM_Period+1)/TIMxCLK
2.5、定时器中断
TIM2中断通道序号为28,默认优先级35
1)初始化过程:设置寄存器AIRC中PRIGROUP的值,设置优先级的分配——>设置TIM2寄存器,允许相应中断——>设置TIM2的优先级(IP[28])——>设置允许TIM2中断通道。
2)中断响应过程:TIM2的UIE条件成立,TIM2本身中断标志置位,——>申请中断——>Pending标志置位——>执行中断服务程序——>硬件清除Pending标志位
3)执行TIM2的中断服务程序:所有TIM2的中断事件都在一个TIM2中断服务中完成,故需要在中断程序中判断是哪个中断源要服务!
三、实例1
【程序功能】数码管每个1s加一,到F跳转到0(用定时器2中断实现)
1)、主程序初始化
/* TIM2, GPIOA and GPIOB clock enable */RCC初始化配置
RCC_APB2PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB2Periph_GPIOA |
RCC_APB2Periph_GPIOB, ENABLE);
/****************NVIC初始化****************************/
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
#ifdef VECT_TAB_RAM
/* Set the Vector Table base location at 0x20000000 */
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else /* VECT_TAB_FLASH */
/* Set the Vector Table base location at 0x08000000 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif
/* Enable the TIM1 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/*****************GPIO配置************************************
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* GPIOA Configuration: */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
/*******************************************************************************
*
* 主函数
*
*******************************************************************************/
int main(void)
{
#ifdef DEBUG
debug();
#endif
RCC_Configuration(); //系统时钟配置
NVIC_Configuration(); //NVIC配置
GPIO_Configuration(); //通用IO端口配置
/*-----------------------------------------------------------------------------*/
/***72M下定时值的计算((1+预分频TIM_Prescaler)/72*(1+定时周期TIM_Period))*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //配置RCC,使能TIMx
/* Time Base configuration */
TIM_TimeBaseStructure.TIM_Prescaler = 7199; //时钟预分频数 例如:时钟频率=72/(时钟预分频+1)
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; ////定时器模式 向上计数
TIM_TimeBaseStructure.TIM_Period = 9999;//自动重装载寄存器周期的值(定时时间)累计 0xFFFF个频率后产生个更新或者中断(也是说定时时间到)
TIM_TimeBaseStructure.TIM_ClockDivision = 0; ////时间分割值
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //初始化定时器2
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); //打开中断 溢出中断
//打开定时器
TIM_Cmd(TIM2, ENABLE);
/* Main Output Enable */
TIM_CtrlPWMOutputs(TIM2, ENABLE);
while (1)
{
GPIO_Write( GPIOB , LED7Code[Count%16]<<8); //将Count数据送到GPIOB高八位
}
}