打印
[STM8]

STM8L的定时器问题!50分

[复制链接]
7887|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
_正方形|  楼主 | 2013-8-23 23:51 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
使用STM8L-discovery时发现的问题,求解答。

以下是我想用定时器实现1ms延时,使用了内部高速晶振,程序如下
static void TIM1_Config(void)
{
    TIM1_SetCounter(0);  
   //128分频 向上计数模式 使用HSI-16MHz
    TIM1_TimeBaseInit(128,TIM1_CounterMode_Up,124,0);

    TIM1_ARRPreloadConfig(DISABLE);
    /* Clear TIM1 update flag */
    TIM1_ClearFlag(TIM1_FLAG_Update);
    /* Enable update interrupt */
    TIM1_ITConfig(TIM1_IT_Update, ENABLE);
    /* enable interrupts */
    enableInterrupts();

    /* Enable TIM1 */
    TIM1_Cmd(ENABLE);
}

将主时钟HSI-16MHz进行128分频,向上计数到124,即125次,得到触发中断时间128/16*125=1000us即一毫秒,这个经测试准确无误,同理我想得到10us进中断,于是将初始化程序改动如下


static void TIM1_Config(void)
{
    TIM1_SetCounter(0);  
   //16分频 向上计数
    TIM1_TimeBaseInit(16,TIM1_CounterMode_Up,9,0);

    TIM1_ARRPreloadConfig(DISABLE);
    /* Clear TIM1 update flag */
    TIM1_ClearFlag(TIM1_FLAG_Update);
    /* Enable update interrupt */
    TIM1_ITConfig(TIM1_IT_Update, ENABLE);
    /* enable interrupts */
    enableInterrupts();

    /* Enable TIM1 */
    TIM1_Cmd(ENABLE);
}


理论上讲16分频后得到1MHz,向上计数到9为十次,应有10us进一次中断 可是经实际测量进中断的时间为20us左右
我又改动如下
TIM1_TimeBaseInit(16,TIM1_CounterMode_Up,4,0); 发现触发一次中断仍为20us

进一步改动,发现无论分频系数和重载值怎么改动 进中断的时间最小约为20us,不能再小了

有没有人碰见过这个问题?如何解决?与使用的内部晶振有关吗?

跪了很久了 如能解决 50分奉上
沙发
1849097455| | 2013-8-24 08:20 | 只看该作者
10us中断不能识别,中断也要反应时间的。

使用特权

评论回复
板凳
xxiao6130| | 2013-8-24 08:24 | 只看该作者
支持2楼,定时10us,我一般用查询法,你不妨试试!

使用特权

评论回复
地板
_正方形|  楼主 | 2013-8-24 08:53 | 只看该作者
xxiao6130 发表于 2013-8-24 08:24
支持2楼,定时10us,我一般用查询法,你不妨试试!

是不是就直接在主函数里面等待定时器溢出改变中断标志位?中断函数里面什么都不用写是不

使用特权

评论回复
5
xxiao6130| | 2013-8-24 09:08 | 只看该作者
是的,你可以看看这个

TIME4应用.pdf

86.85 KB

使用特权

评论回复
6
yuanquanquan| | 2013-8-24 11:22 | 只看该作者
同意2楼    中断处理要占用时间

使用特权

评论回复
7
yuanquanquan| | 2013-8-24 11:24 | 只看该作者
就算中断函数里面只清标志位   也不会达到你下面的要求

使用特权

评论回复
8
_正方形|  楼主 | 2013-8-24 11:55 | 只看该作者
xxiao6130 发表于 2013-8-24 09:08
是的,你可以看看这个

我在Debug里面找到了反汇编的代码如下,是中断里面执行的指令


TIM1_UPD_OVF_TRG_COM_IRQHandler:
_interrupt_25:
    008201    8A             PUSH      CC
    008202    84             POP       A
    008203    A4BF           AND       A, #0xBF
    008205    88             PUSH      A
    008206    86             POP       CC
    008207    CD8147         CALL      ?push_l0
    00820A    CD814C         CALL      ?push_l1
    00820D    CD827A         CALL      TimingDelay_Decrement
    008210    A601           LD        A, #?b1
    008212    CD834C         CALL      TIM1_ClearITPendingBit
    008215    CD8179         CALL      ?pop_l1
    008218    CD816E         CALL      ?pop_l0
    00821B    80             IRET

