[牛人杂谈] IP的初始化流程

[复制链接]
1128|8
 楼主| xinpian101 发表于 2018-3-11 08:47 | 显示全部楼层 |阅读模式
本帖最后由 xinpian101 于 2018-3-11 09:06 编辑

芯片一般包含5种时钟源:
 内部高速振荡器HIRC(一般是22.1184M,也有的是12M或者16M)
 内部低速振荡器LIRC(一般是10K,有的是32K)
 外部高速晶振HXT(范围一般是4~24M)
 外部低速晶振LXT(32K)
 PLL
注意:有的芯片外部晶振HXT和LXT是共用引脚的。
为了省电,上电之后,默认只有HIRC是起振的,其他的晶振都需要软件使能才会起振。起振之后也不是马上供给各个IP,也需要软件使能之后该IP才会有时钟,它的寄存器才能被访问和读/写。
每个IP的初始化包括2部分,系统初始化和IP本身功能的初始化,流程如下:
1) 系统初始化
 选择IP时钟源,一般有上面5种可以选择。如果某个IP的时钟源不能选择,则它的时钟源就是HCLK(就是CPU的时钟)。选择时钟源之前,IP默认选择的时钟源和将选择的时钟源必须都要保持使能。不然IP将不工作。一般IP默认选择的时钟都是HIRC,如果IP想选择HXT做时钟源,必须先使能HXT(如果没有修改过Config0,上电后HIRC默认是使能的),然后IP才能切换时钟源。千万不能先关闭HIRC,再切IP的时钟源,这样IP会不工作的,或者工作不正常。虽然在切时钟源的时候IP也许并没有工作,但是也要保证2个时钟源(当前选择的和将要选择的)都是使能的才能切时钟源。
注:Config0是用户配置区寄存器,用于配置上电默认使能的时钟、启动的Flash、加密、使能DataFlash等
 使能IP时钟
 配置MFP寄存器(多功能引脚寄存器)
2) 最后配置IP的功能
每个IP系统初始化步骤都是一样的:选择时钟源、使能时钟、配置多功能引脚。


 楼主| xinpian101 发表于 2018-3-11 09:55 | 显示全部楼层
/* Enable UART module clock */
    CLK_EnableModuleClock(UART0_MODULE);

    /* Select UART module clock source as HXT and UART module clock divider as 1 */
    CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UARTSEL_HXT, CLK_CLKDIV0_UART(1));

    /* Enable EADC module clock */
    CLK_EnableModuleClock(EADC_MODULE);

    /* EADC clock source is 72MHz, set divider to 8, ADC clock is 72/8 MHz */
    CLK_SetModuleClock(EADC_MODULE, 0, CLK_CLKDIV0_EADC(8));
类似这两个操作,就是这样,先使能,然后切换,之前有朋友质疑这个问题,不用怀疑了,以例程序为准。
huangcunxiake 发表于 2018-3-12 11:42 | 显示全部楼层
让我对时钟有了进一步了解。
Alisa000 发表于 2018-3-12 15:23 | 显示全部楼层
新唐一级代理,提供技术支持QQ1574540195 欢迎交流
gejigeji521 发表于 2018-3-15 11:48 | 显示全部楼层
大家可以试试看,调整顺序到底有没有影响。
643757107 发表于 2018-3-17 23:08 | 显示全部楼层
Config0是用户配置区寄存器,用于配置上电默认使能的时钟、启动的Flash、加密、使能DataFlash等
那么上电默认的IO可以设置吗
捉虫天师 发表于 2018-3-19 08:44 | 显示全部楼层
你可以参考官方的例子和网友们的例子,以及各种第三方例子,你会发现,这个一般就那么几种不同的设置,大部分都是相通的,因此你copy就行了。
捉虫天师 发表于 2018-3-19 08:45 | 显示全部楼层
比如下面是蹄牛系统在M051上的初始化代码,你会发现没啥毛病,是不是老铁。
  1. void SYS_Init(void)
  2. {
  3.         /*---------------------------------------------------------------------------------------------------------*/
  4.         /* Init System Clock                                                                                       */
  5.         /*---------------------------------------------------------------------------------------------------------*/

  6.         /* Enable Internal RC 22.1184MHz clock */
  7.         CLK->PWRCON |= CLK_PWRCON_OSC22M_EN_Msk;

  8.         /* Waiting for Internal RC clock ready */
  9.         while(!(CLK->CLKSTATUS & CLK_CLKSTATUS_OSC22M_STB_Msk));

  10.         /* Switch HCLK clock source to Internal RC and and HCLK source divide 1 */
  11.         CLK->CLKSEL0 &= ~CLK_CLKSEL0_HCLK_S_Msk;
  12.         CLK->CLKSEL0 |= CLK_CLKSEL0_HCLK_S_HIRC;
  13.         CLK->CLKDIV &= ~CLK_CLKDIV_HCLK_N_Msk;
  14.         CLK->CLKDIV |= CLK_CLKDIV_HCLK(1);

  15.         /* Enable external XTAL 12MHz clock */
  16.         CLK->PWRCON |= CLK_PWRCON_XTL12M_EN_Msk;

  17.         /* Waiting for external XTAL clock ready */
  18.         while(!(CLK->CLKSTATUS & CLK_CLKSTATUS_XTL12M_STB_Msk));

  19.         /* Set core clock as PLL_CLOCK from PLL */
  20.         CLK->PLLCON = PLLCON_SETTING;
  21.         while(!(CLK->CLKSTATUS & CLK_CLKSTATUS_PLL_STB_Msk));
  22.         CLK->CLKSEL0 &= (~CLK_CLKSEL0_HCLK_S_Msk);
  23.         CLK->CLKSEL0 |= CLK_CLKSEL0_HCLK_S_PLL;

  24.         /* Update System Core Clock */
  25.         /* User can use SystemCoreClockUpdate() to calculate PllClock, SystemCoreClock and CycylesPerUs automatically. */
  26.         //SystemCoreClockUpdate();
  27.         PllClock        = PLL_CLOCK;            // PLL
  28.         SystemCoreClock = PLL_CLOCK / 1;        // HCLK
  29.         CyclesPerUs     = PLL_CLOCK / 1000000;  // For SYS_SysTickDelay()

  30.         /* Enable UART module clock */
  31.         CLK->APBCLK |= CLK_APBCLK_UART0_EN_Msk;

  32.         /* Select UART module clock source */
  33.         CLK->CLKSEL1 &= ~CLK_CLKSEL1_UART_S_Msk;
  34.         CLK->CLKSEL1 |= CLK_CLKSEL1_UART_S_HXT;

  35.         /*---------------------------------------------------------------------------------------------------------*/
  36.         /* Init I/O Multi-function                                                                                 */
  37.         /*---------------------------------------------------------------------------------------------------------*/

  38.         /* Set P3 multi-function pins for UART0 RXD , TXD and CKO */
  39.         SYS->P3_MFP &= ~(SYS_MFP_P30_Msk | SYS_MFP_P31_Msk);
  40.         SYS->P3_MFP |= (SYS_MFP_P30_RXD0 | SYS_MFP_P31_TXD0);
  41. }
xixi2017 发表于 2018-3-20 17:23 | 显示全部楼层
切换时钟的方法就是保持原来时钟不变,使能新的时钟,配置,稳定后,才可以关闭原来的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

129

主题

1650

帖子

1

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