【裸机开发笔记】6410的系统时钟设置(下)---几个常用函数的C源码。
来源:互联网 发布:js base64转换为pdf 编辑:程序博客网 时间:2024/04/29 04:09
好了,贴源码!
//common.h
#ifndef COMMON_H#define COMMON_Htypedef unsigned long uint32;#define MASK_CODE(LSB_LOCATION,FIELD_LEN) ((((uint32)1<<FIELD_LEN)-1)<<LSB_LOCATION)#define FILL_BITS(MEM_ADDR,LSB_LOCATION,FIELD_LEN,VALUE)(*(volatile uint32 *)(MEM_ADDR)) = ( (*(volatile uint32 *)(MEM_ADDR)) & ~MASK_CODE((LSB_LOCATION),(FIELD_LEN)) ) | ( ((uint32)(VALUE)<<(LSB_LOCATION)) & MASK_CODE((LSB_LOCATION),(FIELD_LEN)) )//注:FILL_BITS(MEM_ADDR,LSB_LOCATION,FIELD_LEN,VALUE)这个宏,它执行的操作是,//用VALUE这个数填充MEM_ADDR地址处从第LSB_LOCATION位开始的FIELD_LEN个位.#define SET_REG(REG_ADDR,LSB_LOCATION,FIELD_LEN,VALUE) FILL_BITS(REG_ADDR,LSB_LOCATION,FIELD_LEN,VALUE)#endif
//clock.h
#ifndef CLOCK_H#define CLOCK_H#include"common.h"#define CONFIG_SYS_CLK_FREQ 12000000 void set_sys_clk(uint32 mode);uint32 get_ARMCLK(void);uint32 get_FCLK(void);//即APLLuint32 get_HCLK(void);uint32 get_PCLK(void);void change_freq(uint32 arm_ratio,uint32 hclkx2_ratio,uint32 hclk_ratio,uint32 pclk_ratio);//0-150-7 0-1 0-15//这四个参数加1后才是实际分频。#define rAPLL_LOCK (*(volatile uint32 *)(0x7e00f000))#define rMPLL_LOCK (*(volatile uint32 *)(0x7e00f004))#define rEPLL_LOCK (*(volatile uint32 *)(0x7e00f008))#define rAPLL_CON(*(volatile uint32 *)(0x7E00F00C))#define rMPLL_CON(*(volatile uint32 *)(0x7E00F010))#define rEPLL_CON0 (*(volatile uint32 *)(0x7E00F014))#define rEPLL_CON1 (*(volatile uint32 *)(0x7E00F018))#define rCLK_SRC(*(volatile uint32 *)(0x7E00F01C))#define rOTHERS (*(volatile uint32 *)(0x7E00F900))#define rMISC_CON(*(volatile uint32 *)(0x7E00F838))#define rCLK_DIV0(*(volatile uint32 *)(0x7E00F020))//--------#define _APLL_MDIV1000//reset: 0x190,10bits#define _APLL_PDIV10//reset: 0x3,6bits#define _APLL_SDIV1//reset: 0x2,3bits#define _MPLL_MDIV1000//reset: 0x214,10bits#define _MPLL_PDIV10//reset: 0x6,6bits#define _MPLL_SDIV1//reset: 0x3,3bits#define _ARM_RATIO2//0-15#define _HCLKX2_RATIO 3//0-7#define _HCLK_RATIO0//0-1#define _PCLK_RATIO3//0-15/*PLL_FOUT:FOUT = MDIV X FIN / (PDIV X 2^SDIV)MDIV: 64 ≤ MDIV ≤ 1023PDIV: 1 ≤ PDIV ≤ 63SDIV: 0 ≤ SDIV ≤ 5FVCO (=MDIV X FIN / PDIV): 800MHz ≤ FVCO ≤ 1600MHzFOUT: 40MHz ≤ FVCO ≤ 1600MHzFIN : 10MHz ≤ FIN ≤ 20MHzDon't set the value P and M to all zeros.CLK:ARM_CLK=APLLOUT / (_ARM_RATIO+1)HCLKX2=MPLLOUT / (_HCLKX2_RATIO+1)HCLK=HCLKX2 / (_HCLK_RATIO+1)PCLK=HCLKX2 / (_PCLK_RATIO+1)设置时还需注意HCLK必须是PCLK的整偶倍数*/#endif
需要修改频率时,只需修改clock.h文件中的下列宏的值即可:
//--------#define _APLL_MDIV1000//reset: 0x190,10bits#define _APLL_PDIV10//reset: 0x3,6bits#define _APLL_SDIV1//reset: 0x2,3bits#define _MPLL_MDIV1000//reset: 0x214,10bits#define _MPLL_PDIV10//reset: 0x6,6bits#define _MPLL_SDIV1//reset: 0x3,3bits#define _ARM_RATIO2//0-15#define _HCLKX2_RATIO 3//0-7#define _HCLK_RATIO0//0-1#define _PCLK_RATIO3//0-15
//clock.c
#include"clock.h" //注:FILL_BITS(MEM_ADDR,LSB_LOCATION,FIELD_LEN,VALUE)这个宏,它执行的操作是,//用VALUE这个数填充MEM_ADDR地址处从第LSB_LOCATION位开始的FIELD_LEN个位.void set_sys_clk(uint32 mode){//mode:0:asyn mode异步模式 //other:syn mode 同步模式 //两种模式的区别参考3-3页的Figure 3.2 uint32 *p; uint32 temp; rAPLL_LOCK = 0xffff; rMPLL_LOCK = 0xffff; rMISC_CON &= ~(1u<<19); //SYNC6670 : Normal Moe, 1 : Sync 667MHz Mode。这里选用Normal mode if(mode==0) { //设置同步模式为异步 rOTHERS &= ~0x80; //异步模式 while((rOTHERS & 0xf00) != 0); //等待OTHERS的8~11位为0 rOTHERS &= ~0x40;}else {//设置为同步模式。 rOTHERS |= 0x40; //同步模式 __asm{ nop; nop; nop; nop; nop; } rOTHERS |= 0x80; while((rOTHERS & 0xf00) != 0xf00); //等待OTHERS的8~11位为1111} //设置ARMCLK,HCLKX2,HCLK和PCLK temp=rCLK_DIV0; p=&temp;FILL_BITS(p,0,4,_ARM_RATIO);FILL_BITS(p,9,3,_HCLKX2_RATIO);FILL_BITS(p,8,1,_HCLK_RATIO);FILL_BITS(p,12,4,_PCLK_RATIO); rCLK_DIV0=temp; //设置APLL,得到APLLOUT temp=rAPLL_CON; p=&temp;FILL_BITS(p,16,10,_APLL_MDIV);FILL_BITS(p,8,6,_APLL_PDIV);FILL_BITS(p,0,3,_APLL_SDIV); temp |= (1u<<31); rAPLL_CON=temp; //设置MPLL,得到MPLLOUT temp=rMPLL_CON; p=&temp;FILL_BITS(p,16,10,_MPLL_MDIV);FILL_BITS(p,8,6,_MPLL_PDIV);FILL_BITS(p,0,3,_MPLL_SDIV);temp |= (1u<<31); rMPLL_CON=temp;//选择源 temp=rCLK_SRC; p=&temp;FILL_BITS(p,0,1,1);//选择APLLOUTFILL_BITS(p,1,1,1);//选择MPLLOUT rCLK_SRC=temp; }void change_freq(uint32 arm_ratio,uint32 hclkx2_ratio,uint32 hclk_ratio,uint32 pclk_ratio){//0-150-70-10-15 uint32 *p; uint32 temp; temp=rCLK_DIV0; p=&temp;FILL_BITS(p,0,4,arm_ratio);FILL_BITS(p,9,3,hclkx2_ratio);FILL_BITS(p,8,1,hclk_ratio);FILL_BITS(p,12,4,pclk_ratio); rCLK_DIV0=temp;}#define APLL 1#define MPLL 2#define EPLL 3static uint32 get_PLLCLK(int pllreg)//返回0说明异常{uint32 r, m, p, s;if (pllreg == APLL)r = rAPLL_CON;else if (pllreg == MPLL)r = rMPLL_CON;else if (pllreg == EPLL)r = rEPLL_CON0;elsereturn 0;m = (r>>16) & 0x3ff;p = (r>>8) & 0x3f;s = r & 0x7;return (m * (CONFIG_SYS_CLK_FREQ / (p * (1 << s))));}/* return ARMCORE frequency */uint32 get_ARMCLK(void){uint32 div;div = rCLK_DIV0;return (get_PLLCLK(APLL) / ((div & 0x7) + 1));}/* return FCLK frequency */uint32 get_FCLK(void){return (get_PLLCLK(APLL));}/* return HCLK frequency */uint32 get_HCLK(void){uint32 fclk;uint32 hclkx2_div = ((rCLK_DIV0>>9) & 0x7) + 1;uint32 hclk_div = ((rCLK_DIV0>>8) & 0x1) + 1;if(rOTHERS & 0x80)fclk = get_FCLK();// SYNC Modeelsefclk = get_PLLCLK(MPLL);// ASYNC Modereturn fclk/(hclk_div * hclkx2_div);}/* return PCLK frequency */uint32 get_PCLK(void){uint32 fclk;uint32 hclkx2_div = ((rCLK_DIV0>>9) & 0x7) + 1;uint32 pre_div = ((rCLK_DIV0>>12) & 0xf) + 1;if(rOTHERS & 0x80)fclk = get_FCLK();// SYNC Modeelsefclk = get_PLLCLK(MPLL);// ASYNC Modereturn fclk/(hclkx2_div * pre_div);}
set_sys_clk(uint32 mode)函数既设置锁相环又根据已定义好的宏设置ARMCLK和HCLK等的分频。mode为0时为异步模式,为1时为同步模式。初始化时一般用这个函数。
change_freq(uint32,uint32,uint32,uint32)根据输入的参数设置ARMCLK和HCLK等的分频,但不改变PLL的设置。通过这个函数可以快捷的实现动态变频。
其他的get*****()函数就请读者自己看吧。
- 【裸机开发笔记】6410的系统时钟设置(下)---几个常用函数的C源码。
- 【裸机开发笔记】6410的系统时钟设置(下)---几个常用函数的C源码。
- 6410的系统时钟设置(下)---几个常用函数的C源码
- 【裸机开发笔记】6410的系统时钟设置(上)---6410时钟控制逻辑框架分析
- 【裸机开发笔记】6410的系统时钟设置(上)---6410时钟控制逻辑框架分
- 【裸机开发笔记】6410的系统时钟设置(中)---相关寄存器介绍
- 【裸机开发笔记】6410的系统时钟设置(中)---相关寄存器介绍
- 三、s3c2440 裸机 系统时钟和定时器的设置
- linux 系统下使用C程序实现时钟的函数
- STM32在系统时钟为72M下的几个延时函数—V3.5库
- c语言之开发中常用的几个函数(一)
- 【驱动开发】Windows系统下枚举设备的几个函数
- android源码开发常用的几个命令
- Tiny6410学习ing—(三)、ARM裸机开发—(4)、系统时钟(汇编语言程序设置)—①
- 1.6.ARM裸机第六部分-S5PV210的时钟系统
- php系统常用的几个函数
- 八.ARM裸机学习之S5PV210的时钟系统2(汇编代码及时钟框图深入理解)
- 八.ARM裸机学习之S5PV210的时钟系统1(原理概念及框图分析)
- 菲波拉契数列的递归与非递归算法
- arecord 使用
- 封装一类Java对象,用户从输入对话框输入两个日期,程序将判断两个日期的天数差
- 通过mk文件编译android4.0.3系统app源码后覆盖安装失败解决办法(android odex文件)
- fckeditor配置方法
- 【裸机开发笔记】6410的系统时钟设置(下)---几个常用函数的C源码。
- 有关T-SQL的10个好习惯
- CAD 批量打印,输出pdf,plt的工具
- Oscache与memcached区别
- N个数的全排列
- 求链表的节点个数 链表可能有环
- 浅谈无缓存I/O操作和标准I/O文件操作区别
- Corba-omniORB编程了解
- TSP问题之动态规划解法