1.1 基本定时器
typedef enum
{
TIMER_A0 ,
TIMER_A1 ,
TIMER_A2 ,
TIMER_B0 ,
TIMER_NUM ,
}TIMERn; //定时器模块
1.2 定时器通道引脚、时钟选择
const GPIO_PIN TIMER_CHANEL_PIN[TIMER_NUM][TIMER_CH_NUM]=
{// CH0 CH1 CH2 CH3 CH4 CH5 CH6
{{P1,1},{P1,2},{P1,3},{P1,4},{P1,5}}, //TIMER_A0
{{P1,7},{P2,0},{P2,1}}, //TIMER_A1
{{P2,3},{P2,4},{P2,5}}, //TIMER_A2
{{P5,6},{P5,7},{P7,4},{P7,5},{P7,6},{P3,5},{P3,6}} //TIMER_B0
};//通道引脚
const GPIO_PIN TIMER_CLK_PIN[TIMER_NUM] =
{
{P1,0},//TIMER_A0----ACLK----
{P1,6},//TIMER_A1----ACLK----
{P2,2},//TIMER_A2----SMCLK----
{P7,7} //TIMER_B0----MCLK----
};//外部时钟输入引脚
2.定时器功能
2.1 实现基本定时
extern STATUS TIMER_Interval_Us (TIMERn, uint32_t us); //初始化一个us级的定时中断
#define TIMER_Interval_Ms(timer,ms) TIMER_Interval_Us(timer,(uint32_t)ms*1000)
2.1.1 中断向量设置传参
/*******************************************************************************
* 函数名称:Set_Vector_Handler(VECTORn vector,__interrupt void pfunc_handler(void))
* 功能说明:设置中断向量地址
* 参数说明:
VECTORn vector :中断向量(枚举变量,见.h文件)
__interrupt void pfunc_handler(void) : 中断服务函数
* 函数返回:无
* 使用示例:Set_Vector_Handler(VECTOR_PORT1,GPIO_IRQ_Handler); //设置PPORT1中断服务函数为GPIO_IRQ_Handler,需要先定义中断服务函数,另外最好先设置中断向量,再开启中断
********************************************************************************/
void Set_Vector_Handler(VECTORn vector, __interrupt void pfunc_handler(void))
{
if(SYSX->RIVECT == DISABLE) //如果没有设置中断向量表到RAM,则设置
{
Set_VectorTable_To_RAM(); //设置中断向量表到RAM
}
//此处若有警告可忽略
__VECTOR_RAM[vector] = (ISR_TYPE)pfunc_handler; //设置该中断向量地址
}
2.1.2 定时中断
/*******************************************************************************
* 函数名称:TIMER_Interval_Us(TIMERn timer,uint32_t us)
* 功能说明:定时器定时初始化(单位:us)
* 参数说明:TIMERn timer :定时器模块
uint32_t us : 定时时间
* 函数返回:不成功则返回ERROR,成功则返回SUCCESS
* 使用例程:TIMER_Interval_Us(TIMER_B0,2500); //TB定时间隔2.5ms中断
********************************************************************************/
STATUS TIMER_Interval_Us(TIMERn timer,uint32_t us)
{
#ifdef DELAY_TIMER
ASSERT((timer != DELAY_TIMER),
"TIMER_Interval_Us",
"定时器已经设置为默认延时功能,不能再作为其他功能使用"); //不允许这种情况下还宏定义该定时器作为延时所用的定时器,请在system.h里修改DELAY_TIMER宏定义
#endif
TIMERX[timer]->CLR = BIT_SET;//置位
TIMERX[timer]->SSEL = TIMER_SSEL_SMCLK;
TIMERX[timer]->ID = 0u;//分频系数清零
//计数值
uint32_t Counter_Value = (uint32_t)(us * g_sClock.SMCLK.fMHZ);
while(Counter_Value > 65536)
{
TIMERX[timer]->ID ++;
Counter_Value >>= 1;
if((TIMERX[timer]->ID == 3u) && (Counter_Value > 65536)) //这个时候意味得选择更低频率的时钟了
{
if(TIMERX[timer]->SSEL == TIMER_SSEL_ACLK) //如果时钟已经是最低的ACLK了,那么意味着设置的频率太低了,失败返回ERROR
{
return ERROR;
}
//更换为更低的ACLK,从新配置
TIMERX[timer]->SSEL = TIMER_SSEL_ACLK;
TIMERX[timer]->ID = 0u;
Counter_Value = (uint32_t)(us * g_sClock.ACLK.fMHZ);
continue;
}
}
if(Counter_Value <= 1)//出现这种情况,说明频率不合适
{
return ERROR;
}
TIMERX[timer]->CCR[0] = (uint16_t)(Counter_Value - 1u);//为什么要减一??因为TAR/TBR计数器从CCR0变化到0还有一个计数周期
TIMERX[timer]->CCTL[0].CAPMODE = RESET;//比较模式
TIMERX[timer]->IE = RESET; //关闭溢出中断
TIMERX[timer]->CCTL[0].IE = RESET; //关闭通道中断
TIMERX[timer]->MC = TIMER_MC_UP; //增计数模式
return SUCCESS;
}
2.1.3 初始化实例
DisableInterrupts(); //禁止总中断
Set_Vector_Handler(VECTOR_TIMER0_A0,TIMER_TA0_IRQ_Handler); //设置中断向量,最好先设置中断向量,在开启中断
TIMER_Interval_Ms(TIMER_A0,200);//初始化一个200ms的定时中断
//TIMER_Interval_Us(TIMER_A0,1000000); //初始化一个1000ms的定时中断,不要写为1000*1000,否则会提示超出范围
TIMER_ITConfig (TIMER_A0,TIMER_CCR0_IRQn,ENABLE);
EnableInterrupts();
__interrupt void TIMER_TA0_IRQ_Handler()
{
LED_Turn(LED2); //黄灯
//FLAG_10MS=1;
}
|