第二课 MC9S08DZ60之多功能时钟发生器S08MCGV1

发布者:智慧启迪最新更新时间:2021-04-07 来源: eefocus关键字:MC9S08DZ60 手机看文章 扫描二维码
随时随地手机看文章

1.MC9S08DZ60系统时钟分配(System Clock Distribution)


在使用多用能时钟发生器(MCG)之前,先来了解下这款单片机的系统时钟。


单片机的各个功能器件对命令的执行都是一步一步的进行的,每个步骤的执行都需要一个激励,这个激励就是时钟,在一定的时钟内完成给定的指令,这既是MCU工作的基本原理。可以打个不恰当的比方,MCU的时钟就如人的心脏,心脏的每一跳动,都在给全身各个功能器官输送血液养分和能量。MCU的时钟也是如此,每一个时钟跳动(震荡周期)片上资源(如ALG、SPI、IIC等)都会得到一个指令去执行。也即心脏如时钟发生器,人体器官如MCU上的片上资源,血液养分和能量就如单片机的指令和数据。


大家可以到我的百度盘下载该芯片的中英文的资料https://pan.baidu.com/s/1dgVbkE https://pan.baidu.com/s/1o9qFU5c,进入1.3 System Clock Distribution章节,建议读者先阅读一遍该章节,可以说确实不难,很快就可以知道这个芯片的时钟从产生到送到各个片上资源的路径,以及有几种时钟可以选择。这里我把芯片资料中的系统时钟图Figure 1-2. MC9S08DZ60 System Clock Distribution Diagram 粘贴上来做一个简单的说明,重点是如何为这款单片机配置系统时钟,那就是写代码!其他的多看看。

A.首先从图Figure 1-2 中要能知道这款单片机的片上资源有哪些,它们分别是RTC、COP、TPM1、TPM2、IIC、SCI1、SCI2、SPI、CPU、BDC、ADC、MSCAN、FLASH、EEPROM、LPO、MCG、XOSC。


B.这么多的片上资源咱们如果是一头蒙,不知道他们是干什么的话,那就不要管它们是什么。这课主题是MCG,也就是比拟的心脏,其他的,如CPU就理解为人的大脑,MSCAN就理解为人的嘴巴用来沟通的,FLASH/EEPROM就理解为人的记忆器官, 反正总之这些片上资源它们是能各自完成各自的功能的,如果读者是位初学者且之前没有接触过单片机,那么也没关系,这些器件都会慢慢讲解。


C.看图的左边,MCG这个心脏为MCU片上资源提供了MCGERCLK、MCGIRCLK、MCGFFCLK、MCGOUT、MCGLCLK,并且知道MCG还控制一个(XOSC)外部振荡器以便把晶体或共鸣器用作外部参考时钟。除了MCG外这款单片机内部还有一个LPO 1KHZ的频率发生器只用来给RTC、COP这两个器件工作用。


D.另外右下角有一段英文:The fixed frequency clock(FFCLK) is internally synchronized to the bus clock and must not exceed one half of the bus clock frequency 就是FFCLK这个时钟频率不要大于总线的2倍就可以,其实也不用担心,因为从时钟系统图,看到硬件已经做了÷2的设定.


2.接下来就是看芯片资料的Chapter8 Multi-Purpose Clock Generator(S08MCGV1)来了解这个MCG和怎样去用这个MCG来真正是的单片机工作起来。


很显然,如果读者是第一次接触单片机,你肯定很头痛看这个芯片资料,或许看完之后也不知道怎么去操作这个MCG。即使真是这样,也没关系。不过建议多看看芯片资料,真的会有进步,个人经验,多看几遍就懂了。因为这里面涉及到很多理论概念加之读者的学识以及时间的限制,不啰嗦介绍这个MCG,读者自己看看咯。


3.现在来驱动这个MCG,让它工作起来。


看芯片资料的‘8.3 Register Definition',一共看到5个寄存器(register),分别是MCGC1、MCGC2、MCGTRM、MCGSC、MCGC3。这里给这些寄存器分类为:MCGC1、MCGC2、MCGC3为控制类,MCGTRM为功能类、MCGSC为状态类。好那就建立三个函数,分别来操作这个三类寄存器吧。这三个函数名就分别取MCG_Control,MCG_Function和MCG_Status。


另外看到每个寄存器中有多个设置项,看下图

每个设置项又有多个选择项,看下图

作者在这里采用没个设置项“位与”“异或非”:的方式来最终组成8字节的寄存器内容和判断寄存器中的值,也就是需要为每一个设置项定义多个define宏,如:#define CLKS_FLL_PLL 00 ;其实code warrior 工程文件加入芯片头文件后 有类似的定义,也无需自己定义的,但是为了自己使用,还是自己写了,俗话说看十遍,不如写一遍--不要笑话哈。


