当前位置: 首页 > news >正文

JZ2440开发板——S3C2440的时钟体系

参考博客

(1)S3C2440-裸机篇-05 | S3C2440时钟体系详解(FCLK、PCLK、HCLK) 

 

一、三种时钟(FCLK、HCLK、PCLK)

如下图所示,S3C2440的时钟控制逻辑,给整个芯片提供三种时钟:

(1)FCLK:用于CPU核;

(2)HCLK:用于接在AHB总线上的设备,比如LCD控制器、存储器控制器、中断控制器、USB主机模块等;

(3)PCLK:用于接在APB总线上的设备,比如看门狗、IIS、I2C、ADC、UART等。

另外由数据手册可知(如下图所示),CPU最大的工作频率可达400MHz,高速设备最大的工作频率可达136MHz,低速设备最大的工作频率是68MHz。 

二、如何产生三种时钟 

由底板原理图可知(如下图所示),时钟源是12MHz的晶振。

如何由12MHz提高到400MHz?这需要使用到 PLL(锁相环)。

我们来看一下时钟产生框图:

由图可知有两个时钟源:一个是晶振提供时钟源,另一个是通过外部引脚提供时钟源。具体选择哪个时钟源,由选择器的OM[3:2]来决定,如下图所示:

由于 OM[3:2] 引脚接地,所以其值为00,则选择晶振作为时钟源,如下所示:

由图可知,S3C2440有两个PLL,分别叫做MPLL(main PLL)、UPLL(usb PLL)。UPLL专用于USB设备,MPLL用于设置FCLK、HCLK、PCLK。它们的设置方法类似,这里以MPLL为例。

上电时,MPLL没被启动,FCLK等于外部输入的时钟(一般是晶振产生的12Mhz时钟),我们称之为Fin。如果要提高系统的时钟,需要使用软件来启用MPLL。其上电时序图如下所示:

(1)LOCKTIME 寄存器:用于设置锁相时间

Fin进入MPLL后,需要经过一定的时长(时长可以通过 LOCKTIME 寄存器进行设置,我们一般使用默认值0xFFFF-FFFF就好),MPLL才能输出倍频后的 FCLK。

(2)MPLLCON 寄存器:用于设置FCLK与Fin的倍数关系

已知给 MPLL 输入的 Fin=12MHz,如果想让MPLL输出的 FCLK = 400MHz(因为CPU最大的工作频率可达400MHz),该如何设置呢?可以通过 MPLLCON 寄存器进行设置。

有如下公式:

从MPLL输出的FCLK = (2*m*Fin)/(p*2^s)m = MDIV(即 MPLLCON[19:12] 的值 )+ 8p = PDIV(即 MPLLCON[9:4] 的值 )+ 2s = SDIV(即 MPLLCON[1:0] 的值 )

数据手册会给出FCLK典型值的设置推荐值,如下图所示,我们编程时使用这些推荐值即可(虽然也可以由公式自己推算)。

(3)CLKDIVN寄存器:用于设置FCLK、HCLK、PCLK的比例

上面已经得到FCLK,那如何由它进一步得到HCLK、PCLK呢?可以将FCLK进行分频,得到HCLK、PCLK,这意味着FCLK、HCLK、PCLK三者存在比例关系。具体的分频系数,可以通过CLKDIVN寄存器进行设置,比如通过 CLKDIVN[2:1] 设置将FCLK分频多少以得到HCLK。

过程总结如下图所示:

三、编程实践

3.1 编程前的分析 

在编程之前,注意数据手册有下面的一段描述:

它表明,如果HDIVN的值不设为0(为0则表示HCLK=FCLK/1,而HCLK一般不等于FCLK,所以一般不会设置为0的),则需要添加上图红框内的代码(注意将“R1_nF…”这个宏转换为实际值)。

假设我们需要设置FCLK=400MHz,HCLK=100MHz,PCLK=50MHz。

则根据第二节的描述,我们需要设置MPLLCON寄存器、CLKDIVN寄存器:

(1)关于MPLLCON寄存器的设置。由于400MHz是典型值, 我们使用数据手册给出的设置:

MDIV(即 MPLLCON[19:12] 的值 ):设置为92(0x5c)

PDIV(即 MPLLCON[9:4] 的值 ):设置为1

SDIV(即 MPLLCON[1:0] 的值 ):设置为1

那么MPLLCON寄存器的值应该设置为:(92<<12)|(1<<4)|(1<<0)

(2)关于CLKDIVN寄存器的设置。

由于 HCLK(100MHz) = FCLK(400MHz) / 4,所以CLKDIVN[2:1] = 0b10;而且CAMDIVN[9]要设置为0(初始值默认也为0,那么设不设置好像都行)。

由于 PCLK(50MHz) = HCLK(100MHz) / 2,所以CLKDIVN[0] = 1;

综合起来,CLKDIVN寄存器要设置为0b101=0x5。

 

3.2 编程实践

完整的代码见链接(课程提供的代码):

(1)其中start.S文件内容如下(我仿写的):

.text
.global _start_start://关看门狗ldr r0,=0x53000000ldr r1,=0str r1,[r0]/*******************************************/	//设置HDIV、PDIV的分频系数,使得FCLK : HCLK : PCLK=400:100:50//通过寄存器CLKDIVN来设置分频系数ldr r0,=0x4c000014ldr r1,=0x5str r1,[r0]//设置CPU工作于异步模式mrc p15,0,r0,c1,c0,0orr r0,r0,#0xc0000000 //R1_nF:OR:R1_iA的值为0xc0000000mcr p15,0,r0,c1,c0,0//设置MPLL的锁相时间/* LOCKTIME(0x4C000000) = 0xFFFFFFFF */ldr r0, =0x4C000000ldr r1, =0xFFFFFFFFstr r1, [r0]//设置MPLL,使它输出400MHzldr r0,=0x4c000004ldr r1,=(92<<12)|(1<<4)|(1<<0)str r1,[r0]
/******************************************************///设置栈/*判断nor/nand启动方式,并设置相应的栈*如何判断启动方式:写0到0地址,然后再读出来,*如果得到0,则表示地址0的内容被修改了,它对应着sram,意味着nand启动*否则为nor启动(因为nor不能直接写)*///ldr r0,[0]  //读出原来的值进行备份mov r1,#0ldr r0,[r1]str r1,[r1] //将0写到0地址ldr r2,[r1] //将0地址的内容读出来cmp r1,r2   // r1==r2? 如果相等则表示是nand启动ldr sp,=0x4000000+0x1000 //先假设是nor启动(nor启动时,内部的SRAM映射到0x40000000,4096=0x1000)moveq sp,#4096 //如果相等则表示nand启动,将sp指向内部SRAM的最高地址处streq r0,[r1]  //如果相等则表示nand启动,恢复原来的值bl mainhalt:b halt

(2)led.c文件的内容如下(我仿写的):

#include "s3c2440_soc.h"void delay(volatile int d)
{while (d--);
}int main(void)
{//设置GPFCON让GPF4/5/6配置为输出引脚GPFCON &= ~((3<<8)|(3<<10)|(3<<12));//先清零GPFCON |= ((1<<8)|(1<<10)|(1<<12));//置位,设置为输出引脚GPFDAT=0xff;//全部熄灭//循环点亮while(1){GPFDAT=0xff;//全部熄灭GPFDAT=0xef;//让LED1亮delay(100000);GPFDAT=0xff;//让LED1灭GPFDAT=0xdf;//让LED2亮delay(100000);GPFDAT=0xff;//让LED2灭GPFDAT=0xbf;//让LED4亮delay(100000);}return 0;
}//课程的版本
#if 0int main(void)
{int val = 0;  /* val: 0b000, 0b111 */int tmp;/* 设置GPFCON让GPF4/5/6配置为输出引脚 */GPFCON &= ~((3<<8) | (3<<10) | (3<<12));GPFCON |=  ((1<<8) | (1<<10) | (1<<12));/* 循环点亮 */while (1){tmp = ~val;tmp &= 7;GPFDAT &= ~(7<<4);GPFDAT |= (tmp<<4);delay(100000);val++;if (val == 8)val =0;}return 0;
}#endif

 代码依据是数据手册与原理图中的相关内容,如下所示:

