TIVA注意使能模块时钟时需要加个6cycle以上的延时

[复制链接]
1024|7
 楼主| xyz549040622 发表于 2016-8-1 08:38 | 显示全部楼层 |阅读模式
  1. 很多用户在使用TI M4的时候,会忽略一个细节,在使能外设模块时钟,直接去操作此模块,会导致进入FaultIsr中断服务入口,导致无法调试。

  2. 在函数注释说明有个NOTE,大家可能没有注意到。如下:

  3. //! \note It takes five clock cycles after the write to enable a peripheral
  4. //! before the the peripheral is actually enabled. During this time, attempts
  5. //! to access the peripheral result in a bus fault. Care should be taken
  6. //! to ensure that the peripheral is not accessed during this brief time
  7. //! period.

  8. extern void SysCtlPeripheralEnable(uint32_t ui32Peripheral);

  9. //*****************************************************************************
  10. //
  11. //! Enables a peripheral.
  12. //!
  13. //! \param ui32Peripheral is the peripheral to enable.
  14. //!
  15. //! This function enables a peripheral. At power-up, all peripherals are
  16. //! disabled; they must be enabled in order to operate or respond to register
  17. //! reads/writes.
  18. //!
  19. //! The \e ui32Peripheral parameter must be only one of the following values:
  20. //! \b SYSCTL_PERIPH_ADC0, \b SYSCTL_PERIPH_ADC1, \b SYSCTL_PERIPH_CAN0,
  21. //! \b SYSCTL_PERIPH_CAN1, \b SYSCTL_PERIPH_CCM0,\b SYSCTL_PERIPH_COMP0,
  22. //! \b SYSCTL_PERIPH_EEPROM0, \b SYSCTL_PERIPH_EMAC, \b SYSCTL_PERIPH_EPHY,
  23. //! \b SYSCTL_PERIPH_EPI0,
  24. //! \b SYSCTL_PERIPH_GPIOA, \b SYSCTL_PERIPH_GPIOB, \b SYSCTL_PERIPH_GPIOC,
  25. //! \b SYSCTL_PERIPH_GPIOD, \b SYSCTL_PERIPH_GPIOE, \b SYSCTL_PERIPH_GPIOF,
  26. //! \b SYSCTL_PERIPH_GPIOG, \b SYSCTL_PERIPH_GPIOH, \b SYSCTL_PERIPH_GPIOJ,
  27. //! \b SYSCTL_PERIPH_GPIOK, \b SYSCTL_PERIPH_GPIOL, \b SYSCTL_PERIPH_GPIOM,
  28. //! \b SYSCTL_PERIPH_GPION, \b SYSCTL_PERIPH_GPIOP, \b SYSCTL_PERIPH_GPIOQ,
  29. //! \b SYSCTL_PERIPH_GPIOR, \b SYSCTL_PERIPH_GPIOS, \b SYSCTL_PERIPH_GPIOT,
  30. //! \b SYSCTL_PERIPH_HIBERNATE,
  31. //! \b SYSCTL_PERIPH_I2C0, \b SYSCTL_PERIPH_I2C1, \b SYSCTL_PERIPH_I2C2,
  32. //! \b SYSCTL_PERIPH_I2C3, \b SYSCTL_PERIPH_I2C4, \b SYSCTL_PERIPH_I2C5,
  33. //! \b SYSCTL_PERIPH_I2C6, \b SYSCTL_PERIPH_I2C7, \b SYSCTL_PERIPH_I2C8,
  34. //! \b SYSCTL_PERIPH_I2C9, \b SYSCTL_PERIPH_LCD0,
  35. //! \b SYSCTL_PERIPH_ONEWIRE0,
  36. //! \b SYSCTL_PERIPH_PWM0, \b SYSCTL_PERIPH_PWM1, \b SYSCTL_PERIPH_QEI0,
  37. //! \b SYSCTL_PERIPH_QEI1, \b SYSCTL_PERIPH_SSI0, \b SYSCTL_PERIPH_SSI1,
  38. //! \b SYSCTL_PERIPH_SSI2, \b SYSCTL_PERIPH_SSI3, \b SYSCTL_PERIPH_TIMER0,
  39. //! \b SYSCTL_PERIPH_TIMER1, \b SYSCTL_PERIPH_TIMER2, \b SYSCTL_PERIPH_TIMER3,
  40. //! \b SYSCTL_PERIPH_TIMER4, \b SYSCTL_PERIPH_TIMER5, \b SYSCTL_PERIPH_TIMER6,
  41. //! \b SYSCTL_PERIPH_TIMER7, \b SYSCTL_PERIPH_UART0, \b SYSCTL_PERIPH_UART1,
  42. //! \b SYSCTL_PERIPH_UART2, \b SYSCTL_PERIPH_UART3, \b SYSCTL_PERIPH_UART4,
  43. //! \b SYSCTL_PERIPH_UART5, \b SYSCTL_PERIPH_UART6, \b SYSCTL_PERIPH_UART7,
  44. //! \b SYSCTL_PERIPH_UDMA, \b SYSCTL_PERIPH_USB0, \b SYSCTL_PERIPH_WDOG0,
  45. //! \b SYSCTL_PERIPH_WDOG1, \b SYSCTL_PERIPH_WTIMER0, \b SYSCTL_PERIPH_WTIMER1,
  46. //! \b SYSCTL_PERIPH_WTIMER2, \b SYSCTL_PERIPH_WTIMER3,
  47. //! \b SYSCTL_PERIPH_WTIMER4, or \b SYSCTL_PERIPH_WTIMER5
  48. //!
  49. //! \note It takes five clock cycles after the write to enable a peripheral
  50. //! before the the peripheral is actually enabled. During this time, attempts
  51. //! to access the peripheral result in a bus fault. Care should be taken
  52. //! to ensure that the peripheral is not accessed during this brief time
  53. //! period.

  54. //!
  55. //! \return None.
  56. //
  57. //*****************************************************************************
  58. void
  59. SysCtlPeripheralEnable(uint32_t ui32Peripheral)
  60. {
  61. //
  62. // Check the arguments.
  63. //
  64. ASSERT(_SysCtlPeripheralValid(ui32Peripheral));

  65. //
  66. // Enable this peripheral.
  67. //
  68. HWREGBITW(SYSCTL_RCGCBASE + ((ui32Peripheral & 0xff00) >> 8),
  69. ui32Peripheral & 0xff) = 1;
  70. }