另外还要理解芯片资料的介绍的“8.4.1 Operational Mode”。其中FEI(FLL Engaged Internal)是复位芯片的默认模式,如果要用其他模式,比如FBE(FLL Bypassed External),直接设置到FBE模式,一步即可,但是要想用PBE(PLL Bypassed External),那么就要根据(双向)箭头的指示,找最短路线,先设置为FBE,然后在设置为PBE。怎么去切换时钟模式,在8.4.1节下面小节的每个模式说明中都有介绍,这个读者自己去看了,我只把模式切换(Clock Switch Modes)图贴过来:

最后,读者要了解下,MCG内部的机制,建议读者通过一边浏览代码一边看MCG block diagram。通过这种方式,深入了解MCG提供的寄存器中各个设置项所做的事情,具体到MCG内部的详细情况。不同模式对输入的频率都有限制,这在芯片资料中8.5.2 MCG Mode Switching及相关对CLOCK mode说明章节中都有说明,设置的时钟分频一定要符合要求。

4.不善言表,废话也也多,上代码。


变量的重定义


#ifndef _DATA_TYPE_H_H

#define _DATA_TYPE_H_H

 

typedef char            INT8;

typedef unsigned char   UINT8;

typedef unsigned short  USHORT16;

typedef unsigned int    UNIT16;

typedef unsigned long   ULONG32;

typedef short           SHORT16;

typedef long            LONG32;

typedef unsigned char   BOOL;

#endif


头文件MCG.h


#ifndef _MCG_H_H

#define _MCG_H_H

 

#ifdef CRYSTAL2M

#define RDIV_PARAM 0x00  //2Mhz的外部时钟频率除16

#else

#ifdef CRYSTAL4M

#define RDIV_PARAM 0x08  //4Mhz的外部时钟频率除32

#else

#ifdef CRYSTAL8M

#define RDIV_PARAM 0x10  //8Mhz的外部时钟频率除64

#else

#define RDIV_PARAM 0x18  //其他频率除128

#endif

#endif

#endif

//MCGC1

/*

         7     6   5 4 3      2       1           0

    R  |---------------------------------------------

       | CLKS    |RDIV   | IREFS | IRCLKEN | IREFSTEN

    W  |---------|-----------------------------------

Reset:  0      0   0 0 0     1        0           0

*/

#define CLKS_SHIFT   6

#define RDIV_SHIFT   3

#define IREFS_SHIFT  2

#define IRCLKEN_SHIFT 1

#define IREFSTEN_SHIFT 0

 

/*

只设置目标项,不影响其他项目的设置值,如设置CLKS为0b11那么CLKS为0b11,其他的,如

RDIV不会改变,维持原来的值。

value:为目标设定的值,如设RDIV 0b011,那么value=0x03,

shift:为目标设置项在寄存器中的起点,从0开始

具体方式是:先清零设置项,再给已经清零的设置项赋值。

*/

void MCGC1_Target_Set(UINT8 value,UINT8 shift);

/*

Notice! Put a brandnew value to MCGC1,the pre-Value in MCGC1 will erased.

new value will replace it.

参数setMCGC1可以使用 表1中所有宏定义,如要设置多项,可以用位"与",来选择多个不同

设置选项。

*/

void MCGC1_Set(UINT8 setMCGC1);

//表1

//Selects the system clock source-----------------------------------------------

 

  #define MCGC1_RESET 0x04   //芯片重启复位后寄存器初始值

  #define CLKS_SEL_FLL_PLL     0x00//(0x00<<6)    //Output of FLL or PLL is selected.    

 

  #define CLKS_SEL_INT_REF_CLK 0x01//(0x01<<6)    //Internal reference clock is selected.

 

  #define CLKS_SEL_EXT_REF_CLK 0x02//(0x02<<6)    //External reference clock is selected.

 

  #define CLKS_SEL_RESERVED    0x03//(0x03<<6)    //Reserved, defaults to 00.

 

//Selects the amount to divide down the reference clock selected by the IREFS bit. 

 

//If the FLL is selected, the resulting frequency must be in the range 31.25kHz to 

 

//39.0625kHz. If the PLL is selected, the resulting frequency must be in the range

 

