【原创】TIVA 关于SysCtlDelay()准确延时的测试

[复制链接]
4126|19
 楼主| xyz549040622 发表于 2015-11-25 16:25 | 显示全部楼层 |阅读模式
本帖最后由 xyz549040622 于 2015-11-25 17:23 编辑

上一篇帖子中分析,SysCtlDelay(SysCtlClockGet() / M / 3)的延时时间都为1/M(s).帖子链接如下
https://bbs.21ic.com/icview-1203016-1-1.html

可是实际测试却不是这么一回事的

设置系统主时钟为50MHZ,直接用SysCtlDelay(5000000 / 3000);延时,延时时间为很准确的2ms
代码如下
  1. //*****************************************************************************
  2. //
  3. // hello.c - Simple hello world example.
  4. //
  5. // Copyright (c) 2012-2014 Texas Instruments Incorporated.  All rights reserved.
  6. // Software License Agreement
  7. //
  8. // Texas Instruments (TI) is supplying this software for use solely and
  9. // exclusively on TI's microcontroller products. The software is owned by
  10. // TI and/or its suppliers, and is protected under applicable copyright
  11. // laws. You may not combine this software with "viral" open-source
  12. // software in order to form a larger program.
  13. //
  14. // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
  15. // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
  16. // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  17. // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
  18. // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
  19. // DAMAGES, FOR ANY REASON WHATSOEVER.
  20. //
  21. // This is part of revision 2.1.0.12573 of the EK-TM4C123GXL Firmware Package.
  22. //
  23. //*****************************************************************************

  24. #include <stdint.h>
  25. #include <stdbool.h>
  26. #include "inc/hw_memmap.h"
  27. #include "inc/hw_types.h"
  28. #include "driverlib/debug.h"
  29. #include "driverlib/fpu.h"
  30. #include "driverlib/gpio.h"
  31. #include "driverlib/pin_map.h"
  32. #include "driverlib/rom.h"
  33. #include "driverlib/sysctl.h"
  34. #include "driverlib/uart.h"
  35. //#include "utils/uartstdio.h"

  36. //*****************************************************************************
  37. //
  38. //! \addtogroup example_list
  39. //! <h1>Hello World (hello)</h1>
  40. //!
  41. //! A very simple ``hello world'' example.  It simply displays ``Hello World!''
  42. //! on the UART and is a starting point for more complicated applications.
  43. //!
  44. //! UART0, connected to the Virtual Serial Port and running at
  45. //! 115,200, 8-N-1, is used to display messages from this application.
  46. //
  47. //*****************************************************************************

  48. //*****************************************************************************
  49. //
  50. // The error routine that is called if the driver library encounters an error.
  51. //
  52. //*****************************************************************************
  53. #ifdef DEBUG
  54. void
  55. __error__(char *pcFilename, uint32_t ui32Line)
  56. {
  57. }
  58. #endif

  59. ////*****************************************************************************
  60. ////
  61. //// Configure the UART and its pins.  This must be called before UARTprintf().
  62. ////
  63. ////*****************************************************************************
  64. //void
  65. ConfigureUART(void)
  66. {
  67. //    //
  68. //    // Enable the GPIO Peripheral used by the UART.
  69. //    //
  70.     ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

  71. //    //
  72. //    // Enable UART0
  73. //    //
  74.     ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

  75. //    //
  76. //    // Configure GPIO Pins for UART mode.
  77. //    //
  78.     ROM_GPIOPinConfigure(GPIO_PA0_U0RX);
  79.    ROM_GPIOPinConfigure(GPIO_PA1_U0TX);
  80.     ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

  81. //    //
  82. //    // Use the internal 16MHz oscillator as the UART clock source.
  83. //    //
  84.     UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);

  85. //    //
  86. //    // Initialize the UART for console I/O.
  87. //    //
  88.     UARTStdioConfig(0, 115200, 16000000);
  89. }

  90. //*****************************************************************************
  91. //
  92. // Print "Hello World!" to the UART on the evaluation board.
  93. //
  94. //*****************************************************************************
  95. int
  96. main(void)
  97. {
  98.     volatile uint32_t ui32Loop;

  99.     //
  100.     // Enable lazy stacking for interrupt handlers.  This allows floating-point
  101.     // instructions to be used within interrupt handlers, but at the expense of
  102.     // extra stack usage.
  103.     //
  104.     ROM_FPULazyStackingEnable();

  105.     //
  106.     // Set the clocking to run directly from the crystal.
  107.     //
  108.     ROM_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ |
  109.                        SYSCTL_OSC_MAIN);

  110.     //
  111.     // Enable the GPIO port that is used for the on-board LED.
  112.     //
  113.     ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

  114.     //
  115.     // Enable the GPIO pins for the LED (PF2 & PF3).
  116.     //
  117.     ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2);

  118.     //
  119.     // Initialize the UART.
  120.     //
  121.     ConfigureUART();

  122. //    //
  123. //    // Hello!
  124. //    //
  125. /*    UARTprintf("Hello, world!\n");
  126.     ui32Loop=0;
  127.     ui32Loop=ROM_SysCtlClockGet();
  128.     UARTprintf("%d\n",ui32Loop);
  129.     ui32Loop=0;
  130.     ui32Loop=SysCtlClockGet();
  131.     UARTprintf("%d\n",ui32Loop);*/
  132.     //
  133.     // We are finished.  Hang around doing nothing.
  134.     //
  135.     while(1)
  136.     {
  137.         //
  138.         // Turn on the BLUE LED.

  139.         GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2);

  140.         //
  141.         // Delay for a bit.
  142.         //
  143.         SysCtlDelay(50000000 / 3000);

  144.         //
  145.         // Turn off the BLUE LED.
  146.         //
  147.         GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0);

  148.         //
  149.         // Delay for a bit.
  150.         //
  151.         SysCtlDelay(50000000 / 3000);
  152. /*                    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2);

  153.                     //
  154.                     // Delay for a bit.
  155.                     //
  156.                     SysCtlDelay(ROM_SysCtlClockGet() / 3000);

  157.                     //
  158.                     // Turn off the BLUE LED.
  159.                     //
  160.                     GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0);

  161.                     //
  162.                     // Delay for a bit.
  163.                     //
  164.                     SysCtlDelay(ROM_SysCtlClockGet() / 3000);*/
  165.     }
  166. }