有两种解决方法:
1.直接系统延时
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
SysCtlDelay(6);
2.等待模块时钟配置成功
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_TIMER0)); //读取其模块时钟状态

dirtwillfly 发表于 2016-8-1 09:26 | 显示全部楼层
感谢分享
mmbs 发表于 2016-8-1 23:09 | 显示全部楼层
为什么要六个延时?
mmbs 发表于 2016-8-1 23:11 | 显示全部楼层
tiva的寄存器配置需要吗?
 楼主| xyz549040622 发表于 2016-8-2 09:10 | 显示全部楼层
mmbs 发表于 2016-8-1 23:09
为什么要六个延时?

这是官方提供的数据,不知道为什么。我们会使用就好啦。应该是等待时钟稳定了。
cemaj 发表于 2016-8-2 21:57 | 显示全部楼层
xyz549040622 发表于 2016-8-2 09:10
这是官方提供的数据,不知道为什么。我们会使用就好啦。应该是等待时钟稳定了。 ...

这个六个延时,用的是多大的晶振?
cemaj 发表于 2016-8-2 21:59 | 显示全部楼层
有没有相关的寄存器可以读取?
vibra2016 发表于 2016-8-2 22:15 | 显示全部楼层
6个cycle的延时的还是挺少的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

2841

主题

19330

帖子

110

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