搜索
bottom↓
回复: 9

令我崩溃的AT91SAM7S64的定时器中断问题【恢复】

[复制链接]

出0入0汤圆

发表于 2009-1-16 20:47:17 | 显示全部楼层 |阅读模式
从早晨开始一直在调AT91SAM7S64的定时器中断,就是用定时器定时1S,然后产生中断实现二极管闪亮,中断已经实现,但是进一次中断后,定时器就不再产生中断了,让我近乎崩溃,哪位朋友指点一下啊,源码如下:

#include "Board.h"

#include "dbgu.h"

unsigned char  m=0,n=3;

/********************************************************************************************************

** 函数名称:DelayNS()

** 函数功能:长软件延时

** 入口参数:dly                延时参数,值越大,延时越久

** 出口参数:无

********************************************************************************************************/

void  DelayNS(unsigned long  dly)

{  

unsigned long  i;

for(; dly>0; dly--) 

for(i=0; i<60000; i++);

}



/********************************************************************************************************

** 函数名称:cuowu()

** 函数功能:警报

** 入口参数:无

** 出口参数:无

********************************************************************************************************/

void cuowu (void)

{

while(1)

{

DelayNS(50);

*AT91C_PIOA_ODSR&=0x00000002;

DelayNS(50);

*AT91C_PIOA_ODSR|=0xfffffffd;

}

}



/********************************************************************************************************

** 函数名称:time_init()

** 函数功能:定时器初始化

** 入口参数:无

** 出口参数:无

********************************************************************************************************/

void time_init(void)

{



*AT91C_PMC_PCER=(1<<12); // 打开电源



*AT91C_TC0_CCR=0x01;



*AT91C_TC0_CMR=((0x1<<15)|(0x2<<13)|0x4); // 波形模式 up带RC比较 1024分频 



*AT91C_TC0_RC= 65000; // 这里在晶振18.432时正好是 1秒钟



*AT91C_TC0_IER=(0x1<<4);//使能RC比较中断 



*AT91C_TC0_CCR=0x04; // 启动定时器

}



/********************************************************************************************************

** 函数名称:TC2ISR()

** 函数功能:中断执行

** 入口参数:无

** 出口参数:无

********************************************************************************************************/

void TC2ISR_c_irq_handler(void)

{

if(n%2)

{

*AT91C_PIOA_ODSR&=0xfffffffd;

}

else

{

*AT91C_PIOA_ODSR|=0x00000002;

}

n++;

*AT91C_AIC_EOICR =0x01;   /* 结束中断 */

}



/********************************************************************************************************

** 函数名称:AIC_init()

** 函数功能:中断初试化

** 入口参数:无

** 出口参数:无

********************************************************************************************************/

void AIC_init(void)

{

AT91C_AIC_SMR[12] = (0x0|(0x3<<5));       //优先级最低,沿边触发



AT91C_AIC_SVR[12]=(unsigned int)TC2ISR_c_irq_handler;    //中断入口



*AT91C_AIC_IECR=(1<<12);//系统级使能TC2中断

}



int main( void )

{

*AT91C_PIOA_PER=0xffffffff;                      //PIOA作为I/O使用  

*AT91C_PIOA_OER=0x00000006;                       //PIOA1-2输出使能

*AT91C_PIOA_OWER=0x00000006;

*AT91C_PIOA_SODR=0xffffffff;

time_init();                        //初始化定时器

AIC_init();                         //初始化中断

while(1)

{

DelayNS(30);

*AT91C_PIOA_ODSR|=0x00000004;       //熄灭

DelayNS(30);

*AT91C_PIOA_ODSR&=0xfffffffb;       //点亮

}

}



点击此处下载 ourdev_590484.rar(文件大小:281K) (原文件名:LED.rar) 

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2009-1-18 12:17:25 | 显示全部楼层
感觉国内用at91sam7s的人好少



at定时器这个玩意比较变态,每次进中断以后都要读一下SR来清除SR,否则中断就阻塞了



定时器中断要这样写



void TC2_Int_Handler(void) __irq

{

        // Read TC_SR to clear it

        DWORD dwKeyPort = AT91C_BASE_TC2->TC_SR; // 没这句是不行的,没这句中断只能玩一次

        

        AT91C_BASE_TC2->TC_CCR = AT91C_TC_SWTRG;

        AT91C_BASE_AIC->AIC_EOICR = 0;

}

出0入0汤圆

 楼主| 发表于 2009-1-18 23:41:48 | 显示全部楼层
在此,我非常非常感谢各位对我的解答,我按"Tomcat 菜猫"说的清除SR后,终于实现了能多次进入中断

为什么非要清空SR才行呢?AT真的太变态了,这个陷阱对于我来说实在太恶心了.

出0入0汤圆

 楼主| 发表于 2009-1-18 23:10:43 | 显示全部楼层
太谢谢各位的解答了,我这就试试,谢谢!!

出0入0汤圆

发表于 2009-1-18 21:36:07 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-1-17 23:07:01 | 显示全部楼层
这是iar4.30下一个标准的工程例子,仔细对比下看看初始化和中断服务函数的写法,个人经验觉得你的中断函数不对 ourdev_592264.rar(文件大小:620K) (原文件名:AT91SAM7X256-TC-IAR.rar) 

出0入0汤圆

 楼主| 发表于 2009-1-16 22:21:25 | 显示全部楼层
哎!这问题竟然也没人回答,得学会自立了

出0入0汤圆

