i.MX6ULL终结者主频和时钟配置例程程序设计

本实验对应的例程在光盘资料的:i.MX6UL终结者光盘资料\04_裸机例程源码\7_clk 目录下面,我们在Ubuntu系统下使用命令“mkdir 7_clk”建立“7_clk”文件夹,如图 1所示:
在这里插入图片描述

图 1

然后使用命令“cd 7_clk”进入7_clk文件。如图 2所示:
在这里插入图片描述

图 2

然后使用命令“cp -r …/6_key/* ./”将上一章试验中的所有内容拷贝到刚刚新建的“7_clk”里面,如图 3:
在这里插入图片描述

图 3

拷贝完成以后的工程如图 4所示:
在这里插入图片描述

图 4

然后使用命令“vi drivers/clk/clk.h”修改clk.h文件。如图 5所示:
在这里插入图片描述

图 5

修改如下内容:

  1 #ifndef __BSP_CLK_H
  2 #define __BSP_CLK_H
  3 
  4 #include "imx6ul.h"
  5 
  6 /* 函数声明 */
  7 void clk_enable(void);
  8 void imx6u_clkinit(void);
  9 
 10 
 11 #endif

gpio.h文件中是两个函数声明。主要是第7行添加void clk_enable和第8行添加 imx6u_clkinit函数声明,部分截图如图 6所示:
在这里插入图片描述

图 6

添加完成之后,保存并退出文件。
然后使用命令“vi drivers/clk/clk.c”修改clk.c文件。如图 7所示:
在这里插入图片描述

图 7

添加内容如下:

 1 #include "clk.h"
  2 
  3 /*
  4  * @description : 使能I.MX6U所有外设时钟
  5  * @param               : 无
  6  * @return              : 无
  7  */
  8 void clk_enable(void)
  9 {
 10         CCM->CCGR0 = 0XFFFFFFFF;
 11         CCM->CCGR1 = 0XFFFFFFFF;
 12         CCM->CCGR2 = 0XFFFFFFFF;
 13         CCM->CCGR3 = 0XFFFFFFFF;
 14         CCM->CCGR4 = 0XFFFFFFFF;
 15         CCM->CCGR5 = 0XFFFFFFFF;
 16         CCM->CCGR6 = 0XFFFFFFFF;
 17 }
 18 
 19 /*
 20  * @description : 初始化系统时钟,设置系统时钟为528Mhz,设置PLL2和
 21                PLL3各个PFD时钟,所有时钟频率按照I.MX6U官方手册推荐的值.
 22  * @param              : 无
 23  * @return              : 无
 24  */
 25 void imx6u_clkinit(void)
 26 {
 27         unsigned int reg = 0;
 28         /* 1、设置ARM内核时钟为528MHz */
 29         /* 1.1、判断当前ARM内核是使用的哪个时钟源启动的,
正常情况下ARM内核是由pll1_sw_clk驱动的,而
 30          *      pll1_sw_clk有两个来源:pll1_main_clk和tep_clk。
 31          *      如果要让ARM内核跑到528M的话必须选择
pll1_main_clk作为pll1的时钟源。
 32          *      如果我们要修改pll1_main_clk时钟的话就必须
                    先将pll1_sw_clk从pll1_main_clk切换到step_clk,
 33          *      当修改完pll1_main_clk以后在将pll1_sw_clk
                    切换回pll1_main_clk。而step_clk的时钟源可以选择
 34          *      板子上的24MHz晶振。
 35          */
 36 
 37         if((((CCM->CCSR) >> 2) & 0x1 ) == 0) /* 当前pll1_sw_clk使用pll1_main_clk*/
 38         {
 39                 CCM->CCSR &= ~(1 << 8); /* 配置step_clk时钟源为24MH OSC */
 40                 CCM->CCSR |= (1 << 2);  /* 配置pll1_sw_clk时钟源为step_clk */
 41         }
 42 
 43         /* 1.2、设置pll1_main_clk为1056MHz,也就是528*2=1056MHZ,
 44          *      因为pll1_sw_clk进ARM内核的时候会被二分频!
 45          *      配置CCM_ANLOG->PLL_ARM寄存器
 46          *      bit13: 1 使能时钟输出
 47          *      bit[6:0]: 88, 由公式:Fout = Fin * div_select / 2.0,
                    1056=24*div_select/2.0,
 48          *      得出:div_select=    88  
 49          */
 50         CCM_ANALOG->PLL_ARM = (1 << 13) 
                            | ((88 << 0) & 0X7F);   /* 配置pll1_main_clk=1056MHz */
 51            CCM->CCSR &= ~(1 << 2);                                                                 
 52            CCM->CACRR = 1;                                                                                 
 53 
 54         /* 2、设置PLL2(SYS PLL)各个PFD */
 55         reg = CCM_ANALOG->PFD_528;
 56           reg&=~(0X3F3F3F3F);/*清除原来设置 */
 57         reg |= 32<<24; /* PLL2_PFD3=528*18/32=297Mhz */
 58         reg |= 24<<16; /*PLL2_PFD2=528*18/24=396Mhz(DDR时钟最大400Mhz) */
  
 59         reg |= 16<<8;     /* PLL2_PFD1=528*18/16=594Mhz*/   
 60         reg |= 27<<0;     /* PLL2_PFD0=528*18/27=352Mhz   
*/
 61         CCM_ANALOG->PFD_528=reg; /* 设置PLL2_PFD0~3*/                         
 62 
 63         /* 3、设置PLL3(USB1)各个PFD */
 64         reg = 0;                      /* 清零   */
 65         reg = CCM_ANALOG->PFD_480;
 66         reg &= ~(0X3F3F3F3F);      /* 清除原来的设置 */                                                      
 67         reg |= 19<<24;            /* PLL3_PFD3=480*18/19=454.74Mhz */
 68         reg |= 17<<16;            /* PLL3_PFD2=480*18/17=508.24Mhz*/
 69         reg |= 16<<8;            /* PLL3_PFD1=480*18/16=540Mhz */
 70         reg |= 12<<0;            /* PLL3_PFD0=480*18/12=720Mhz */    
 71         CCM_ANALOG->PFD_480=reg; /* 设置PLL3_PFD0~3 */                             
 72 
 73         /* 4、设置AHB时钟最小6Mhz,最大132Mhz (boot rom设置好了不用设置)*/
 74         CCM->CBCMR &= ~(3 << 18);       /* 清除设置*/
 75         CCM->CBCMR |= (1 << 18);        /* pre_periph_clk=PLL2_PFD2=396MHz */
 76         CCM->CBCDR &= ~(1 << 25);       /* periph_clk=pre_periph_clk=396MHz */
 77         while(CCM->CDHIPR & (1 << 5));/* 等待握手完成 */
 78 
 79         /* 修改AHB_PODF位的时候需要先禁止AHB_CLK_ROOT的输出,但是
 80          * 我没有找到关闭AHB_CLK_ROOT输出的的寄存器,所以就没法设置。
 81          * 下面设置AHB_PODF的代码仅供学习参考不能直接拿来使用!!
 82          * 内部boot rom将AHB_PODF设置为了3分频,即使我们不设置AHB_PODF,
 83          * AHB_ROOT_CLK也依旧等于396/3=132Mhz。
 84          */
 85 #if 0
 86         /* 要先关闭AHB_ROOT_CLK输出,否则时钟设置会出错 */
 87         CCM->CBCDR &= ~(7 << 10);       /* CBCDR的AHB_PODF清零 */
 88         CCM->CBCDR |= 2 << 10; /* AHB_PODF 3分频,AHB_CLK_ROOT=132MHz */
 89         while(CCM->CDHIPR & (1 << 1));/* 等待握手完成 */
 90 
 91 #endif
 92 
 93         /* 5、设置IPG_CLK_ROOT最小3M最大66M (boot rom设置好了不用设置)*/
 94         CCM->CBCDR &= ~(3 << 8);        /* CBCDR的IPG_PODF清零 */
 95         CCM->CBCDR |= 1 << 8;           /* IPG_PODF 2分频IPG_CLK_ROOT=66M */
96 
 97         /* 6、设置PERCLK_CLK_ROOT时钟 */
 98         CCM->CSCMR1 &= ~(1 << 6);       /* PERCLK_CLK_ROOT时钟源为IPG */
 99         CCM->CSCMR1 &= ~(7 << 0);       /* PERCLK_PODF位清零,即1分频 */
100 }
101 