由下面的原理图可知,GPF4~GPF6引脚输出低电平时,对应的LED1、LED2、LED4会亮。

 

3.3 现象与分析

1、在课程提供的代码(见上面提到的链接)目录下执行make时,在进行链接时报错:

xjh@ubuntu:~/iot/embedded_basic/jz2440/armBareMachine/clk$ make
arm-linux-gcc -c -o led.o led.c
arm-linux-gcc -c -o start.o start.S
arm-linux-ld -Ttext 0 led.o start.o -o led.elf
led.o:(.ARM.exidx+0x0): undefined reference to `__aeabi_unwind_cpp_pr0'
led.o:(.ARM.exidx+0x8): undefined reference to `__aeabi_unwind_cpp_pr1'
make: *** [all] Error 1
xjh@ubuntu:~/iot/embedded_basic/jz2440/armBareMachine/clk$

解决方法是在 arm-linux-gcc 命令加上 -nostdlib 这个选项。它表示不链接系统标准启动文件和标准库文件,只把指定的文件传递给连接器。这个选项常用于编译内核、bootloader等程序,它们不需要启动文件、标准库文件(书P35)。

回顾一下朱的裸机课程,如果 arm-linux-ld 时只有一个待连接的.o文件,Makefile中的arm-linux-gcc命令不需要加上 -nostdlib 这个选项(比如chapter4->8.leds.s),如果有两个待链接的.o文件,则需要加上该选项(比如chapter5->3.set_sp_s及以后的裸机程序)。

这里韦的课程为何不加呢?估计与我环境不一样?

2、一些编程注意事项

(1) &=,这两个符号不能有空格,即不能写成“& =”

GPFCON & = ~((3<<8)|(3<<10)|(3<<12)); //会报错

 (2)Makefile文件中arm-linux-ld时,.o文件第一个必须是start.o文件!否则可以连接成功,但烧写到开发板后没有现象。

(3)直接写成 ldr r0,[0] 貌似会报错,要写成:

mov r1,#0
ldr r0,[r1]

(4)课程的led.c文件用的是位操作,我没有仔细分析其代码,而是直接赋值修改。有时间分析一下其代码。

3、烧写现象

以NorFlash启动,在uboot的shell界面下按“n”,使用“usb下载线+dnw”方式将生成的led.bin烧写到NandFlash中。然后改为NandFlash启动,可以看见三颗LED灯在快速地循环点亮。

 如果将start.S文件中两条“/**************/”之间的内容(也就是时钟初始化部分)删掉,重新编译烧写运行,可以看见三颗LED灯依然在循环点亮,但速度明显慢许多!(此时FCLK应该是12MHz,而HCLK与PCLK又是多少呢?)

四、总结

1、深入讲解了S3C2440芯片的结构

掌握了S3C2440的时钟体系架构和上电复位时序,其时钟源有两个:外部晶振或者外部时钟,通过OM[3:2]硬件选择;其内部主要调整频率的PLL有两个:MPLL(产生FCLK)和UPLL(产生UCLK);其主要的时钟频率有三个(FCLK->CPU使用,HCLK->AHB总线高速外设使用,PCLK->APB总线低速外设使用),其中HCLK和PCLK由FCLK分频而来。

2、学习了如何进行芯片操作

掌握了如何编程设置寄存器控制S3C2440的时钟频率,比如本节设置FCLK=400Mhz,HCLK=100Mhz,PCLK=50Mhz。

3、其他一些启发

可以关闭某些模块的时钟,以达到省电的目的。 比如设置CLKCON寄存器来关闭某些模块。

相关文章:

JZ2440开发板——S3C2440的时钟体系

参考博客 &#xff08;1&#xff09;S3C2440-裸机篇-05 | S3C2440时钟体系详解&#xff08;FCLK、PCLK、HCLK&#xff09; 一、三种时钟&#xff08;FCLK、HCLK、PCLK&#xff09; 如下图所示&#xff0c;S3C2440的时钟控制逻辑&#xff0c;给整个芯片提供三种时钟&#xff1…...