下面是被调用的函数   
?pop_l0:
    00816E    89             PUSHW     X
    00816F    1E05           LDW       X, (?b5, SP)
    008171    BF00           LDW       0x00, X
    008173    1E07           LDW       X, (?b7, SP)
    008175    BF02           LDW       ?b2, X
    008177    200B           JRA       0x0B
?pop_l1:
    008179    89             PUSHW     X
    00817A    1E05           LDW       X, (?b5, SP)
    00817C    BF04           LDW       ?b4, X
    00817E    1E07           LDW       X, (?b7, SP)
    008180    BF06           LDW       ?b6, X
    008182    2000           JRA       0x00
    008184    1E03           LDW       X, (?b3, SP)
    008186    1F07           LDW       (?b7, SP), X
    008188    85             POPW      X
    008189    5B04           ADD       SP, #?b4
    00818B    81             RET
?push_l0:
    008147    88             PUSH      A
    008148    A600           LD        A, #0x00
    00814A    2005           JRA       0x05
?push_l1:
    00814C    88             PUSH      A
    00814D    A604           LD        A, #?b4
    00814F    2000           JRA       0x00
    008151    88             PUSH      A
    008152    89             PUSHW     X
    008153    7B04           LD        A, (?b4, SP)
    008155    88             PUSH      A
    008156    7B04           LD        A, (?b4, SP)
    008158    89             PUSHW     X
    008159    1E08           LDW       X, (?b8, SP)
    00815B    1F04           LDW       (?b4, SP), X
    00815D    5F             CLRW      X
    00815E    97             LD        XL, A
    00815F    1F08           LDW       (?b8, SP), X
    008161    FE             LDW       X, (X)
    008162    1F06           LDW       (?b6, SP), X
    008164    1E08           LDW       X, (?b8, SP)
    008166    5C             INCW      X
    008167    5C             INCW      X
    008168    FE             LDW       X, (X)
    008169    1F08           LDW       (?b8, SP), X
    00816B    85             POPW      X
    00816C    84             POP       A
    00816D    81             RET

TimingDelay_Decrement:
    00827A    CD8335         CALL      0x8335
    00827D    2602           JRNE      0x02
    00827F    BE02           LDW       X, ?b2
    008281    270F           JREQ      0x0F
    008283    AE000C         LDW       X, #TimingDelay
    008286    CD8260         CALL      ?load32_l0_0x
    008289    CD8293         CALL      ?dec32_l0_l0
    00828C    AE000C         LDW       X, #TimingDelay
    00828F    CD826C         CALL      ?load32_0x_l0
    008292    81             RET


TIM1_ClearITPendingBit:
    00834C    43             CPL       A
    00834D    C752B6         LD        TIM1_SR1, A
    008350    81             RET

是不是就意味着执行这些指令的时间就是上面我测得的约20us?


使用特权

评论回复
9
_正方形|  楼主 | 2013-8-24 11:57 | 只看该作者
yuanquanquan 发表于 2013-8-24 11:24
就算中断函数里面只清标志位   也不会达到你下面的要求

刚刚的问题同问quanquan哥

使用特权

评论回复
10
yuanquanquan| | 2013-8-24 12:23 | 只看该作者
_正方形 发表于 2013-8-24 11:57
刚刚的问题同问quanquan哥

我也坐等大神解释

使用特权

评论回复
11
dwwzl302| | 2013-8-24 16:47 | 只看该作者
想得到更小的定时周期,唯一的方法就是提高时钟频率吧!

使用特权

评论回复
12
乌月明星稀| | 2013-8-24 17:08 | 只看该作者
将主时钟的时钟频率提高到16M,提高中断处理速度。中断相应的机器周期:11个(主时钟时钟节拍是1us,则定时中断到相应过程需要11us的时间),所以总时间为:11us+10us =21us;即使在中断中直接退出,相应地,也需要11个周期执行完IRET指令。也就是说,你中断在退出后定时器又已经中断了。况且你那个清零操作也需要时间。退出和重新响应已经占用了22us的时间了!!!而不是20us!如果改成16Mhz,你退出和响应只需要22/16<2us。