文件clk.c 中有两个函数:clk_enable和新添加的imx6u_clkinit。
clk_enable:使能I.MX6U的所有外设时钟。
imx6u_clkinit:先设置系统主频为528MHz,然后设置8路PFD,最后设置AHB、IPG和PERCLK的时钟频率。
然后使用命令“vi main.c”打开main.c。如图 8所示:
在这里插入图片描述

图 8

然后添加下面的内容:

  1 #include "clk.h"
  2 #include "delay.h"
  3 #include "led.h"
  4 #include "beep.h"
  5 #include "key.h"
  6 
  7 /*
  8  * @description : main函数
  9  * @param               : 无
 10  * @return              : 无
 11  */
 12 int main(void)
 13 {
 14         int i = 0;
 15         int keyvalue = 0;
 16         unsigned char led_state = OFF;
 17         unsigned char beep_state = OFF;
 18 
 19         imx6u_clkinit();         /* 初始化系统时钟   */
 20         clk_enable();            /* 使能所有的时钟  */
 21         led_init();          /* 初始化led*/
 22         beep_init();          /* 初始化beep*/
 23         key_init();             /* 初始化key*/
 24 
 25         while(1)
 26         {
 27                 keyvalue = key_getvalue();
 28                 if(keyvalue)
 29                 {
 30                         switch ((keyvalue))
 31                         {
 32                                 case KEY0_VALUE:
 33                                         beep_state = !beep_state;
 34                                         beep_switch(beep_state);
 35                                         break;
 36                         }
 37                 }
 38                 i++;
 39                 if(i==50)
 40                 {
 41                         i = 0;
 42                         led_state = !led_state;
 43                         led_switch(LED0, led_state);
 44                 }
 45 
 46                 delay(10);
 47         }
 48 
 49         return 0;
 50 }

我们在main.c里添加了clk.h头文件,然后主函数中添加初始化及使能clk的函数。在这里插入图片描述

©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页