|
楼主 |
发表于 2008-11-17 17:03:15
|
显示全部楼层
>> 同步时钟与四大时钟域(CPU/HSB/PBB/PBA)
所谓同步时钟,就是芯片内部用于协调各个模块的工作的脉搏,通常说来就是系统时钟。一个系统
只有一个系统时钟,虽然四大时钟域可以有彼此不同的时钟(对UC3A和UC3B来说HSB永远和CPU工作在同
频率),但是他们只是系统时钟的不同分频而已——换句话说,四大时钟域拥有的只是对引入自己的系
统使用拥有独立自主的分频设置。
能够有资格做系统时钟的只有三种时钟源:系统内部自带的115KHz默认RC时钟,就是通常所谓的
Slow clock,当系统复位以后会自动默认连接这个时钟;Oscillator 0和PLL0。大家注意,PLL1和
Oscillator 1是没有资格充当系统时钟的。可以用“数字0的等级高于1,因此0比1更强悍”来记忆这个
特征。
<font color=red>[寄存器概述]
对系统时钟和四大时钟域的设定来说,主要有以下几个方面:
一、系统时钟的选择
二、时钟域连接到系统主时钟的分频设置
其中,系统时钟的选择是通过寄存器MCCTRL的MCSEL位来实现的,这是一个长度为2的二进制数,可
以表示3种有效的选择:
--------------------------------------------------
0: The slow clock is the source for the main clock
1: Oscillator 0 is source for the main clock
2: PLL0 is source for the main clock
--------------------------------------------------
四大时钟域的分频设置是通过寄存器CKSEL进行的。其中xxxDIV是分频开关,当为0时表示不分频;
xxxSEL是分频设置,这是一个3位的二进制数字,表示将进行2^(xxxSEL + 1)倍的分频。
需要强调的是,当xxxDIV为0时,一定要把xxxSEL也写为0。
[Software Framework 的使用]
当我们通过AVR32 Studio的Software Framework添加向导增加了Power Manager驱动模块以后,系统
会自动在DRIVERS模块下增加一个PM文件夹,其中包含了操作AVR32 UC3 PM模块的底层API,我们只需要
在工程中增加一个 #inludePM.h 语句,就可以获得以下函数的使用权限:
extern void pm_cksel
(
volatile avr32_pm_t *pm,
unsigned int pbadiv,
unsigned int pbasel,
unsigned int pbbdiv,
unsigned int pbbsel,
unsigned int hsbdiv,
unsigned int hsbsel
);
函数说明:该函数将分别指定四大时钟域在连接到系统主时钟时“是否分频”以及“选择多大的分频”
输入参数:&AVR32_PM
PBA分频开关 0表示不分频 1表示总线PBA将以pbasel指定的分频数连接到系统主时钟
PBA的分频
PBB的分频开关
PBB的分频
HSB的分频开关(UC3A/B永远和CPU域的时钟设置相同,所以这里实际上设置的是CPU的分频开关)
HSB的分频(UC3A/B永远和CPU域的时钟设置相同,所以这里实际上设置的是CPU的分频)
extern void pm_switch_to_clock(volatile avr32_pm_t *pm, unsigned long clock);
函数说明:该函数用于选择系统的主时钟
输入参数:&AVR32_PM
主时钟源,只能是以下的常数之一:
AVR32_PM_MCSEL_SLOW 芯片自带的默认115K RC振荡器
AVR32_PM_MCSEL_OSC0 选择Oscillator 0作为系统主时钟
AVR32_PM_MCSEL_PLL0 选择PLL0作为系统主时钟
extern void pm_switch_to_osc0(volatile avr32_pm_t *pm, unsigned int fosc0, unsigned int startup);
函数说明:直接将Oscillator 0作为系统主时钟(使用晶振而不是时钟),同时要指定所连接的外晶振的频率和启动时间。
输入参数:&AVR32_PM
所连接的晶振频率
该晶振的启动时间
extern int pm_configure_clocks(pm_freq_param_t *param);
函数说明:该函数会根据用户的需要自动的配置PM,以满足设定的CPU和PBA总线时钟
该函数会首先尝试连接PLL来实现所设定的CPU频率,如果失败了,系统会尝试直接连接Oscillator 0
PBA的频率会根据CPU的频率自动的进行优化,他总是等于CPU频率的/(2^x),所以PBA的最大频率总是
低于30MHz
HSB和PBB的频率总是和CPU相同,当自动配置完成以后,CPU、HSB和PBA的频率会被自动的反馈回来
输入参数:频率设置信息结构体指针 (pm_freq_param_t *) 相信情况请参考下面的结构体说明
输出参数:PM_FREQ_STATUS_OK 频率设置成功
PM_FREQ_STATUS_FAIL 频率设置失败
//! Input and output parameters when initializing PM clocks using pm_configure_clocks().
typedef struct
{
//! CPU frequency (input/output argument).
unsigned long cpu_f;
//! PBA frequency (input/output argument).
unsigned long pba_f;
//! Oscillator 0 frequency (board dependant) (input argument).
unsigned long osc0_f;
//! Oscillator 0 startup time: AVR32_PM_OSCCTRL0_STARTUP_x_RCOSC (input argument).
unsigned long osc0_startup;
} pm_freq_param_t;
[应用实例]
#include avr32/io.h
#include PM.h
int main(void)
{
volatile avr32_pm_t* pm = &AVR32_PM;
//使用外部的12M晶振
pm_enable_osc0_crystal(pm,12000000);
//使能Oscillator,并设置startup time为18ms
pm_enable_clk0(pm,3);
//使用PLL0连接Oscillator0产生一个60MHz的时钟,需要先产生一个大于80MHz的频率
pm_pll_setup
(
pm,
0, //PLL0
9, //*10
1, //不分频
0, //连接Oscillator0
16 //default
);
//设置PLL0的属性
pm_pll_set_option
(
pm,
0, //PLL0
0, //选择频率范围80-180MHz
1, //输出频率2分频,获得60M的实际输出
0 //default
);
//使能PLL0
pm_pll_enable(pm, 0);
//等待PLL0锁定
pm_wait_for_pll0_locked(pm);
//这一句不可省略,当CPU/HSB时钟超过系统最工作频率的一半,也就是33M时
flashc_set_wait_state(1);
//选择PLL作为系统主时钟
pm_switch_to_clock(pm,AVR32_PM_MCSEL_PLL0);
//分别设置四大时钟域的时钟
pm_cksel
(
pm,
1, //PBA开启分频
0, //2分频,也就是PBA工作在30M频率之下
0, //PBB不分频
0, //PBB工作在60M频率下
0, //HSB不分频
0 //CPU和HSB都工作在60M的频率下
);
return 0;
}
本贴被 Gorgon Meducer 编辑过,最后修改时间:2008-12-16,22:26:34. |
|