发表于 2009-9-10 15:20:50 | 显示全部楼层
请问楼主改成怎样才好的啊 ?
我刚刚才接触,有点不明白

出0入0汤圆

发表于 2010-8-11 19:37:04 | 显示全部楼层
extern void SpiADCUpdate(void);
extern void TimerCallback(void);
void timer0_c_irq_handler(void)
{
        int temp = AT91C_BASE_TC0->TC_SR;
        temp = temp;
        TimerCallback();
//        AT91C_BASE_ADC->ADC_CR = 0x2;
//        ADC_flag = 1;
//        SpiADCUpdate();
//        printfd("0");
}


extern OS_EVENT *semTimer50us;
extern OS_EVENT *semTimer2;
void timer1_c_irq_handler(void)
{
//        static int flag=0;
        int temp = AT91C_BASE_TC1->TC_SR;
        temp = temp;
        AT91F_AIC_DisableIt (AT91C_BASE_AIC, AT91C_ID_TC1);       
        OSSemPost(semTimer50us);
//        if(flag){
//                AT91F_PIO_SetOutput(AT91C_BASE_PIOA, LED1);               
//        }       
//        else{
//                AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, LED1);               
//        }
//        flag=(flag+1)&1;       
//        printf("1");
}
void timer2_c_irq_handler(void)
{
//        static int flag=0;
        int temp = AT91C_BASE_TC2->TC_SR;

        if(temp&AT91C_TC_LDRAS)
        {
       
        }
//        AT91F_AIC_DisableIt (AT91C_BASE_AIC, AT91C_ID_TC2);       
//        OSSemPost(semTimer2);
//        if(flag){
//                AT91F_PIO_SetOutput(AT91C_BASE_PIOA, LED2);               
//        }       
//        else{
//                AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, LED2);               
//        }
//        flag=(flag+1)&1;
//        printf("2");
}

void AT91F_TC_Open ( AT91PS_TC TC_pt, unsigned int Mode, unsigned int TimerId)
{
        unsigned int dummy;
        //* First, enable the clock of the TIMER
        AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1<< TimerId ) ;
        //* Disable the clock and the interrupts
        TC_pt->TC_CCR = AT91C_TC_CLKDIS ;
        TC_pt->TC_IDR = 0xFFFFFFFF ;
        //* Clear status bit
        dummy = TC_pt->TC_SR;
        //* Suppress warning variable "dummy" was set but never used
        dummy = dummy;
        //* Set the Mode of the Timer Counter
        TC_pt->TC_CMR = Mode ;
        //* Enable the clock
        TC_pt->TC_CCR = AT91C_TC_CLKEN ;
}

void TimerInit0(void)
{
        // Open timer0
        AT91F_TC_Open(AT91C_BASE_TC0,AT91C_TC_CLKS_TIMER_DIV2_CLOCK|(1<<15)|(2<<13),AT91C_ID_TC0);
        AT91C_BASE_TC0->TC_RC = MCK/8UL/100UL;//div:8 , 100Hz interrupt
        // Open Timer 0 interrupt
        AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_TC0, TIMER0_INTERRUPT_LEVEL,AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, timer0_c_irq_handler);
        AT91C_BASE_TC0->TC_IER = AT91C_TC_CPCS;  //  IRQ enable CPC
        AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_TC0);
        // Generate interrupt by software
        //AT91F_AIC_Trig (AT91C_BASE_AIC,AT91C_ID_TC0) ;
        // Start timer0
        AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG ;       
}

void TimerInit1(void)
{
        // Open timer1  
        AT91F_TC_Open(AT91C_BASE_TC1,AT91C_TC_CLKS_TIMER_DIV1_CLOCK|(1<<15)|(2<<13)|(AT91C_TC_CPCSTOP),AT91C_ID_TC1);
        AT91C_BASE_TC1->TC_RC = MCK/2UL/20000UL;
        // Open Timer 1 interrupt
        AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_TC1, TIMER1_INTERRUPT_LEVEL,AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, timer1_c_irq_handler);
        AT91C_BASE_TC1->TC_IER = AT91C_TC_CPCS;  //  IRQ enable CPC
//        AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_TC1);
        // Generate interrupt by software
//        AT91F_AIC_Trig (AT91C_BASE_AIC,AT91C_ID_TC1) ;
        // Start timer1
//        AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG ;       
}

#if 0

void TimerInit2(void)
{

        // Open timer2  
        AT91F_TC_Open(AT91C_BASE_TC2,AT91C_TC_CLKS_TIMER_DIV1_CLOCK|(1<<15)|(2<<13)|(AT91C_TC_CPCSTOP),AT91C_ID_TC2);
        AT91C_BASE_TC2->TC_RC = MCK/2UL/20000UL;
        // Open Timer 2 interrupt
        AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_TC2, TIMER2_INTERRUPT_LEVEL,AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, timer2_c_irq_handler);
        AT91C_BASE_TC2->TC_IER = AT91C_TC_CPCS;  //  IRQ enable CPC

}
#endif

出0入0汤圆

发表于 2010-8-11 19:39:57 | 显示全部楼层
老外的代码唯一没看懂的地方,就是计算rc触发时间长度,,只看见一个100hz 的提示,然后我反着算,觉得不对,arm可是有48mhz呢,用2分频的话,每个间断也得有0.03us啊? 然后就开始迷糊了,特别是UL这个单位,,,,恐怕得找到定义。。

不过老外写的蛮容易懂的。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 07:16

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表