[数据集][目标检测]男女性别检测数据集VOC+YOLO格式9769张2类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;9769 标注数量(xml文件个数)&#xff1a;9769 标注数量(txt文件个数)&#xff1a;9769 标注…...

static 初始化报错

在 C 或 C 中&#xff0c;当你在函数中使用 static 关键字初始化一个局部变量时&#xff0c;编译器要求初始化器&#xff08;initializer&#xff09;是编译时常量。如果你尝试用动态计算的值初始化 static 变量&#xff08;如函数参数或运行时生成的值&#xff09;&#xff0c…...

3D Gaussian Splatting 论文学习

概述 目前比较常见的渲染方法大致可以分为2种&#xff1a; 将场景中的物体投影到渲染平面&#xff1a;传统的渲染管线就是这种方式&#xff0c;主要针对Mesh数据&#xff0c;可以将顶点直接投影成2D的形式&#xff0c;配合光栅化、深度测试、Alpha混合等就可以得到渲染的图像…...

MySQL 安全机制全面解析

‍ 在如今的数字化时代&#xff0c;数据库安全 变得越来越重要。为了防止对数据库进行非法操作&#xff0c;MySQL 定义了一套完整的安全机制&#xff0c;包括用户管理、权限管理 和 角色管理。本文将为你深入浅出地介绍这三大安全机制&#xff0c;帮助你轻松掌握MySQL的安全管…...

vue原理分析(十四)研究new Vue()中的 initProvide

在Vue.prototype._init 中有一些init函数&#xff0c;今天我们来研究这些init函数 Vue.prototype._init function (options) {......{initProxy(vm);}......initLifecycle(vm);initEvents(vm);initRender(vm);callHook$1(vm, beforeCreate, undefined, false /* setContext *…...

Qt控制开发板的LED

Qt控制开发板的LED 使用开发板的IO接口进行控制是嵌入式中非常重要的一点&#xff0c;就像冯诺依曼原理说的一样&#xff0c;一个计算机最起码要有输入输出吧&#xff0c;我们有了信息的接收和处理&#xff0c;那我们就要有输出。 我们在开发板上一般都是使用开发板的GPIO接口…...

S3C2440开发板点亮LED灯+PWM定时器

目录 GPIO引脚和寄存器概述 点亮LED灯步骤 1.配置GPIO 2.点亮LED 设置引脚为输出 控制引脚电平 完整代码 PWM GPIO引脚和寄存器概述 GPIO端口&#xff1a; S3C2440的GPIO引脚可被配置为输入或输出&#xff08;控制LED的引脚通常配置为输出模式&#xff09;。寄存器&#…...

S-Procedure的基本形式及使用

理论 Lemma 1. ( S- Procedure[ 34] ) : Define the quadratic func- \textbf{Lemma 1. ( S- Procedure[ 34] ) : Define the quadratic func- } Lemma 1. ( S- Procedure[ 34] ) : Define the quadratic func- tions w.r.t. x ∈ C M 1 \mathbf{x}\in\mathbb{C}^M\times1 x…...

free -h 查看内存free空间不足

free空间不足 大部分被buff/cache占用 解决办法一: 手动释放缓存 释放页缓存 sudo sync; sudo sysctl -w vm.drop_caches1 释放目录项和inode缓存 sudo sync; sudo sysctl -w vm.drop_caches2 释放所有缓存&#xff08;页缓存、目录项和inode缓存&#xff09; sudo sync…...

rust学习笔记

参考资料&#xff1a;https://doc.rust-lang.org/book/ch01-02-hello-world.html 一、 编译与运行 在 Rust 中&#xff0c;编译和运行代码的常用命令是使用 cargo&#xff0c;这是 Rust 的包管理和构建工具。以下是使用 cargo 和 rustc&#xff08;Rust 编译器&#xff09;的具…...

【有啥问啥】复习变分下界即证据下界(Evidence Lower Bound, ELBO):原理与应用