使用特权

评论回复
13
_正方形|  楼主 | 2013-8-24 20:29 | 只看该作者
乌月明星稀 发表于 2013-8-24 17:08
将主时钟的时钟频率提高到16M,提高中断处理速度。中断相应的机器周期:11个(主时钟时钟节拍是1us,则定时 ...

我用延时实现IO口翻转,跑的比较慢的时候是好的,可以出方波,刚才把分频系数改成1,示波器上测发现直接出高电平了,连个波形都没有

使用特权

评论回复
14
乌月明星稀| | 2013-8-24 22:35 | 只看该作者
在16MHZ的时候连个波形都没有还是在1M的时候没有波形?主时钟频率要快。我玩STM8这么多年了都没遇到过这个问题。

使用特权

评论回复
15
_正方形|  楼主 | 2013-8-24 22:56 | 只看该作者
乌月明星稀 发表于 2013-8-24 22:35
在16MHZ的时候连个波形都没有还是在1M的时候没有波形?主时钟频率要快。我玩STM8这么多年了都没遇到过这个 ...

程序是这样的

这个是主函数里的循环
while (1)
{
       GPIO_SetBits(GPIOC, GPIO_Pin_7);
       Delay(1);
       GPIO_ResetBits(GPIOC,GPIO_Pin_7);
       Delay(1);

}
下面是定时器和CLK的设置
static void TIM1_Config(void)
{
    TIM1_SetCounter(0);  
   //不分频 向上计数 10次
    TIM1_TimeBaseInit(1,TIM1_CounterMode_Up,9,0);

    TIM1_ARRPreloadConfig(DISABLE);
    /* Clear TIM1 update flag */
    TIM1_ClearFlag(TIM1_FLAG_Update);
    /* Enable update interrupt */
    TIM1_ITConfig(TIM1_IT_Update, ENABLE);
    /* enable interrupts */
    enableInterrupts();

    /* Enable TIM1*/
    TIM1_Cmd(ENABLE);
}

static void CLK_Config(void)
{
  /* High speed internal clock prescaler: 1 */
  CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_1);

  /* Select HSE as system clock source */
  CLK_SYSCLKSourceSwitchCmd(ENABLE);
  CLK_SYSCLKSourceConfig(CLK_SYSCLKSource_HSI);

  while (CLK_GetSYSCLKSource() != CLK_SYSCLKSource_HSI)
  {}

  /* Enable TIM4 CLK */
  CLK_PeripheralClockConfig(CLK_Peripheral_TIM1, ENABLE);
}

下面是延时函数

void Delay(__IO uint32_t nTime)
{
  TimingDelay = nTime;

  while (TimingDelay != 0);
}

void TimingDelay_Decrement(void)
{
  if (TimingDelay != 0x00)
  {
    TimingDelay--;
  }
}


中断里面是这样的
INTERRUPT_HANDLER(TIM1_UPD_OVF_TRG_COM_IRQHandler, 23)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.

  */

  TimingDelay_Decrement();

  /* Cleat Interrupt Pending bit */
  TIM1_ClearITPendingBit(TIM1_IT_Update);
}


用上面的程序,TIM1直接不分频,PC7接到示波器上直接就是1,
然后把TIM1_TimeBaseInit(1,TIM1_CounterMode_Up,9,0)改成TIM1_TimeBaseInit(16,TIM1_CounterMode_Up,9,0);后有波形

就是说跑1MHZ有波形,跑16MHz直接高电平
难道是硬件问题?

使用特权

评论回复
16
zxm19820916| | 2016-6-15 15:42 | 只看该作者
_正方形 发表于 2013-8-24 22:56
程序是这样的

这个是主函数里的循环

你16M的时候,那个数字9也要相应改才行啊。

使用特权

评论回复
17
nice樱木| | 2016-7-7 18:57 | 只看该作者
学习了

使用特权

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

本版积分规则

3

主题

29

帖子

1

粉丝