其实,Exynos 4412的IROM代码已经设置了PLL,我们可以通过串口把IROM设置的PLL寄存器值打印出来,这些值打印出来是这样的(摘自韦东山老师的《嵌入式Linux系统开发完全手册_基于4412__上册》):
CLK_SRC_CPU = 0x01000001
CLK_DIV_DMC0 = 0x00111713
CLK_DIV_DMC1 = 0x01011171
CLK_SRC_TOP0 = 0x01110000
CLK_SRC_TOP1 = 0x00001000
CLK_DIV_TOP = 0x00015470
CLK_SRC_LEFTBUS = 0x00000001
CLK_DIV_LEFTBUS = 0x00000013
CLK_SRC_RIGHTBUS = 0x00000001
CLK_DIV_RIGHTBUS = 0x00000013
APLL_LOCK = 0x00000960
MPLL_LOCK = 0x00000000
EPLL_LOCK = 0x00000FFF
VPLL_LOCK = 0x00000FFF
CLK_DIV_CPU0 = 0x00773730
CLK_DIV_CPU1 = 0x00000077
APLL_CON1 = 0x00003800
APLL_CON0 = 0xA0640301
MPLL_CON1 = 0x00003800
MPLL_CON0 = 0xA0640301
EPLL_CON2 = 0x00000080
EPLL_CON1 = 0x66010000
EPLL_CON0 = 0x00600302
VPLL_CON2 = 0x00000080
VPLL_CON1 = 0x66016000
VPLL_CON0 = 0x006F0302
CLK_SRC_CPU = 0x01000001
CLK_SRC_DMC = 0x00111000
CLK_SRC_TOP0 = 0x01110000
CLK_SRC_TOP1 = 0x00001000
现在来计算 ARMCLK的时钟频率:
由上一节《Exynos4412时钟体系分析》的介绍我们知道,ARMCLK 有如下计算公式:
如下图所示:
由上边打印的寄存器CLK_SRC_CPU 的值为:
十六进制:0x01000001
二进制:0000 0001 0000 0000 0000 0000 0000 0001
BIT[0] 控制第1个MUX (即 MUXAPLL) ,该位值为1.
BIT[16]控制 第2个 MUX( 即MUXCORE) ,该位值为0.
所以由此看出ARMCLK时钟走的是如下的路线:
所以:ARMCLK = MUXCORE的输出 / DIVCORE / DIVCORE2
ARMCLK = MDIV x FIN / (PDIV x 2 ^ SDIV) / (CORE_RATIO + 1) / (CORE2_RATIO + 1)
= 0x64 x 24MHz / (3 x 2 ^ 1) / (0 + 1) / (0 + 1)
= 400 MHz
本次实验涉及3个小实验:
system_clock_disable_apll:不使用 APLL,让CPU运行于 24MHz 频率,观察 LED 闪烁是否变慢
system_clock_apll:重新设置APLL,让 CPU 运行于1.4GHz频率,观察 LED 闪烁是否变快
system_clock_plls:参考厂家提供的u-boot代码,设置所有PLL供后续章节使用第一个小实验
实现的目标:不使用 APLL,让CPU运行于 24MHz 频率,观察 LED 闪烁是否变慢
一、程序说明
我们在前一个实验,《Tiny4412之C语言实现流水灯》的基础上修改。
start.S大部分相同,只是增加一条函数调用语句
bl system_clock_init // 调用时钟初始化函数
如下图所示:
链接脚本system_clock.lds的内容和上一个实验key.lds完全相同,只把名字改了改;Makefile的内容也大部分一样,也只是改了改里边文件的名字,led.c文件和LED实验时完全相同,新增加了文件system_clock.c,代码如下:
/* CMU_CPU */
#define CLK_SRC_CPU (*(volatile unsigned int *)0x10044200)
#define CLK_DIV_CPU0 (*(volatile unsigned int *)0x10044500)
#define CLK_DIV_CPU1 (*(volatile unsigned int *)0x10044504)
/* CMU_DMC */
#define CLK_SRC_DMC (*(volatile unsigned int *)0x10040200)
#define CLK_DIV_DMC0 (*(volatile unsigned int *)0x10040500)
#define CLK_DIV_DMC1 (*(volatile unsigned int *)0x10040504)
/* CMU_TOP */
#define CLK_SRC_TOP0 (*(volatile unsigned int *)0x1003C210)
#define CLK_SRC_TOP1 (*(volatile unsigned int *)0x1003C214)
#define CLK_DIV_TOP (*(volatile unsigned int *)0x1003C510)
/* CMU_LEFTBUS */
#define CLK_SRC_LEFTBUS (*(volatile unsigned int *)0x10034200)
#define CLK_DIV_LEFTBUS (*(volatile unsigned int *)0x10034500)
/* CMU_RIGHTBUS */
#define CLK_SRC_RIGHTBUS (*(volatile unsigned int *)0x10038200)
#define CLK_DIV_RIGHTBUS (*(volatile unsigned int *)0x10038500)
/* locktime */
#define APLL_LOCK (*(volatile unsigned int *)0x10044000)
#define MPLL_LOCK (*(volatile unsigned int *)0x10044008)
#define EPLL_LOCK (*(volatile unsigned int *)0x1003C010)
#define VPLL_LOCK (*(volatile unsigned int *)0x1003C020)
/* APLL */
#define APLL_CON1 (*(volatile unsigned int *)0x10044104)
#define APLL_CON0 (*(volatile unsigned int *)0x10044100)
/* MPLL */
#define MPLL_CON0 (*(volatile unsigned int *)0x10040108)
#define MPLL_CON1 (*(volatile unsigned int *)0x1004010c)
/* EPLL */
#define EPLL_CON2 (*(volatile unsigned int *)0x1003C118)
#define EPLL_CON1 (*(volatile unsigned int *)0x1003C114)
#define EPLL_CON0 (*(volatile unsigned int *)0x1003C110)
/* VPLL */
#define VPLL_CON0 (*(volatile unsigned int *)0x1003C120)
#define VPLL_CON1 (*(volatile unsigned int *)0x1003C124)
#define VPLL_CON2 (*(volatile unsigned int *)0x1003C128)
/*
* 函数名:
* system_clock_init
* 功能: 初始化4412的系统时钟
*/
void system_clock_init(void)
{
/* IROM或BL1设置了APLL,
* 本程序设置不启动APLL,
* 而是使在晶振时钟, 以体验一下LED闪灯变慢
*/
CLK_SRC_CPU = 0x0;
}
没什么可说的,很简单,前部分是后期会用到的一些寄存器地址的定义,主要的是下边system_clock_init这个函数,在这个函数中将CLK_SRC_CPU寄存器的值设为0,这样ARMCLK的频率将走下面这条路径,设置为24MHZ:
二、编译、烧写实验
按照前几节介绍的方法,将程序上传到服务器编译,并烧写到SD卡上,给开发板上电,可以明显感觉到LED闪烁的频率大大降低,说明我们设置的时钟起作用了,这里就不上图了(上了图大家也看不出来)。
第二个小实验
实现的目标:重新设置APLL,让 CPU 运行于1.4GHz频率,观察 LED 闪烁是否变快
一、程序说明
文件同第一个小实验,只是在它的基础上对system_clock.c文件中的system_clock_init函数进行修改:
/*
* 函数名: system_clock_init
* 功 能: 初始化4412的系统时钟
* 最终结果: APLL=1.4GHz
*/
void system_clock_init(void)
{
/*
* 1. 在设置APLL之前, 先设置时钟源为晶振
*/
CLK_SRC_CPU = 0x0;
/*
* 2. 设置APLL
*/
/* 2.1 设置锁定时间: APLL_CON0中PDIV=3, 所以APLL_LOCK = 270x3 */
APLL_LOCK = 270 * 3;
/* 2.2 设置分频参数 */
/*
* CORE2_RATIO = 0;
* APLL_RATIO = 2;
* PCLK_DBG_RATIO = 1;
* ATB_RATIO = 6;
* PERIPH_RATIO = 7;
* COREM1_RATIO = 7;
* COREM0_RATIO = 3;
* CORE_RATIO = 0;
*/
CLK_DIV_CPU0 = ((0<<28) | (2<<24) | (1<<20) | (6<<16) | (7<<12) | (7<<8) | (3<<4) | 0);
/*
* CORES_RATIO = 5;
* HPM_RATIO = 0;
* COPY_RATIO = 6;
*/
CLK_DIV_CPU1 = ((5 << 8) |(0 << 4) | (6));
/* 2.3 设置控制参数并使能PLL */
/* 默认值 */
APLL_CON1 = 0x00803800;
/*
* 设置APLL的M,P,S值, APLL输出 = 0xAF x 24MHz / (3 x 2 ^ 0) = 1.4GHz
* 使能APLL
*/
APLL_CON0 = (1<<31 | 0xAF<<16 | 3<<8 | 0x0);
/* 3. 设置MUX, 使用APLL的输出 */
CLK_SRC_CPU = 0x01000001;
}
注释的已经很清楚了,需要注意的就是:上电之后 IROM设置了APLL ,CPU工作于APLL提供的时钟;当我们要改变 APLL时,要先使得CPU工作于另一个时钟源,即晶振。设置完APLL后,再让CPU重新工作于APLL提供的时钟。
二、编译、烧写实验
按照前几节介绍的方法,将程序上传到服务器编译,并烧写到SD卡上,给开发板上电,可以明显感觉到LED闪烁的频率大大提高(比《Tiny4412之C语言实现流水灯》时闪烁的还要快,因为当时CPU运行在400MHZ,现在运行在1.4GHZ),说明我们设置的时钟起作用了,这里就不上图了(上了图大家也看不出来)。
第三个小实验
实现的目标:参考厂家提供的u-boot代码,设置所有PLL供后续章节使用
一、程序说明
文件同第一个小实验,只是在它的基础上对system_clock.c文件中的system_clock_init函数进行修改:
/*
函数名:
system_clock_init
功能:
初始化4412的系统时钟
最终结果:
A=1400000000, M=800000000, E=96000000 V=350000000
ARMCLK=1500000000, DMC=400000000, ACLK200=160000000
ACLK100=100000000, ACLK160=160000000, ACLK133=133333333
*/
void system_clock_init(void)
{
/* 1.设置CMU_CPU相关 */
CLK_SRC_CPU = 0x0; // 设置CMU_CPU部分中所有的MUX的源
/* 2.设置CMU_DMC相关 */
/*
CORE_TIMERS_RATIO = 0x0;
COPY2_RATIO = 0x0;
DMCP_RATIO = 0x1;
DMCD_RATIO = 0x1;
DMC_RATIO = 0x1;
DPHY_RATIO = 0x1;
ACP_PCLK_RATIO = 0x1;
ACP_RATIO = 0x3;
*/
CLK_DIV_DMC0 = ((0x0 << 28) | (0x0 << 24) | (0x1 << 20) | (0x1 << 16) | (0x1 << 12) | (0x1 << 8) | (0x1 << 4) | (0x3));
CLK_DIV_DMC1 = 0x07071713;
/* 3.设置CMU_TOP相关 */
/*
MUX_ONENAND_SEL = 0x0;
MUX_ACLK_133_SEL = 0x0;
MUX_ACLK_160_SEL = 0x0;
MUX_ACLK_100_SEL = 0x0;
MUX_ACLK_200_SEL = 0x0;
MUX_VPLL_SEL = 0x1;
MUX_EPLL_SEL = 0x1;
*/
CLK_SRC_TOP0 = ((0x0 << 28) | (0x0 << 24) | (0x0 << 20) | (0x0 << 16) | (0x0 << 12) | (0x1 << 8) | (0x1 << 4));
CLK_SRC_TOP1 = 0x01111000;
/*
ACLK_400_MCUISP_RATIO = 0x1;
ACLK_266_GPS_RATIO = 0x2;
ONENAND_RATIO = 0x1;
ACLK_133_RATIO = 0x5;
ACLK_160_RATIO = 0x4;
ACLK_100_RATIO = 0x7;
ACLK_200_RATIO = 0x4;
*/
CLK_DIV_TOP = ((0x1 << 24) | (0x2 << 20) | (0x1 << 16) | (0x5 << 12) | (0x4 << 8) | (0x7 << 4) | (0x4));
/* 3.设置CMU_LEFTBUS相关 */
CLK_SRC_LEFTBUS = 0x10;
/*
GPL_RATIO = 0x1;
GDL_RATIO = 0x3;
*/
CLK_DIV_LEFTBUS = ((0x1 << 4) | (0x3));
/* 4.设置CMU_RIGHTBUS相关 */
CLK_SRC_RIGHTBUS = 0x10;
/*
GPR_RATIO = 0x1;
GDR_RATIO = 0x3;
*/
CLK_DIV_RIGHTBUS = ((0x1 << 4) | (0x3));
/* 5.设置各个锁相环(PLL)的locktime */
APLL_LOCK = (0x3 * 270);
MPLL_LOCK = (0x3 * 270);
EPLL_LOCK = (0x2 * 3000);
VPLL_LOCK = (0x2 * 3000);
/*
APLL_RATIO = 0x2;
CORE_RATIO = 0x0;
CORE2_RATIO = 0x0;
COREM0_RATIO = 0x3;
COREM1_RATIO = 0x7;
PERIPH_RATIO = 0x7;
ATB_RATIO = 0x6;
PCLK_DBG_RATIO = 0x1;
*/
CLK_DIV_CPU0 = ((0x0 << 28) | (0x2 << 24) | (0x1 << 20) | (0x6 << 16) | (0x7 <<12) | (0x7 << 8) | (0x3 << 4) | (0x0));
/*
CORES_RATIO = 0x5;
HPM_RATIO = 0x0;
COPY_RATIO = 0x6;
*/
CLK_DIV_CPU1 = ((0x5 << 8) |(0x0 << 4) | (0x6));
/* 6.设置APLL = 1400000000 */
APLL_CON1 = 0x00803800;
APLL_CON0 = (1<<31 | 0xAF<<16 | 0x3<<8 | 0x0);
/* 7.设置MPLL = 800000000 */
MPLL_CON1 = 0x00803800;
MPLL_CON0 = (1<<31 | 0x64<<16 | 0x3<<8 | 0x0);
/* 8.设置EPLL = 96000000 */
EPLL_CON2 = 0x00000080;
EPLL_CON1 = 0x66010000;
EPLL_CON0 = (1<<31 | 0x40<<16 | 0x2<<8 | 0x3);
/* 9.设置VPLL = 350000000 */
VPLL_CON2 = 0x00000080;
VPLL_CON1 = 0x66010000;
VPLL_CON0 = (1<<31 | 0x48<<16 | 0x2<<8 | 0x3);
/*10.修改源*/
CLK_SRC_CPU = 0x01000001;
CLK_SRC_DMC = 0x00011000;
CLK_SRC_TOP0 = 0x00000110;
CLK_SRC_TOP1 = 0x01111000;
}
二、编译、烧写实验
按照前几节介绍的方法,将程序上传到服务器编译,并烧写到SD卡上,给开发板上电,现象和第二个小实验完全相同。
上一篇:TINY4412裸机程序,按键检测
下一篇:tiny4412 裸机程序 一、说明
推荐阅读最新更新时间:2024-11-08 10:38
推荐帖子
- 测评汇总:米尔基于NXP第一颗带NPU套件MYC-JX8MPQ
- 活动详情:【米尔基于NXP第一颗带NPU套件MYC-JX8MPQ】更新至2022-04-17测评报告汇总:@流行科技【米尔MYC-JX8MPQ评测】+完善QT端的sht20读取【米尔MYC-JX8MPQ评测】+人脸识别打开系统基于QT+OpenCV【米尔MYC-JX8MPQ评测】+QT调用OpenCV库进行测试【米尔MYC-JX8MPQ评测】+OpenCV库进行编译【米尔MYC-JX8MPQ评测】搭建QT开发环境【米尔MYC-JX8MPQ评测】+开箱点
- EEWORLD社区 测评中心专版
- 多个18b20温度传感器1602液晶显示
- 多个18b20温度传感器1602液晶显示多个18b20温度传感器1602液晶显示大哥,这也得花钱买啊?像我这样的新手没钱,发帖子也没人加分,怎办?1谢谢楼主回复楼主用心思考的帖子顶一个!辛苦了!正好学习一下!感谢!顶一个学习一下下载下来看看,学习中看看你内容收藏、。。确实需要啊!顶你个。学习回复楼主用心思考的帖子谢谢不错不知道是不是楼主原创哥,这也得花钱买啊?像我这样的新手没钱,发帖子也没人加分,怎办?大哥,这不错不知道是
- 用心思考 51单片机
- 第一次做东西的本科小弟求救:有关GPRS通信问题
- 系统实现的功能:将位置信息和指令通过GPRS发送给PC,pc根据收到的信息返回相关信息。实现这些功能至少需要哪些硬件?开发价格大概在多少?需要准备哪些知识(我现在只有数模电基础:(我会加油学的))?由于实在是水平和知识所限,以前有没有经验,恳请各位大哥帮小弟一把,不甚感激!ps:QQ361276269,注明GPRS,再次感谢!第一次做东西的本科小弟求救:有关GPRS通信问题
- syly 嵌入式系统
- PCM168x:具有通用前端的高性能音频ADC,展示自动的PGA裁剪抑制控制
- 打破传统ADC输入灵敏度设计,实现剪裁时自动低增益及高信噪比,跟随动画短片了解自动PGA裁剪抑制控制示范要领。PCM168x:具有通用前端的高性能音频ADC,展示自动的PGA裁剪抑制控制
- 德州仪器_视频 模拟与混合信号
- IAR汇编程序中多次使用RSEG伪指令是什么意思?
- 如题!IAR汇编程序中多次使用RSEG伪指令是什么意思?IAR汇编程序中多次使用RSEG伪指令是什么意思?IAR汇编程序中多次使用RSEG伪指令是什么意思?IAR汇编程序中多次使用RSEG伪指令是什么意思?IAR汇编程序中多次使用RSEG伪指令是什么意思?为什么不先搜一下?http://www.laogu.com/wz_2474.htmRSEG伪指令选择一个事先用SEGMENT伪指令声明的普通段。RSEG伪指令的格式如下:RSEGsegment其中segment是事先由SE
- chen611 嵌入式系统
- FPC压延铜与电解铜的区别有哪些不同呢?
- 在FPC(柔性电路板)的制造中,铜箔是至关重要的导电材料。常用的铜箔类型主要有压延铜(RA铜)和电解铜(ED铜)。这两种铜箔在制造工艺、物理性能、应用场景等方面存在显著区别。下面是它们的主要区别:1.制造工艺压延铜(RA铜):压延铜是通过物理轧制工艺制造的。将铜块加热后,进行反复轧制直到达到所需的厚度。由于这种轧制工艺,压延铜的晶粒结构呈纤维状,具有较高的延展性和柔韧性。电解铜(ED铜):电解铜是通过电化学沉积法制造的。在电解液中,通过电流的作用将铜沉积到基板上,形成铜箔。电解铜
- 嘉立创FPC PCB设计
设计资源 培训 开发板 精华推荐
- LT6654AHS6-4.096、16 位 ADC 电压基准的典型应用
- NCV8415SGEVB:具有浪涌电流管理演示板的自保护低侧驱动器
- AM3G-2415SZ 15V 3 瓦 DC/DC 转换器的典型应用
- STM32 EXtend
- ADR430B 2.048 Vout 超低噪声 XFET 电压基准的典型应用,具有灌电流和拉电流能力
- LTC1107CS8,升压稳压器 VPP 电源管理
- 使用 Microchip Technology 的 MIC2772-L2L3YML 的参考设计
- 10A60v恒流电子负载COPY
- 使用 ON Semiconductor 的 LM78M05 的参考设计
- 使用 Microchip Technology 的 MIC2807-OOYML 的参考设计