⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 timer.c

📁 AT91RM9200-UC/OS-II,clock,irq,usart,pio等驱动
💻 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 + -