|
我设置了TC0定时器RC比较中断,RC寄存器能启动比较并复位清零,但到计数设定值确始终进不了中断,不知道为何?盼各位高手指点下子!谢谢
程序原代码:
#define XOS_Time_ticks_per_sec 5/*一秒中断5次 即:200ms一个时钟*/
#define OS_Tick_freq ((32768/XOS_Time_ticks_per_sec)-1)//1/(32768/65536)
//定时器0初始化
void Time0_Init(void)
{ volatile uint32 dummy;
//使能TC0外设时钟电源,PMC_PCER,使能TCO外部处理器时钟
AT91F_TC0_CfgPMC();
//使能PMC主时钟
//*AT91C_PMC_SCER |= 1;
/***************************************************************************/
//禁用TC0计数器,禁用TCO时钟 (TC0计数器时钟使能命令无效、TC0计数器时钟禁用命令无效、TC0软件触发命令无效)
*AT91C_TC0_CCR = AT91C_TC_CLKDIS;
//中断禁用寄存器:TC_IDR,禁止所有TC0中断使能和比较
*AT91C_TC0_IDR = 0xffffffff;
//TC状态寄存器寄存器名称: TC_SR 只读取当前TC0状态标志.清中断源,读取SR状态位
dummy = *AT91C_TC0_SR;
dummy = dummy;
//中断屏蔽寄存器寄存器名称: TC_IMR 只读取当前TC0中断使能标志,不可写入操作
//TC0模式寄存器设置
//TCCLKS: 时钟选择为TIMER_CLOCK5,UP 模式,有RC 比较自动触发
//TIMER_CLOCK1 = MCK/2 =59,904000MHz/2
//TIMER_CLOCK2 = MCK/8
//TIMER_CLOCK3 = MCK/32
//TIMER_CLOCK4 = MCK/128
//TIMER_CLOCK5 = MCK/1024 = 59,904000MHz/1024 = 0.0585MHz
AT91C_BASE_TC0->TC_CMR =
//TCCLKS=8,时钟选择TIMER_CLOCK5; 200mS中断 65536/OS_Tick_freq=200ms
AT91C_TC_CLOCK5|
//WAVESEL=10,UP 模式,有RC比较自动触发
AT91C_TC_WAVESEL_UP_AUTO|
//WAVE=1,波形模式使能
AT91C_TC_WAVE|
AT91C_TC_CPCTRG
;
//RA,RB,RC实时寄存器复初始值
*AT91C_TC0_RC = OS_Tick_freq;
/*********************************************************************/
//禁止AIC所有中断向量,禁止AIC中断TCO向量,AIC_IDCR,AIC_ICCR
AT91F_AIC_DisableIt(AT91C_BASE_AIC, 0xFFFFFFFF);//AT91F_AIC_DisableIt(AT91C_BASE_AIC, AT91C_ID_TC0);
//清除 TC0 interrupt 标志位
*AT91C_AIC_ICCR = (1 << AT91C_ID_TC0);
//结束AIC中TC0中断命令
AT91F_AIC_AcknowledgeIt(AT91C_BASE_AIC);
//AIC中断地址配置、优先级、触发模式配置、中断地址入口函数
AT91F_AIC_ConfigureIt(
AT91C_BASE_AIC, // AIC base address 0xfffff000
AT91C_ID_TC0, // SYSTEM peripheral ID
AT91C_AIC_PRIOR_HIGHEST, // Max priority
AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE,//Internal Sources Code Label Edge triggered
Time0_asm_handler);
//TC0计数器COUNTER值寄存器清
*AT91C_TC0_CV = 0;
//使能TC0时钟计数
*AT91C_TC0_CCR = AT91C_TC_CLKEN;
//TC0,使能RC比较中断 TC_IER ,设置中断触发方式
*AT91C_TC0_IER = AT91C_TC_CPCS;
//AIC中断向量使能
*AT91C_AIC_IECR = (1 << AT91C_ID_TC0);
//触发一次中断
AT91F_AIC_Trig(AT91C_BASE_AIC,AT91C_ID_TC0);
//开始计时
*AT91C_TC0_CCR = AT91C_TC_SWTRG;}
//定时器0中断
void Time0_c_handler(void)
{ volatile uint32 dummy;
// int tmp;
//中断结束处理
//清中断源,读取SR状态位
dummy = *AT91C_TC0_SR;
dummy = dummy;
//清除TC0中断向量
*AT91C_AIC_ICCR = (1 << AT91C_ID_TC0);
//中断结束处理
*AT91C_AIC_EOICR = 0;}
//主函数
int main()
{ //定时器0初始化
Time0_Init();
//AT91F_DBGU_Printk("\n\rBasicBoot Successfull: Enter main()\n\r");
while (1)
{ /*(temp1==1)
{
*AT91C_PIOA_OER = ((uint32)0x1)<<21;
*AT91C_PIOA_OER = ((uint32)0x1)<<22;
}
else
{
*AT91C_PIOA_ODR = ((uint32)0x1)<<21;
*AT91C_PIOA_ODR = ((uint32)0x1)<<22;
}*/
}
}
汇编部分代码:
;----------------------------------------------------------------------------
;- IRQ Entry
;----------------------------------------------------------------------------
MACRO
IRQ_ENTRY $reg
;- Adjust and save LR_irq in IRQ stack
sub r14, r14, #4
stmfd sp!, {r14}
;- Write in the IVR to support Protect Mode
;- No effect in Normal Mode
;- De-assert the NIRQ and clear the source in Protect Mode
ldr r14, =AT91C_BASE_AIC
str r14, [r14, #AIC_IVR]
;- Save SPSR and r0 in IRQ stack
mrs r14, SPSR
stmfd sp!, {r0, r14}
;- Enable Interrupt and Switch in SYS Mode
mrs r0, CPSR
bic r0, r0, #I_BIT
orr r0, r0, #ARM_MODE_SYS
msr CPSR_c, r0
;- Save scratch/used registers and LR in User Stack
IF "$reg" = ""
stmfd sp!, { r1-r3, r12, r14}
ELSE
stmfd sp!, { r1-r3, $reg, r12, r14}
ENDIF
MEND
;----------------------------------------------------------------------------
;- IRQ Exit
;----------------------------------------------------------------------------
MACRO
IRQ_EXIT $reg
;- Restore scratch/used registers and LR from User Stack
IF "$reg" = ""
ldmia sp!, { r1-r3, r12, r14}
ELSE
ldmia sp!, { r1-r3, $reg, r12, r14}
ENDIF
;- Disable Interrupt and switch back in IRQ mode
mrs r0, CPSR
bic r0, r0, #ARM_MODE_SYS
orr r0, r0, #I_BIT:OR:ARM_MODE_IRQ
msr CPSR_c, r0
;- Mark the End of Interrupt on the AIC
ldr r0, =AT91C_BASE_AIC
str r0, [r0, #AIC_EOICR]
;- Restore SPSR_irq and r0 from IRQ stack
ldmia sp!, {r0, r14}
msr SPSR_cxsf, r14
;- Restore adjusted LR_irq from IRQ stack directly in the PC
ldmia sp!, {pc}^
MEND
;------------------------------------------------------------------------------
;- Called Functions : Time0_c_handler
;- Called Macros : IRQ_ENTRY, IRQ_EXIT
;------------------------------------------------------------------------------
EXPORT Time0_asm_handler
IMPORT Time0_c_handler
Time0_asm_handler
IRQ_ENTRY
ldr r0, =Time0_c_handler
mov r14, pc
bx r0
IRQ_EXIT
;
END |
阿莫论坛20周年了!感谢大家的支持与爱护!!
一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。
|