您的位置:首页 > 其它

单片机总线时钟粗略计算

2017-11-14 17:09 393 查看
最近一直在想怎么测单片机的总线时钟,于是想出了一个方法,也不知是否正确,权且估算一下吧。

先说明一下时钟周期,机器周期,总线周期的区别吧:

时钟周期: 时钟周期也称为振荡周期,定义为时钟脉冲的倒数(可以这样来理解,时钟周期就是单片机外接晶振的倒数,例如12M的晶振,它的时间周期就是1/12 us),是计算机中最基本的、最小的时间单位。

机器周期:    在计算机中,为了便于管理,常把一条指令的执行过程划分为若干个阶段,每一阶段完成一项工作。例如,取指令、存储器读、存储器写等,这每一项工作称为一个基本操作。完成一个基本操作所需要的时间称为机器周期。一般情况下,一个机器周期由若干个S周期(状态周期)组成。   
8051系列单片机的一个机器周期同6个 S周期(状态周期)组成。前面已说过一个时钟周期定义为一个节拍(用P表示),二个节拍定义为一个状态周期(用S表示),8051单片机的机器周期由6个 状态周期组成,也就是说一个机器周期=6个状态周期=12个时钟周期。 (例如外接24M晶振的单片机,他的一个机器周期=12/24M 秒)

指令周期:    执行一条指令所需要的时间,一般由若干个机器周期组成。指令不同,所需的机器周期也不同。       对于一些简单的的单字节指令,在取指令周期中,指令取出到指令寄存器后,立即译码执行,不再需要其它的机器周期。对于一些比较复杂的指令,例如转移指令、乘法指令,则需要两个或者两个以上的机器周期。    通常含一个机器周期的指令称为单周期指令,包含两个机器周期的指令称为双周期指令。

总线周期: 由于存贮器和I/O端口是挂接在总线上的,CPU对存贮器和I/O接口的访问,是通过总线实现的。通常把CPU通过总线对微处理器外部(存贮器或 I/O接口)进行一次访问所需时间称为一个总线周期。
总结:时钟周期是最小单位,机器周期需要1个或多个时钟周期,指令周期需要1个或多个机器周期;机器周期指的是完成一个基本操作的时间,这个基本操作有时可能包含总线读写,因而包含总线周期,但是有时可能与总线读写无关,所以,并无明确的相互包含的关系。指令周期:是CPU的关键指标,指取出并执行一条指令的时间。一般以机器周期为单位,分单指令执行周期、双指令执行周期等。现在的处理器的大部分指令(ARM、DSP)均采用单指令执行周期。机器周期:完成一个基本操作的时间单元,如取指周期、取数周期。时钟周期:CPU的晶振的工作频率的倒数。

一个nop所占的时间为一个机器指令的时间,8051中为1us。

单片机型号为飞思卡尔MC9s12xep100,在main函数里放置时钟初始化函数,同时初始化一个引脚,并设置为输出,然后主函数放置该引脚电平的翻转函数。大致如下;

void main()
{
MCUInit();
DDRP_DDRP4=1;//PTP4设置为输出
while(1)
{
PTP_PTP4=~PTP_PTP4;
}
}
然后用示波器测量该引脚翻转电平所用的时间,以下是部分数据:(示波器精度有限)

总线频率—>耗时    ≈ (1/总线频率)*10

16MHZ  —>620ns ≈ 625ns

20MHZ  —>500ns ≈ 500ns

32MHZ  —>312ns ≈ 312ns

40MHZ  —>252ns ≈ 250ns

48MHZ  —>208ns ≈ 208ns

60MHZ  —>168ns ≈ 166ns

通过上面的数据,发现耗时与 (1/总线频率)*10基本相等,至于为何乘10,不知何因。权且当做粗略估算吧。

----------------------------------------------------------------单片机9s08dz60------------------------------------------------------------------------------

顺便记录下对dz60的测试

总线频率—>翻转电平耗时    ≈ (1/总线频率)*10   asm("nop")耗时

16MHZ  —>680ns               ≈ 625ns                 370ns

8MHZ  —>1.36us               ≈ 1.25us                 740ns

4MHZ  —>2.76us               ≈ 2.50us                 1.5us

其中asm("nop")耗时的计算方法如下:

void main()
{
MCUInit();
DDRP_DDRP4=1;//PTP4设置为输出
while(1)
{
PTP_PTP4=1;
asm("nop");
PTP_PTP4=0;
}
}
下面附dz60时钟初始化函数(晶振8MHZ,总线8MHZ)

void MCUInit(void)
{
SOPT1 = 0x20;						//取消看门狗,使能停止模式
SOPT2 = 0X00;						//写入一次SOPT2
/* 初始化时钟,使用PEE模式,晶振为8Mhz,总线频率为8mhz(datasheet P151) */
/*----------------------------FEI -> FBE----------------------------------*/
MCGC2 = 0x36;						//总线分频为1.P133.
while (!MCGSC_OSCINIT);				//EREFS位选择的晶体是否完成初始化.P134.
MCGC1 = 0xB8;						//选择使用外部晶振.P131.
while (MCGSC_IREFST);       		//等待外部参考成为参考时钟的当前源
while(MCGSC_CLKST != 2);			//等待外部参考 时钟成为 MCGOUT

/*----------------------------FBE -> BLPE---------------------------------*/
MCGC2 = 0x3E;						//设置LP位为1(此时已经进入BLPE模式)
MCGC1 = 0x98;//0x98->RDIV=8;0x90->RDIV=4;		//更改RDIV
MCGC3 = 0x44;//0x44->VDIV=16;0x48->VDIV=32		//选择PLL,VDIV为4
while(!MCGSC_PLLST);				//PLLS时钟的当前源是否PLL

/*----------------------------BLPE -> PBE---------------------------------*/
MCGC2 = 0x36;						//设置LP位为0(此时已经进入BLPE模式)
while (!MCGSC_LOCK);				//等待PLL获得锁定

/*----------------------------PBE -> PEE----------------------------------*/
MCGC1 = 0x18;						//选择PLL为系统时钟
while(MCGSC_CLKST != 3);			//等待时钟稳定
}
MCGOUT=(8MHZ/8)*16/1=16MHZ,总线时钟为8MHZ
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: