📄 timer.c
字号:
#include "includes.h"
#include "timer.h"
#include "interrupt.h"
/*******************************************************************************
*外设时钟列表,他们的tc_handling可以根据具体情况各自设置各自的,但对与中断程序入口
*函数OS_CPU_IRQ_ISR_Handler来说,他们的中断处理程序只有一个AT91F_TC_HANDLING,只是
*该函数的参数pTCBASE不同而已,各个时钟的特殊处理函数由AT91F_TC_HANDLING区分调用各自
*的tc_handling
*******************************************************************************/
TC tc_table[TC_CNT] = {
{AT91C_ID_TC0,0,AT91C_BASE_TC0,NULL},
{AT91C_ID_TC1,0,AT91C_BASE_TC1,NULL},
{AT91C_ID_TC2,0,AT91C_BASE_TC2,NULL},
{AT91C_ID_TC3,0,AT91C_BASE_TC3,NULL},
{AT91C_ID_TC4,0,AT91C_BASE_TC4,NULL},
{AT91C_ID_TC5,0,AT91C_BASE_TC5,NULL}
};
/*******************************************************************************
* 名称:SetTcPMC()
* 功能:设置时钟的时钟
* 入口参数:pTc 时钟设备的属性参数
* ID--//该设备的ID,目前用该外设的中断号
*
* 出口参数:无
* 说明:
*******************************************************************************/
void SetTcPMC(TC *pTc)
{
switch(pTc->Id)
{
case AT91C_ID_TC0:
AT91F_TC0_CfgPMC();
break;
case AT91C_ID_TC1:
AT91F_TC1_CfgPMC();
break;
case AT91C_ID_TC2:
AT91F_TC2_CfgPMC();
break;
case AT91C_ID_TC3:
AT91F_TC3_CfgPMC();
break;
case AT91C_ID_TC4:
AT91F_TC4_CfgPMC();
break;
case AT91C_ID_TC5:
AT91F_TC5_CfgPMC();
break;
default:
break;
}
}
/*******************************************************************************
* 名称:TC_init()
* 功能:时钟设备初始化函数
* 入口参数:tc 时钟设备的属性参数
* ID--//该设备的ID,目前用该外设的中断号
* dly--//该设备的定时周期,最小单位1ms
* tc_handling--//对设备的中断处理程序
* 出口参数:无
* 说明:设置对应时钟设备的定时周期及针对该时钟的中断处理程序,打开该设备自己的
* 中断使能位,同时把设备加入中断处理程序列表,打开中断控制器的对应中断使
* 能位
*******************************************************************************/
void TC_init(TC tc)
{
#if OS_CRITICAL_METHOD == 3
int cpu_sr;
#endif
unsigned int sr;
int idx;
TC *pTc;
OS_ENTER_CRITICAL();
if(tc.dly == 0)
{
OS_EXIT_CRITICAL();
return;
}
//根据中断号从同类设备的索引表中找出对应的序号
idx = Index_table[tc.Id];
//找出对应的时钟
pTc = tc_table + idx;
//填充时钟列表tc_table + idx
pTc->dly = tc.dly;
pTc->tc_handling = tc.tc_handling;
SetTcPMC(pTc);
//不采用外部时钟源
AT91C_BASE_TCB0->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_NONE | AT91C_TCB_TC2XC2S_NONE;
//关闭时钟的所有功能
pTc->pTCBASE->TC_CCR = AT91C_TC_CLKDIS; //Disable the clock 0
pTc->pTCBASE->TC_IDR = 0xffffffff;
//设置时钟的时钟源为主时钟的128分频
//设置工作方式,RC比较复位并重新开始记数
pTc->pTCBASE->TC_CMR = AT91C_TC_TCCLKS_MCK128 | AT91C_TC_CPCTRG;//0x03 --- 144k //0x04 --- SCLK == 32.678k
sr = pTc->pTCBASE->TC_SR;
//设置时钟周期,1ms为单位
pTc->pTCBASE->TC_RA =0;
pTc->pTCBASE->TC_RB =0;
pTc->pTCBASE->TC_RC =(unsigned int)(MASTER_CLK / 128 / TIMER_TICKS_PER_SEC * tc.dly);
//复位并开始时钟记数
pTc->pTCBASE->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
//使能RC比较中断,CV与RC比较
AT91F_TC_InterruptEnable(pTc->pTCBASE,AT91C_TC_CPCS);
//填充中断处理函数列表,供OS_CPU_IRQ_ISR_Handler查询使用
intConnect(pTc->Id,(AT91_REG)pTc->pTCBASE,AT91F_TC_HANDLING);
//设置该外设对应的中断控制器使能位
intEnable(pTc->Id);
OS_EXIT_CRITICAL();
}
/*******************************************************************************
* 名称:AT91F_TC_HANDLING()
* 功能:时钟中断处理函数
* 入口参数:tc_base 对应时钟外设的基地址
* tc_vector 对应的外设中断号
* 出口参数:无
* 说明:该函数是所有时钟外设的中断函数入口(与OS_CPU_IRQ_ISR_Handler的接口),在
* 该函数中判断具体的外设中断处理函数并执行
*******************************************************************************/
void AT91F_TC_HANDLING(int tc_base,int tc_vector)
{
volatile int sr;
int idx;
TC *pTC;
AT91C_BASE_SYS->AIC_IVR = 0L; /* Debug variant of vector read (protect mode is used) */
while ((sr = ((AT91PS_TC)tc_base)->TC_SR) & AT91C_TC_CPCS); /* Clear the tick interrupt source */
//根据中断号从同类设备的索引表中找出对应的序号
idx = Index_table[tc_vector];
pTC = tc_table + idx;
if(pTC->tc_handling)
pTC->tc_handling();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -