单片机总线中的周期概念及其时钟时间估算及编程应用示例

控制/MCU

1815人已加入

描述

最近一直在想怎么测单片机的总线时钟,于是想出了一个方法,也不知是否正确,权且估算一下吧。

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

时钟周期: 时钟周期也称为振荡周期,定义为时钟脉冲的倒数(可以这样来理解,时钟周期就是单片机外接晶振的倒数,例如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

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分