//1 MHz to 2 MHz.

 

  #define RDIV_1   0x00//(0x00<<3)    //Divides reference clock by 1(reset default)

 

  #define RDIV_2   0x01//(0x01<<3)   //Divides reference clock by 2

 

  #define RDIV_4   0x02//(0x02<<3)  //Divides reference clock by 4

 

  #define RDIV_8   0x03//(0x03<<3)  //Divides reference clock by 8

 

  #define RDIV_16  0x04//(0x04<<3)  //Divides reference clock by 16

 

  #define RDIV_32  0x05//(0x05<<3)  //Divides reference clock by 32

 

  #define RDIV_64  0x06//(0x06<<3)  //Divides reference clock by 64

 

  #define RDIV_128 0x07//(0x07<<3)  //Divides reference clock by 128     

 

//Selects the reference clock source.

 

  #define IREFS_SEL_INT_REF_CLK 0x01//0x01//(0x01<<2)    //Internal reference clock selected

 

  #define IREFS_SEL_EXT_REF_CLK 0x00//(0x00<<2)    //External reference clock selected

 

//Enables the internal reference clock for use as MCGIRCLK.

 

  #define MCGIRCLK_ACTIVE   0x01//(0x01<<1)  //MCGIRCLK active

 

  #define MCGIRCLK_INACTIVE 0x00//(0x00<<1)  //MCGIRCLK inactive

 

//Controls whether or not the internal reference clock remains enabled when

 

//the MCG enters stop mode.

 

  #define INT_CLK_ENABLE_IN_STOP  0x01    //Internal reference clock stays enabled

 

                                      // in stop if IRCLKEN is set or if MCG is in 

                                      //FEI, FBI, or BLPI mode before entering stop

 

  #define INT_CLK_DISABLE_IN_STOP 0x00  //Internal reference clock is disabled in stop

 

//MCGC2

 

/*

        7 6   5      4    3    2       1        0

R     ----------------------------------------------

      |BDIV |RANGE| HGO |LP |EREFS |ERCLKEN |EREFSTEN

W     ----------------------------------------------

Reset: 0 1     0     0    0    0      0         0

*/

#define BDIV_SHIFT    6

#define RANGE_SHIFT   5

#define HGO_SHIFT     4

#define LP_SHIFT      3

#define EREFS_SHIFT   2

#define ERCLKEN_SHIFT  1

#define EREFSTEN_SHIFT  0

/*

只设置目标项,不影响其他项目的设置值,如设置BDIV为0b11那么BDIV为0b11,其他的,如

RANGE不会改变,维持原来的值。

value:为目标设定的值,如设BDIV 0b11,那么value=0x03,

shift:为目标设置项在寄存器中的起点,从0开始

具体方式是:先清零设置项,再给已经清零的设置项赋值。

*/

void MCGC2_Target_Set(UINT8 value,UINT8 shift);

/*

Notice!  Put a brandnew value to MCGC2,the pre-Value in MCGC2 will erased.

new value will replace it.

参数setMCGC2可以使用 表2 中所有宏定义,如要设置多项,可以用位"与",来选择多个不同

设置选项。

*/

void MCGC2_Set(UINT8 setMCGC2);

//表2

//Selects the amount to divide down the clock source selected by the CLKS bits in the

 

//MCGC2 register. This controls the bus frequency.

  #define MCGC2_RESET 0x40     //MCGC2复位值

 

  #define BDIV_1 0x00//(0x00<<6)    //Divides selected clock by 1

 

  #define BDIV_2 0x01//(0x01<<6)    //Divides selected clock by 2 (reset default)

 

  #define BDIV_4 0x02//(0x02<<6)    //Divides selected clock by 4

 

  #define BDIV_8 0x03//(0x03<<6)    //Divides selected clock by 8

 

//Selects the frequency range for the external oscillator or external clock source.

 

  #define RANGE_1_16_MHZ  0x01//(0x01<<5)   //High frequency range selected for the external 

                                    //oscillator of 1 MHz to 16 MHz

 

  #define RANGE_1_40_MHZ  0x01//(0x01<<5)    //1 MHz to 40 MHz for external clock source

 

  #define RANGE_32_100_KHZ  0x00//(0x00<<5)    //Low frequency range selected for the external

                                       // oscillator of 32 kHz to 100 kHz

 

  #define RANGE_32K_1M_HZ  0x00//(0x00<<5)    //32 kHz to 1 MHz for external clock source.

 

//Controls the external oscillator mode of operation

 

  #define HGO_HI_GAIN  0x01//(0x01<<4)    //Configure external oscillator for high gain operation

[1] [2] [3] [4]
关键字:MC9S08DZ60 引用地址:第二课 MC9S08DZ60之多功能时钟发生器S08MCGV1

上一篇:第五课 MC9S08DZ60之串行外围设备接口SPI
下一篇:第三课 MC9S08DZ60之通用输出输入GPIO

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved