打印
[其他ST产品]

st72f324定时器问题

[复制链接]
2689|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
windark|  楼主 | 2007-5-14 11:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我在做自己的试验时,发现每当我的计数器寄存器值达到输出比较寄存器1值时,确实的发生了中断,但是在中断的过程中,计数器寄存器值立刻跳到输出比较寄存器2的值后面,如果oc2R=0x8000,则计数器寄存器值会在0x800c等几个值,总之不管oc2r改为多少,经常性的出现这个情况。
而且有时候没有出现这个情况时,我的csr值会不知道被那个步骤给事先读取,这样子csr就被清零了,不能实现我的目标;事实上我的程序还没有运行到读取TBcsr那一步。    难道是因为c语言和汇编的问题,汇编稳定性高?

还有个问题,你们给的那个输出比较定时器例程,我也单步执行了,结果是正确的(ps 我那个定时器程序几乎和你们给的一样,除了我自己的那些main程序)
但是你们的当执行到while (TimerTick < 100)时,刚好是tof被置位的第二步,理论上应该是先读csr再写或读clr才能清掉tof这一位,但事实上你们的程序没有这个代码他也自动把tof给清零了,这是怎么回事?难道我理解有问题?
而且你们的中断代码里还有那个清除tof的代码,要是之前被自动清除的话这句就没意义了啊。

但愿我仿真器没问题。
main()
{
    // 第一次使能Timer时,Counter是从0xFFFC开始计数,所以第一次输出比较的值要减4
    Timer_Step = OC1_10us - 4;    // Timer start from 0xFFFC, so deduct 4

    TACSR = CSR_TIMD;        // Disable the Timer
    TACR1 = CR1_OCIE;        // Enable OC interrupt
    TACR2 = 0x04;            // Prescaler = /2
    TAOC1HR = Timer_Step >> 8;
    TAOC1LR = Timer_Step;
    
    TACLR = 0;            // Clear the counter
    TACSR = 0;            // Enable the timer
    
    //Timer_Step += OC1_10us;        // Prepare next time OC value
    _asm("rim");            // Enable global interrupt

  TimerTick = 0;
    while (TimerTick < 100) {    // 分别用100和200各运行一次
    //TACLR=0x07;
    _asm("nop");
    }
    _asm("nop");            // 调试时在此设一个断点,察看执行的时间
    _asm("halt");
}
沙发
香水城| | 2007-5-14 14:37 | 只看该作者

楼主能否讲清楚些

“但是在中断的过程中,计数器寄存器值立刻跳到输出比较寄存器2的值后面”,这句话如何理解?

“....,则计数器寄存器值会在0x800c等几个值,...”,“等几个值”是什么意思?

你如何知道上述现象?是否在中断程序中设置了调试断点?

请注意:当你设置了断点暂停了程序的运行,计数器并没有停止,在断点处执行单步操作后你会发现计数器值已经跑的很远了;另外,如果在调试环境中你有窗口察看各个寄存器的值,在断点处程序停下后,调试器会读取所有要观察的寄存器;如果CSR寄存器也是要察看的对象时,调试器在程序停下时已经对它进行了操作。因此,程序在断点处停下后,在确保程序到此处的动作正确后,应移开这个断点,重新运行程序到新的断点,而不应从断点处继续执行。

使用特权

评论回复
板凳
windark|  楼主 | 2007-5-14 14:57 | 只看该作者

回复香水城

就算我全部单步运行,也是如此结果。感觉是仿真器坏了或者设置不对!
至于那个详细说明:如oc2r值为0800,即复位值,那么当cr达到oc1r值时,发生中断,但显示并非是ocf1置1,而是ocf2置1,而且此时cr值会跳到080?值,?表示这个值不确定,但080?肯定是大于或等于0800这个oc2r值。

这只是其中一个错误现象,还有个怪现象,一旦进入中断,如果中断程序里有一个timertick++这一语句,那么进入中断后会立即执行一次,而汇编代码里不显示它会被执行,但通过寄存器可以看到timertick变为1了,然后在实际语句中它又被+1.同样的,TAOC1R一开始也会被赋予新值,整个中断程序相当与执行了2次。这样导致的结果是最终定时的时间还是准的,但程序是很不可靠的。
程序就是你们那个定时器程序,我一点都不改的,就是用于测试。

我觉得,这是仿真器坏了

使用特权

评论回复
地板
windark|  楼主 | 2007-5-14 15:04 | 只看该作者

关于调试器的读操作

调试器读寄存器值并将之显示在窗口,这个难道也是相当于对寄存器读么?
比如tof被置一,但我把csr和clr在窗口显示了,会不会把tof清零?

使用特权

评论回复
5
香水城| | 2007-5-14 15:14 | 只看该作者

不知道你注意到没有,两个输出比较中断不能被单独使能或

设置了CR1中的OCIE位后,输出比较中断就被使能,不管是输出比较1还是输出比较2,任一比较成功事件都会触发中断;你的问题很可能是在中断中的断点停下来时,输出比较2触发了中断而不是输出比较1,这一点从你的描述中可以看出来,“发生中断,但显示并非是ocf1置1,而是ocf2置1”。

使用特权

评论回复
6
香水城| | 2007-5-14 15:17 | 只看该作者

只要在窗口中显示的寄存器,在断点停下时都会被调试器读

使用特权

评论回复
7
windark|  楼主 | 2007-5-14 15:25 | 只看该作者

单步时不也能读么

我一直是单步执行,实时的看每个寄存器状态。
我中断程序里面没有设置断点,要么就是每个单步相当与加一个断点。
你在5楼说的情况我很清楚,确实我也有这么想过。

我在试了次,不用单步执行,在中断里面设置断点,这样子结果就正确了,确实是因为单步执行导致的错误。

能否详细讲讲单步执行的原理?

使用特权

评论回复
8
香水城| | 2007-5-14 16:25 | 只看该作者

单步执行的原理就是一次执行一行语句或一条指令

执行完一行语句或一条指令后,可以查看各种变量或寄存器的内容,调试器会读出所有你要查看的内容。

使用特权

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

本版积分规则

5

主题

49

帖子

0

粉丝