打印
[应用相关]

实在看不下去了,STM32软件精确延时的方法!!!!!!

[复制链接]
楼主: zhonggx
手机看帖
扫描二维码
随时随地手机跟帖
21
zhonggx|  楼主 | 2014-9-27 17:04 | 只看该作者 回帖奖励 |倒序浏览
huzi2099 发表于 2014-9-27 15:43
到点儿做事儿而不是等着到点儿做事儿

请你看另一个贴子吧,很多人要实现软件延时,51那种通过循环方法因为ARM的周期不确定的原因,无法实现比较精确的软件延时。
我只不过提供一种在不影响SYSTICK工作情况下,通过查询SYSTICK计数器的寄存器来实现精确软件延时的方法。

请看不懂的人,先想过再喷。

使用特权

评论回复
22
zhonggx|  楼主 | 2014-9-27 17:06 | 只看该作者
本帖最后由 zhonggx 于 2014-9-27 17:14 编辑
xlsbz 发表于 2014-9-27 15:26
while (uint32_t dwTime)
{
     __IO uint32_t  cnt = SysTick->VAL;;

问题就你提的,你根本就没看懂。我这个方法主要就是不占用其它计数器,不影响SYSTICK的工作,也不受限于SYSTICK本身周期设置。

使用特权

评论回复
23
mmuuss586| | 2014-9-27 17:07 | 只看该作者
zhonggx 发表于 2014-9-27 09:15
晕死,是有人需要这样死等的延时函数!!
有些时候用这个样的方法确实也很简单。比如我要延时几个微秒, ...

:dizzy:
哦,不过我不喜欢死等,呵呵;

使用特权

评论回复
24
zhonggx|  楼主 | 2014-9-27 17:08 | 只看该作者
huzi2099 发表于 2014-9-27 15:43
到点儿做事儿而不是等着到点儿做事儿

那你如果不用死延时,在不再用其它定时器的情况下,你读一下1-WIRE总线试试。到点做事是没错,要分情况,别上来就喷!

使用特权

评论回复
25
zhonggx|  楼主 | 2014-9-27 17:09 | 只看该作者
mmuuss586 发表于 2014-9-27 17:07
哦,不过我不喜欢死等,呵呵;

还时那个问题,那你如果不用死延时,在不再用其它定时器的情况下,你读一下1-WIRE总线试试。

使用特权

评论回复
26
bear1| | 2014-9-27 17:30 | 只看该作者
本帖最后由 bear1 于 2014-9-27 17:35 编辑
mmuuss586 发表于 2014-9-27 09:08
为什么不换个思路写延时程序呢;
你这样程序就是死等,多浪费资源啊;
...


对哦,还是死等,不过楼主的想法值得我们鼓励和学习

使用特权

评论回复
27
bear1| | 2014-9-27 17:34 | 只看该作者
不死等,行不行?

使用特权

评论回复
28
xlsbz| | 2014-9-27 18:24 | 只看该作者
zhonggx 发表于 2014-9-27 17:06
问题就你提的,你根本就没看懂。我这个方法主要就是不占用其它计数器,不影响SYSTICK的工作,也不受限于SY ...

你怎么知道我没看懂。你以为是哥的巴赫猜想啊。
我得方法明显比你的强  我的不用设置systic就行。你的必须硬件初始化。

看我的  你看懂没
uint16_t hah = 1000;
while (hah > 0)
{
      __IO uint32_t  cnt = 随便搞个寄存器;;
      hah--

使用特权

评论回复
29
zhonggx|  楼主 | 2014-9-27 18:53 | 只看该作者
xlsbz 发表于 2014-9-27 18:24
你怎么知道我没看懂。你以为是哥的巴赫猜想啊。
我得方法明显比你的强  我的不用设置systic就行。你的必 ...

你是真没看懂!!
你以为我是通过赋值来延时?!不懂装懂的白痴!!!!

使用特权

评论回复
30
江枫渔火| | 2014-9-27 18:55 | 只看该作者

      TI的资料中,此函数在Sysctl.c中是这样定义的:

#if defined(ewarm) || defined(DOXYGEN)    //定义在IAR的编译环境中
void
SysCtlDelay(unsigned long ulCount)
{
    __asm("    subs    r0, #1\n"
          "    bne.n   SysCtlDelay\n"
          "    bx      lr");
}
#endif

#if defined(codered) || defined(gcc) || defined(sourcerygxx)  //定义在codered、gcc、sourcerygcc编译环境下
void __attribute__((naked))
SysCtlDelay(unsigned long ulCount)
{
    __asm("    subs    r0, #1\n"
          "    bne     SysCtlDelay\n"
          "    bx      lr");
}
#endif

#if defined(rvmdk) || defined(__ARMCC_VERSION)  //在KEIL MDK的编译环境下
__asm void
SysCtlDelay(unsigned long ulCount)
{
    subs    r0, #1;
    bne     SysCtlDelay;
    bx      lr;
}
#endif
  不管哪种环境下,发现用了三条汇编指令。我用的是KEIL MDK。
  subs  r0,#1;  // 使用了16位的Thumb指令,无条件更新标志位。S后缀的使用要担心,16位的Thunb指令有可能会无条件更新标志位,也有可能不会。所以,但你需要更新标志位时,一定不要忘了加上S后缀。
   bne SysCtlDelay;  //  无条件跳转指令有两条,B和BX,  BNE中的NE即NotEqual,对应于标志位Z==0;
  表示不等的时候无条件转移到SysCtlDelay处对应的地址;
   bx    lr;  //执行这条指令后,把返回地址存储到LR(R14)中;

关于SysCtlDelay()延时函数:
   TI LM3S8962 默认的设置为采用主晶振6M,   所以,一个周期的时间是1/6us。
   SysCtlDelay()函数里执行了三条指令。
   1.微妙级的延时:
       SysCtlDelay(2); // 延时1us;
        SysCtlDelay(2*x); 延时x us;x=1000时,延时1ms;
        另一种写法
      #defined TheSysClock 6000000
       SysCtlDelay(1*(TheSysClock/3000000)) //延时 1us
    2.毫秒级的延时:
        SysCtlDelay(SysCtlClockGet( ) / 3000);    //   延时1ms
        SysCtlDelay(10 * (SysCtlClockGet( ) / 3000));    //   延时10ms
         SysCtlClockGet( )=6000000 ;
    另一种种写法
        // 定义系统时钟 6M
        #define TheSysClock  6000000
       SysCtlDelay(10 * (TheSysClock / 3000)); 延时10ms
      // 定义系统时钟 8M
        #define TheSysClock  8000000
      SysCtlDelay(10 * (TheSysClock / 3000));  延时10ms

用这个汇编微秒级延时函数,通杀所有M3,M4核的单片机。移植过来时间都不变。还很精准。

使用特权

评论回复
31
zhonggx|  楼主 | 2014-9-27 18:56 | 只看该作者
bear1 发表于 2014-9-27 17:34
不死等,行不行?

可以,那就要浪费一个定时器。

使用特权

评论回复
32
bear1| | 2014-9-27 19:04 | 只看该作者
真理越辨越明啊!

使用特权

评论回复
33
zhonggx|  楼主 | 2014-9-27 19:06 | 只看该作者
江枫渔火 发表于 2014-9-27 18:55
TI的资料中,此函数在Sysctl.c中是这样定义的:

#if defined(ewarm) || defined(DOXYGEN)    //定 ...

汇编方法,如果计时中间有中断,那么影响会比较大的。
我那个方法,其实本质也是用定时器,但是SYSTICK比较专用,功能也单一,我只是轮询它,不影响它本身工作。只要不是在我到达计数那次查询有中断,那么计时还是准的,中间有多少次中断,不影响计时精度。应该说他是SYSTICK计时器的一个副产品。几乎所有CPU中,这个思路都通用,在STM系列中,程序有移植性,不会因为系统时钟等的变化而影响精度。

使用特权

评论回复
34
chen_jhhb| | 2014-9-27 19:13 | 只看该作者
学习中

使用特权

评论回复
35
xlsbz| | 2014-9-27 19:16 | 只看该作者
江枫渔火 发表于 2014-9-27 18:55
TI的资料中,此函数在Sysctl.c中是这样定义的:

#if defined(ewarm) || defined(DOXYGEN)    //定 ...

大牛,大家争论半天 就等你这个大牛出现

OK  多谢

使用特权

评论回复
36
xlsbz| | 2014-9-27 19:18 | 只看该作者
zhonggx 发表于 2014-9-27 19:06
汇编方法,如果计时中间有中断,那么影响会比较大的。
我那个方法,其实本质也是用定时器,但是SYSTICK比 ...

1+1=2讲了半天有意思么?
软件架构的书 linux  vxworks代码你多看看 对你有好处。

思维太窄, 和你讲不清楚

使用特权

评论回复
37
zhonggx|  楼主 | 2014-9-27 19:34 | 只看该作者
xlsbz 发表于 2014-9-27 19:18
1+1=2讲了半天有意思么?
软件架构的书 linux  vxworks代码你多看看 对你有好处。

你真看过?!一个延时函数你都能扯上软件架构,真牛!思维真是广啊!!!!让我想起一个相亲的段子。

使用特权

评论回复
38
xlsbz| | 2014-9-27 19:44 | 只看该作者
zhonggx 发表于 2014-9-27 19:34
你真看过?!一个延时函数你都能扯上软件架构,真牛!思维真是广啊!!!!让我想起一个相亲的段子。 ...

呵呵 被你看穿了

使用特权

评论回复
39
江枫渔火| | 2014-9-27 19:54 | 只看该作者
炒什么,稍安勿躁。切忌浮躁。凡是有利有弊,对于某个问题用合适的方式能解决就行了。上个网就是放松下,爱听就听,爱看就看。前万不要有把自己思想灌进别人脑袋的天真想法。

使用特权

评论回复
40
tuzihog| | 2014-9-27 21:58 | 只看该作者
关注一下

使用特权

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

本版积分规则