时间截图如下:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| xyz549040622 发表于 2015-11-25 16:30 | 显示全部楼层
本帖最后由 xyz549040622 于 2015-11-25 16:32 编辑

使用 SysCtlDelay(ROM_SysCtlClockGet() / 3000);延时,并加入了测试ROM_SysCtlClockGet()值的代码,延时时间为1.1ms

  1.     UARTprintf("Hello, world!\n");
  2.     ui32Loop=0;
  3.     ui32Loop=ROM_SysCtlClockGet();
  4.     UARTprintf("%d\n",ui32Loop);
  5.     ui32Loop=0;
  6.     ui32Loop=SysCtlClockGet();
  7.     UARTprintf("%d\n",ui32Loop);


整个源代码如下:
  1. //*****************************************************************************
  2. //
  3. // hello.c - Simple hello world example.
  4. //
  5. // Copyright (c) 2012-2014 Texas Instruments Incorporated.  All rights reserved.
  6. // Software License Agreement
  7. //
  8. // Texas Instruments (TI) is supplying this software for use solely and
  9. // exclusively on TI's microcontroller products. The software is owned by
  10. // TI and/or its suppliers, and is protected under applicable copyright
  11. // laws. You may not combine this software with "viral" open-source
  12. // software in order to form a larger program.
  13. //
  14. // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
  15. // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
  16. // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  17. // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
  18. // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
  19. // DAMAGES, FOR ANY REASON WHATSOEVER.
  20. //
  21. // This is part of revision 2.1.0.12573 of the EK-TM4C123GXL Firmware Package.
  22. //
  23. //*****************************************************************************

  24. #include <stdint.h>
  25. #include <stdbool.h>
  26. #include "inc/hw_memmap.h"
  27. #include "inc/hw_types.h"
  28. #include "driverlib/debug.h"
  29. #include "driverlib/fpu.h"
  30. #include "driverlib/gpio.h"
  31. #include "driverlib/pin_map.h"
  32. #include "driverlib/rom.h"
  33. #include "driverlib/sysctl.h"
  34. #include "driverlib/uart.h"
  35. //#include "utils/uartstdio.h"

  36. //*****************************************************************************
  37. //
  38. //! \addtogroup example_list
  39. //! <h1>Hello World (hello)</h1>
  40. //!
  41. //! A very simple ``hello world'' example.  It simply displays ``Hello World!''
  42. //! on the UART and is a starting point for more complicated applications.
  43. //!
  44. //! UART0, connected to the Virtual Serial Port and running at
  45. //! 115,200, 8-N-1, is used to display messages from this application.
  46. //
  47. //*****************************************************************************

  48. //*****************************************************************************
  49. //
  50. // The error routine that is called if the driver library encounters an error.
  51. //
  52. //*****************************************************************************
  53. #ifdef DEBUG
  54. void
  55. __error__(char *pcFilename, uint32_t ui32Line)
  56. {
  57. }
  58. #endif

  59. ////*****************************************************************************
  60. ////
  61. //// Configure the UART and its pins.  This must be called before UARTprintf().
  62. ////
  63. ////*****************************************************************************
  64. //void
  65. ConfigureUART(void)
  66. {
  67. //    //
  68. //    // Enable the GPIO Peripheral used by the UART.
  69. //    //
  70.     ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

  71. //    //
  72. //    // Enable UART0
  73. //    //
  74.     ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

  75. //    //
  76. //    // Configure GPIO Pins for UART mode.
  77. //    //
  78.     ROM_GPIOPinConfigure(GPIO_PA0_U0RX);
  79.    ROM_GPIOPinConfigure(GPIO_PA1_U0TX);
  80.     ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

  81. //    //
  82. //    // Use the internal 16MHz oscillator as the UART clock source.
  83. //    //
  84.     UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);

  85. //    //
  86. //    // Initialize the UART for console I/O.
  87. //    //
  88.     UARTStdioConfig(0, 115200, 16000000);
  89. }

  90. //*****************************************************************************
  91. //
  92. // Print "Hello World!" to the UART on the evaluation board.
  93. //
  94. //*****************************************************************************
  95. int
  96. main(void)
  97. {
  98.     volatile uint32_t ui32Loop;

  99.     //
  100.     // Enable lazy stacking for interrupt handlers.  This allows floating-point
  101.     // instructions to be used within interrupt handlers, but at the expense of
  102.     // extra stack usage.
  103.     //
  104.   //  ROM_FPULazyStackingEnable();

  105.     //
  106.     // Set the clocking to run directly from the crystal.
  107.     //
  108.     ROM_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ |
  109.                        SYSCTL_OSC_MAIN);

  110.     //
  111.     // Enable the GPIO port that is used for the on-board LED.
  112.     //
  113.     ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

  114.     //
  115.     // Enable the GPIO pins for the LED (PF2 & PF3).
  116.     //
  117.     ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2);

  118.     //
  119.     // Initialize the UART.
  120.     //
  121.     ConfigureUART();

  122. //    //
  123. //    // Hello!
  124. //    //
  125.     UARTprintf("Hello, world!\n");
  126.     ui32Loop=0;
  127.     ui32Loop=ROM_SysCtlClockGet();
  128.     UARTprintf("%d\n",ui32Loop);
  129.     ui32Loop=0;
  130.     ui32Loop=SysCtlClockGet();
  131.     UARTprintf("%d\n",ui32Loop);
  132.     //
  133.     // We are finished.  Hang around doing nothing.
  134.     //
  135.     while(1)
  136.     {
  137.         //
  138.         // Turn on the BLUE LED.

  139. /*        GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2);

  140.         //
  141.         // Delay for a bit.
  142.         //
  143.         SysCtlDelay(50000000 / 3000);

  144.         //
  145.         // Turn off the BLUE LED.
  146.         //
  147.         GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0);

  148.         //
  149.         // Delay for a bit.
  150.         //
  151.         SysCtlDelay(50000000 / 3000);*/
  152.                     GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2);

  153.                     //
  154.                     // Delay for a bit.
  155.                     //
  156.                     SysCtlDelay(ROM_SysCtlClockGet() / 3000);

  157.                     //
  158.                     // Turn off the BLUE LED.
  159.                     //
  160.                     GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0);

  161.                     //
  162.                     // Delay for a bit.
  163.                     //
  164.                     SysCtlDelay(ROM_SysCtlClockGet() / 3000);
  165.     }
  166. }
可以看到,系统主时钟为50000000

延时时间如下:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| xyz549040622 发表于 2015-11-25 16:50 | 显示全部楼层
本帖最后由 xyz549040622 于 2015-11-25 17:23 编辑

找到问题了终于,一定要开启FPU的,因为在计算50000000/3时浪费了一部分时间。下面进行准确延时的计算
dirtwillfly 发表于 2015-11-25 17:10 | 显示全部楼层
 楼主| xyz549040622 发表于 2015-11-25 17:22 | 显示全部楼层
本帖最后由 xyz549040622 于 2015-11-25 17:35 编辑

再次说明,这个延时确实要精确计算的,毕竟只是粗略延时,us级别,ms级别,s级别的参数都是不同的,现在做到主频率是80MHz的时候,SysCtlDelay(ROM_SysCtlClockGet()/3000)准确延时为2ms。
stalker张 发表于 2015-11-26 09:49 | 显示全部楼层
楼主,可有tiva板的资料,能否共享?
smilingangel 发表于 2015-11-26 14:40 | 显示全部楼层
这个延时程序很不错的,其他程序中俄可采用。
 楼主| xyz549040622 发表于 2015-11-26 14:49 | 显示全部楼层
stalker张 发表于 2015-11-26 09:49
楼主,可有tiva板的资料,能否共享?

官网就有的呀。
yyj8902 发表于 2015-11-28 15:53 | 显示全部楼层
stalker张 发表于 2015-11-26 09:49
楼主,可有tiva板的资料,能否共享?

去TI的官网下载,每种评估板的资料都有的。
stalker张 发表于 2015-11-28 17:32 | 显示全部楼层
yyj8902 发表于 2015-11-28 15:53
去TI的官网下载,每种评估板的资料都有的。

谢谢
309030 发表于 2015-11-28 20:25 | 显示全部楼层
版主的哪个截图使用什么仿真出来的
10299823 发表于 2015-11-29 22:25 | 显示全部楼层
最好使用定时器的。
10299823 发表于 2015-11-29 22:26 | 显示全部楼层
其他的准确率不如定时器。
10299823 发表于 2015-11-29 22:29 | 显示全部楼层
使用延时不好控制。
cemaj 发表于 2015-11-29 22:31 | 显示全部楼层
这个精确吗
pmp 发表于 2015-11-30 06:10 | 显示全部楼层
用示波器测量过?
haolaishi 发表于 2015-11-30 11:58 | 显示全部楼层
xyz549040622 发表于 2015-11-25 17:22
再次说明,这个延时确实要精确计算的,毕竟只是粗略延时,us级别,ms级别,s级别的参数都是不同的,现在做 ...

我试了试,只有这个2ms准确点,其他的误差就很大了,不知道为什么
linlovelife 发表于 2016-1-15 13:41 | 显示全部楼层
学习了!
vivilzb1985 发表于 2016-1-15 22:32 | 显示全部楼层
弱弱的问一句的,这个时钟的采用哪一个的?
lzyyoumuren 发表于 2016-1-26 16:55 | 显示全部楼层
用定时器定时一般比较准确
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:qq群: 嵌入式系统arm初学者 224636155←← +→→点击-->小 i 精品课全集,21ic公开课~~←←→→点击-->小 i 精品课全集,给你全方位的技能策划~~←←

2841

主题

19330

帖子

110

粉丝
快速回复 在线客服 返回列表 返回顶部