打印

发现定时器的奇怪问题

[复制链接]
2567|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
colaring|  楼主 | 2009-5-18 14:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
使用的是TIM3的溢出中断

A:这个竟然就死在这里了!查看寄存器竟然CNT不走了。。。
void TIM3_ISR(void)
{
    while ((TIM3->CNT) < 3600);
}



B:这个能看到a和b的值
void TIM3_ISR(void)
{
    unsigned int a, b;
    
    a = TIM3->CNT;
    asm("nop");
    b = TIM3->CNT;
    
    a = a;
    b = b;
    
    asm("nop");
}

不知道为啥。。。。
沙发
浪淘沙| | 2009-5-18 15:12 | 只看该作者

你的程序能产生溢出中断吗?

这个函数是怎么进来的?  void TIM3_ISR(void)

使用特权

评论回复
板凳
colaring|  楼主 | 2009-5-18 16:36 | 只看该作者

~~

当然能进了,这是定时器的溢出中断。我放断点已经进去了,可是一旦进去执行那个while,CNT就不会变了,永远是0.。。。郁闷

使用特权

评论回复
地板
浪淘沙| | 2009-5-18 16:39 | 只看该作者

怎么初始化定时器的?

使用特权

评论回复
5
colaring|  楼主 | 2009-5-18 16:42 | 只看该作者

麻烦了

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

    TIM_DeInit(TIM3);

    TIM_TimeBaseStructure.TIM_Prescaler = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_Period = 0xAFC8;//50Hz 32点采样
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);


    TIM_UpdateDisableConfig(TIM3,DISABLE);
    TIM_ARRPreloadConfig(TIM3,ENABLE);
    TIM_SelectOutputTrigger(TIM3,TIM_TRGOSource_Update);//选择TIM3的更新事件作为TRGO,触发ADC自动转换
    TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //允许TIM3更新事件中断
    TIM_Cmd(TIM3, ENABLE);//开启TIM3


        NVIC我也开了,但是现在这个情况太奇怪了

使用特权

评论回复
6
colaring|  楼主 | 2009-5-18 16:44 | 只看该作者

。。。

  TIM_SelectOutputTrigger(TIM3,TIM_TRGOSource_Update);//选择TIM3的更新事件作为TRGO,触发ADC自动转换

是出发内部双AD转换的,现在不用管,我们外扩了高精度外部ADC,内部ADC只负责监视电量和触摸屏了

使用特权

评论回复
7
浪淘沙| | 2009-5-18 16:45 | 只看该作者

再问一下,楼主位的程序B是怎么回事?

能看到a和b的值,什么值?

使用特权

评论回复
8
colaring|  楼主 | 2009-5-18 16:50 | 只看该作者

~~

程序B的作用是我用来判断TIM3是否正常的,CNT到底有没有自增。因为程序A,这个While((TIM3->CNT)<3600);彻底让 TIM3不会动了,永远CNT都是0。而我为了想知道TM3到底有没有配置对,会不会运行,才又写了个B,实际运行和期望是一样的,a是50多,b是60多,说明TM3运行正常。

使用特权

评论回复
9
浪淘沙| | 2009-5-18 16:59 | 只看该作者

既然这样说明你对程序A的判断有误,而TIM没有问题

估计你是在调试软件中去看CNT的数值,我不知道你是怎么看的,但我敢肯定是这里出了问题。

你最好把程序A和程序B结合起来试试看,例如:
void TIM3_ISR(void)
{   volatile unsigned int a;
    do
      a = TIM3->CNT;
    while (a < 3600);
}

这样调试停止时,查看变量a里面的内容。

注意在中断程序中清除中断标志。

使用特权

评论回复
10
colaring|  楼主 | 2009-5-18 17:08 | 只看该作者

不行

试了你的程序,一样不行。
我觉得while ((TIM3->CNT) < 3600);没有问题,因为本身(TIM3->CNT)已经是volatile性质的了。

对于调试时单步执行,然后通过IAR看到的CNT数值必定是没有意义的,因为TIM是会独立运行的,但是通过IAR一步一步走,寄存器窗口中CNT的值一定是会变化的,但是现在的问题是,无论我加了while,或者do while,CNT就定死是0了,无论怎么单步走都不会变了,这是最不能理解的了。貌似TIM停止了

使用特权

评论回复
11
colaring|  楼主 | 2009-5-18 17:08 | 只看该作者

~~

中断标志我清除了

使用特权

评论回复
12
浪淘沙| | 2009-5-18 17:11 | 只看该作者

如果IAR软件没有刷新窗口?你的结论还成立吗?

你是宁可相信IAR软件没有问题,而是要相信硬件有问题。

建议你直接看TIM3->CNT对应的地址。

使用特权

评论回复
13
colaring|  楼主 | 2009-5-18 17:19 | 只看该作者

~~

现在发现问题的根源了,这是中断处理

void TIM3_IRQHandler(void)
{
    /*清除TIM3更新事件标志*/
    TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
    TIM3_ISR();
}

这个TIM3_ISR()就是我放置A或者B程序的地方。
其他任何东西不变的前提下,如果我放入的是B程序,TIM3->CR1中的定时器使能位CEN是1,也就是定时器工作,但是一旦放入程序A,也就是类似循环等待的程序,CEN就被清除掉了。。。。。所以CNT永远也不动了。

谢谢浪淘沙的帮忙,我再查查这个CEN是什么原因

使用特权

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

本版积分规则

44

主题

156

帖子

1

粉丝