打印
[DSP编程]

求助:关于c5515 TIMER0 中断问题

[复制链接]
2308|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xzhihui|  楼主 | 2013-8-23 14:01 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 xzhihui 于 2013-8-23 14:40 编辑

需要实现一个定时器中断来采集信号。但是弄了两天了也没调试好。向各位坛友求助。
代码使用的是官方提供的函数库。


测试函数:
Int16 CSL_gptIntrTest(void)
{
        CSL_Handle    hGpt;  // 通用定时器的句柄
        CSL_Status           status;//寄存器操作后的状态
        CSL_Config           hwConfig;//定时器配置参数
        CSL_GptObj          gptObj;//结构体对象

        hitIsr   = FALSE;//中断标志
        status   = 0;//状态初始化

        hGpt = GPT_open (GPT_0, &gptObj, &status);//打开通用定时器并获取结构体
        if((NULL == hGpt) || (CSL_SOK != status))//检验打开后返回的状态
        {
                printf("GPT Open Failed\n");
                return (CSL_TEST_FAILED);
        }
        else
        {
                printf("GPT Open Successful\n");
        }

        IRQ_clearAll();//清除中断标志
        IRQ_disableAll();//关闭所有中断
        
        status = GPT_reset(hGpt);定时器复位
        if(CSL_SOK != status)//检测复位后状态
        {
                printf("GPT Reset Failed\n");
                return (CSL_TEST_FAILED);
        }
        else
        {
                printf("GPT Reset Successful\n");
        }


        IRQ_setVecs((Uint32)(&VECSTART));//配置中断向量表
        IRQ_plug(TINT_EVENT, &gpt0Isr);//设置中断事件地址
        IRQ_enable(TINT_EVENT);//定时器中断使能

        hwConfig.autoLoad          = GPT_AUTO_ENABLE;//使能自动计时器装载
        hwConfig.ctrlTim          = GPT_TIMER_ENABLE;//定时器使能
        hwConfig.preScaleDiv = GPT_PRE_SC_DIV_7;//预分频寄存器0111,对应256的分频值
        hwConfig.prdLow          = (100000)/4;//计时器加载值的周期(低位),时钟频率为100M
        hwConfig.prdHigh          = 0x0000;//计时器加载值的周期(高位),

        status =  GPT_config(hGpt, &hwConfig);//配置定时器对应的寄存器
        if(CSL_SOK != status)//检验
        {
                printf("GPT Config Failed\n");
                return (CSL_TEST_FAILED);
        }
        else
        {
                printf("GPT Config Successful\n");
        }

        IRQ_globalEnable();//开启全局中断
        
        GPT_start(hGpt);//开启定时器

       while(hitIsr != TRUE)//等待中断,程序就停在这里,中断始终没有触发
        {
                cpuCycleCount++;
        }

        IRQ_globalDisable();//关闭CPU中断

        IRQ_clearAll();//清除所有中断标志

        IRQ_disableAll();//禁止所有中断

        status = GPT_stop(hGpt);//停止计时器计数
        if(CSL_SOK != status)
        {
                printf("GPT Stop Failed \n");
                return (CSL_TEST_FAILED);
        }
        else
        {
                printf("GPT Stop Successful\n");
        }

        status = GPT_reset(hGpt);//复位
        status = GPT_close(hGpt);//关闭
        if(CSL_SOK != status)
        {
                printf("GPT Close Failed\n");
                return (CSL_TEST_FAILED);
        }

        return (CSL_TEST_PASSED);
}

中断函数:
interrupt void gpt0Isr(void)
{
        hitIsr = TRUE;//中断变量置位
    IRQ_clear(TINT_EVENT);//清除TINT中断标志
    /* Clear Timer Interrupt Aggregation Flag Register (TIAFR) */
    CSL_SYSCTRL_REGS->TIAFR = 0x01;//清除TIAFR中断的标志
}

程序中所用的函数,均是CSL函数库中的函数,我没有改动。


相关帖子