复习变分下界即证据下界&#xff08;Evidence Lower Bound, ELBO&#xff09;&#xff1a;原理与应用 变分下界&#xff08;Variational Lower Bound&#xff09;&#xff0c;也称为“证据下界”&#xff08;Evidence Lower Bound, ELBO&#xff09;&#xff0c;是概率模型中的…...

Linux shell编程学习笔记78:cpio命令——文件和目录归档工具(上)

0 前言 在Linux系统中&#xff0c;除了tar命令&#xff0c;我们还可以使用cpio命令来进行文件和目录的归档。 1 cpio命令的功能&#xff0c;帮助信息&#xff0c;格式&#xff0c;选项和参数说明 1.1 cpio命令的功能 cpio 名字来自 "copy in, copy out"&#xf…...

为什么在 JSON 序列化中不使用 transient

有些小伙伴发现了&#xff0c;明明在返回的实体类中指定了属性为transient。为什么前端得到的返回json中还是有这个属性的值&#xff1f; 类&#xff1a; private String name; private transient String password;返回结果&#xff1a; { name:"刘大大", password:…...

K8S - Volume - NFS 卷的简介和使用

在之前的文章里已经介绍了 K8S 中两个简单卷类型 hostpath 和 emptydir k8s - Volume 简介和HostPath的使用 K8S - Emptydir - 取代ELK 使用fluentd 构建logging saidcar 但是这两种卷都有同1个限制&#xff0c; 就是依赖于 k8s nodes的空间 如果某个service pod中需要的vol…...

IO模型---BIO、NIO、IO多路复用、AIO详解

本篇将想给详细解释一下什么是BIO、NIO、IO多路复用以及AIO~ 同步的阻塞(BIO)和非阻塞(NIO)的区别 BIO&#xff1a;线程发来IO请求后&#xff0c;一直阻塞着IO线程&#xff0c;需要缓冲区这边数据准备好之后&#xff0c;才会进行下一步的操作。 举个&#x1f330;&#xff1…...

蓝桥杯真题——约翰的牛奶

输入样例&#xff1a; 8 9 10 输出样例&#xff1a; 1 2 8 9 10 本题是宽搜的模版题&#xff0c;不论怎么倒牛奶&#xff0c;A,B,C 桶里的牛奶可以看做一个三元点集 我们只要找到A桶是空的&#xff0c;B,C桶中的状态即可 #include <iostream> #include <cstring…...

单机docker-compose部署minio

单机多副本docker-compose部署minio 简单介绍 如果服务器有限可以单机挂载多硬盘实现多副本容错&#xff08;生产不推荐&#xff09; 部署好的文件状态 有两个重要文件 docker-compose.yaml和nginx.conf docker-compose.yaml是docker部署容器的配置信息包括4个minio和1个ng…...

Winform实现弹出定时框功能

1、程序 private void TimeDialogInitialize(){for(int i1; i<30;i){cbbTimeDialog.Items.Add(i);}}private void cbbTimeDialog_SelectedIndexChanged(object sender, EventArgs e){foreach(int i in cbbTimeDialog.Items){if(cbbTimeDialog.SelectedItem!null &&…...

【机器学习(四)】分类和回归任务-梯度提升决策树(GBDT)-Sentosa_DSML社区版

文章目录 一、算法概念一、算法原理&#xff08;一&#xff09; GBDT 及负梯度拟合原理&#xff08;二&#xff09; GBDT 回归和分类1、GBDT回归1、GBDT分类二元分类多元分类 &#xff08;三&#xff09;损失函数1、回归问题的损失函数2. 分类问题的损失函数&#xff1a; 三、G…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

3.3.1_1 检错编码(奇偶校验码)

从这节课开始&#xff0c;我们会探讨数据链路层的差错控制功能&#xff0c;差错控制功能的主要目标是要发现并且解决一个帧内部的位错误&#xff0c;我们需要使用特殊的编码技术去发现帧内部的位错误&#xff0c;当我们发现位错误之后&#xff0c;通常来说有两种解决方案。第一…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

Pinocchio 库详解及其在足式机器人上的应用

Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库&#xff0c;专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性&#xff0c;并提供了一个通用的框架&…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...