您的位置 首页 模拟

Cortex-M3 (NXP LPC1788)之SysTick体系节拍定时器

在GPIO控制篇中的延时闪烁LED只用了简单的for循环,为了精确的计时本篇介绍使用SysTick定时器每1ms产生中断,从而实现精确定时的目…

在GPIO操控篇中的延时业绩LED只用了简略的for循环,为了准确的计时本篇介绍运用SysTick守时器每1ms发生中止,然后完成准确守时的意图。要运用体系节拍守时器首要进行两个部分的装备。1:体系时钟操控。2体系节拍守时器的操控。

一,体系时钟操控

LPC1788有3个独立的振荡器。他们是主振荡器,内部RC振荡器,RTC振荡器。复位后,LPC1788将用内部的RC振荡器运转,直到被软件切换。这样就能在没有任何外部晶振的情况下运转。LPC1788的时钟操控如图1所示

在开发板上运用12M的晶振奋为主振荡器,它经过锁相环PLL0来进步频率供给CPU。咱们芯片总是从内部的RC振荡器开端作业,因而主振荡器只会应软件的恳求而发动。完成办法是设定SCS寄存器中的OSCEN位使能。主振荡器供给一个状况标志SCS寄存器的OSCSTAT位,这样软件就能够确认何时主振荡器在运转安稳。此刻,软件能够操控切换到主振荡器,使其作为时钟源。在发动曾经,有必要经过SCS的OSCRANGE位,挑选一个频率规模。在确认了主振荡器之后,需求进行锁相环的装备。1,装备CLKSRCSEL挑选正确的时钟源。2,将正确的PLL设置值写入PLLCFG寄存器而且在PLLCON中使能PLL。3,向PLLFEED寄存器中写入馈送序列0xAA,0x55。4,设置所需的时钟分配器如CCLKSEL,PCLSEL,EMCCLKSEL,以及USBCLKSEL寄存器。5,查询PLLSTAT寄存器等候PLL确定。

二,体系节拍守时器的操控

LPC1788的体系节拍守时器是一个24位的守时器,当数值到达0时发生中止。体系节拍守时器的时钟信号能够由CPU时钟供给(即图1中的cclk)。想要在规则的时刻距离循环的发生中止,有必要将指定的正确时刻距离值装入STRELOAD寄存器进行初始化。假设咱们挑选cclk作为体系节拍的时钟信号,而且依据开发板将体系时钟设置成12MHZ,为了循环1ms发生一次中止,咱们写入STRELOAD的值为cclk/1000 – 1 。

程序的代码如下,使LED灯每500ms业绩。SystemInit函数在发动文件中被调用。

  1. #definerFIO1DIR(*(volatileunsigned*)0x20098020)
  2. #definerFIO1MASK(*(volatileunsigned*)0x20098030)
  3. #definerFIO1PIN(*(volatileunsigned*)0x20098034)
  4. #definerFIO1SET(*(volatileunsigned*)0x20098038)
  5. #definerFIO1CLR(*(volatileunsigned*)0x2009803c)
  6. #definerCLKSRCSEL(*(unsigned*)(0x400FC10C))//时钟源挑选寄存器
  7. #definerPLL0CON(*(unsigned*)(0x400FC080))//PLL0操控寄存器
  8. #definerPLL0CFG(*(unsigned*)(0x400FC084))//PLL0装备寄存器
  9. #definerPLL0STAT(*(unsigned*)(0x400FC088))//PLL0状况寄存器
  10. #definerPLL0FEED(*(unsigned*)(0x400FC08C))//PLL0馈送寄存器
  11. #definerPLL1CON(*(unsigned*)(0x400FC0A0))
  12. #definerPLL1CFG(*(unsigned*)(0x400FC0A4))
  13. #definerPLL1STAT(*(unsigned*)(0x400FC0A8))
  14. #definerPLL1FEED(*(unsigned*)(0x400FC0AC))
  15. #definerCCLKSEL(*(unsigned*)(0x400FC104))//CPU时钟挑选寄存器
  16. #definerUSBCLKSEL(*(unsigned*)(0x400FC108))//USB时钟挑选寄存器
  17. #definerPCLKSEL(*(unsigned*)(0x400FC1A8))//外设时钟寄存器
  18. #definerPCON(*(unsigned*)(0x400FC0C0))
  19. #definerPXCONP(*(unsigned*)(0x400FC0C4))
  20. #definerSCS(*(unsigned*)(0x400FC1A0))//体系操控和状况寄存器
  21. #definerCLKOUTCFG(*(unsigned*)(0x400FC1C8))
  22. #definerSTCTRL(*(unsigned*)(0xE000E010))
  23. #definerSTRELOAD(*(unsigned*)(0xE000E014))
  24. #definerSTCURR(*(unsigned*)(0xE000E018))
  25. #definerSTALIB(*(unsigned*)(0xE000E01C))
  26. #defineCCLK120000000
  27. volatileunsignedlongSysTickCnt;
  28. /*
  29. 体系时钟初始化
  30. */
  31. voidSystemInit()
  32. {
  33. rSCS&=~(0x1<<4);//频率12M
  34. rSCS|=(0x1<<5);//使能主振荡器
  35. while(0==(rSCS&(0x1<<6)));//等候主振荡器安稳
  36. rCLKSRCSEL=0x1;
  37. rPLL0CFG=0x9;//装备CCLK=120M
  38. rPLL0CON=0x01;
  39. rPLL0FEED=0xAA;
  40. rPLL0FEED=0x55;
  41. while(0==(rPLL0STAT&(0x1<<10)));
  42. rCCLKSEL=(0x1|(0x1<<8));
  43. rPCLKSEL=0x2;//装备PCLK=60M
  44. rCLKOUTCFG=0x0|(0xb<<4)|(0x1<<8);
  45. }
  46. /*
  47. 体系节拍守时器初始化
  48. */
  49. unsignedcharSysTick_Config(unsignedintticks)
  50. {
  51. if(ticks>0xFFFFFFUL)
  52. return0;
  53. rSTRELOAD=ticks;
  54. rSTCURR=0x0;
  55. rSTCTRL=(0x1)|(0x1<<1)|(0x1<<2);
  56. return1;
  57. }
  58. /*
  59. 体系节拍守时器中止处理函数
  60. */
  61. voidSysTick_Handler(void)
  62. {
  63. SysTickCnt++;
  64. }
  65. intmain()
  66. {
  67. unsignedcharvalue=1;
  68. SysTick_Config(CCLK/1000-1);//每1ms发生一次SysTick体系反常
  69. rFIO1DIR|=(1<<18);//GPIO1.18->OUTPUT
  70. while(1)
  71. {
  72. if(SysTickCnt>=500)
  73. {
  74. SysTickCnt=0;
  75. value=!value;
  76. }
  77. if(0==value)
  78. {
  79. rFIO1PIN&=~(1<<18);
  80. }
  81. elseif(1==value)
  82. {
  83. rFIO1PIN|=(1<<18);
  84. }
  85. }
  86. }

关于SysTick的反常的优先级能够在SHPR3中进行设置,优先级等级能够从0~31。初始化默以为0,只低于固定的负数优先级的复位,硬件毛病和NMI。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/zhishi/moni/265681.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部