沙发
xzhihui|  楼主 | 2013-8-23 14:03 | 只看该作者
本帖最后由 xzhihui 于 2013-8-27 19:35 编辑

跟上我在线调试寄存器的状态
停在while的状态:

1,TIMER0寄存器状态:

定时器已使能,分频值为1100,自动装载,开始计数,
自动加载值为0x61a9, 计数器值:0x4a81

2.TIAFR寄存器状态:

TIMER0中断标志已成立。
在这里,TIMER0和TIMER1的标志同时存在,直接操作寄存器不能清除TIMER1的中断标志。

3.中断 IER0寄存器状态:

TIMER中断使能。

4.中断IFR0状态:

中断寄存器里的TIMER中断标志缺没有置位。

5.中断寄存器其他状态:

中断屏蔽位已经关闭,中断向量表地址是0x007c










使用特权

评论回复
板凳
zhangmangui| | 2013-8-23 16:14 | 只看该作者
不懂  帮忙顶

使用特权

评论回复
地板
xzhihui|  楼主 | 2013-8-25 09:23 | 只看该作者
难道没人遇到过这个问题吗?
还是没人用过?
我用官方的C55_CSL_3.03的库诶

使用特权

评论回复
5
xzhihui|  楼主 | 2013-8-26 18:40 | 只看该作者
还有人看吗?
没人看就接帖子了。

使用特权

评论回复
6
zhangmangui| | 2013-8-26 18:44 | 只看该作者
xzhihui 发表于 2013-8-26 18:40
还有人看吗?
没人看就接帖子了。

一时半会也看不出来是什么原因   也没遇到过   帮忙顶

使用特权

评论回复
7
xzhihui|  楼主 | 2013-8-27 18:23 | 只看该作者
问题算是解决了,不过我也没弄明白根本原因。

使用特权

评论回复
8
zhangmangui| | 2013-8-27 18:35 | 只看该作者
xzhihui 发表于 2013-8-27 18:23
问题算是解决了,不过我也没弄明白根本原因。

你再仔细研究一下  然后来分享给大家  谢谢

使用特权

评论回复
9
xzhihui|  楼主 | 2013-8-27 18:40 | 只看该作者
我后来在调试的时候,加了一个中断标志的判断
while(1)
{
    if((CSL_SYSCTRL_REGS->TIAFR &0x01) == 0x01)
        CSL_SYSCTRL_REGS->TIAFR = 0x01;
}

手动清除一次就可以进入中断,但这样的话就使中断失去意义了。
然后我又重新去看关于通用定时器的手册,发现DSP有这样的一个情况:
手册的原文:
The TIAFR latches each timer's interrupt signal when the timer counter expires. Using this register, the
programmer can determine which of the three timers generated the timer interrupt since the bits in the
TIAFR are OR'ed together and sent to the DSP as a single interrupt
. Each timer interrupt flag needs to be
cleared by the CPU with a write of "1" to the corresponding flag bit.

3个定时器会产生的标志是映射到相同的CPU中断上。
我实验板在每次上电的时候,TIMER0 和TIMER1都会有中断标志产生。
我的程序在初始化的时候只对TIMER0进行了初始化,没有对TIMER1进行操作。
然后在每次初始化的时候加上了

hGpt = GPT_open (GPT_0, &gptObj, &status);
status = GPT_reset(hGpt);
status = GPT_close(hGpt);
我在调试的时候还发现,不打开定时器,就不能清除定时器的中断标志,直接对寄存器操作无效。

使用特权

评论回复
10
xzhihui|  楼主 | 2013-8-27 18:41 | 只看该作者
本帖最后由 xzhihui 于 2013-8-27 19:33 编辑

每次开timer后,我都会调用一次:

while(1)
{
    if((CSL_SYSCTRL_REGS->TIAFR &0x01) == 0x01)
    {
         CSL_SYSCTRL_REGS->TIAFR = 0x01;//手动清除定时器中断标志
         break;
    }
}
手动清除第一次的中断标志。后续就可以正常中断。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:独立,内敛,提升,品味。

18

主题

509

帖子

2

粉丝