写在前面的话->:
单片机要工作的话要具备一些基本条件,其中一条就是要有稳定的同步信号。在飞思卡尔 S12 这款单片机中 这个同步信号像其他单片机一样也是由 外部晶振来提供的。但与传统 51 单片机不同的是 S12 里面集成了 PLL (锁相环) 倍频电路,它可以把外部晶振的频率超到一定之后再提供给单片机,做为系统时钟。并且这个 PLL 电路是可以软件编程的。所以在对 S12 这款单片机进行软件编程时,首先就要配置系统的时钟。假如没有配置好系统时钟的话就像人没有了心脏一样,接下来单片机具体在干什么事就只有它知道。
配置系统时钟的步骤如下:
1、失能系统 PLL
2、打开 PLL 电路
3、计算频率
要改变频率只要修改 SYNR、REFDV、POSTDIV 这三个寄存器的值即可。具体怎么修改,改成多大可参考
datasheet,MC9S12XS128RMV1.pdf 这个 PDF 文档(文档是英文的),里面有具体的公式。以下给出常用的
配置。
/*----------40M----------*/
SYNR =0xc0 | 0x04; REFDV=0xc0 | 0x01; POSTDIV=0x00;
/*----------48M----------*/
SYNR =0xc0 | 0x05; REFDV=0xc0 | 0x01; POSTDIV=0x00;
/*----------64M----------*/
SYNR =0xc0 | 0x07; REFDV=0xc0 | 0x01; POSTDIV=0x00;
4、等待 PLL 输出频率稳定
5、使能系统 PLL
实验的目的:学会 MC9S12XS128 这款单片机系统时钟的配置很 GPIO 的使用。
/********************************代码实现*************************************/
#include <hidef.h> /* common defines and macros */
#include <MC9S12XS128.h> /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12xs128"
#include <MC9S12XS128.h> /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12xs128"
/*--------函数原型声明-------------------------**/
void SetBusCLK_48M(void);
void DE_48M_ms(int ms);
/*----------------------------------------------*/
/*--------主函数中 8路LED以200ms的间隔闪烁-------*/
void main(void)
{
byte i = 0;
DisableInterrupts;
SetBusCLK_48M();
DDRB = 0XFF; //PB口设置为输出
PORTB = 0XFF; //PB口初始化输出高电平
for(;;)
{
for(i=0;i<8;i++)
{
PORTB &= ~(1<<i); //LED ON
DE_48M_ms(200);
PORTB |= (1<<i); //LED OFF
DE_48M_ms(200);
}
}
void main(void)
{
byte i = 0;
DisableInterrupts;
SetBusCLK_48M();
DDRB = 0XFF; //PB口设置为输出
PORTB = 0XFF; //PB口初始化输出高电平
for(;;)
{
for(i=0;i<8;i++)
{
PORTB &= ~(1<<i); //LED ON
DE_48M_ms(200);
PORTB |= (1<<i); //LED OFF
DE_48M_ms(200);
}
}
}
/*-----------------配置系统时钟------------------*/
void SetBusCLK_48M(void)
{
CLKSEL = 0X00; //disengage PLL to system
PLLCTL_PLLON = 1; //turn on PLL
SYNR = 0xc0 | 0x05;
REFDV = 0xc0 | 0x01;
POSTDIV = 0x00; //pllclock=2*osc*(1+SYNR)/(1+REFDV)=80MHz;
_asm(nop); //BUS CLOCK=48M
_asm(nop);
while(!(CRGFLG_LOCK == 1)); //when pll is steady ,then use it;
CLKSEL_PLLSEL = 1; //engage PLL to system;
}
/*-----------------ms 级延时---------------------*/
void DE_48M_ms(int ms)
{
int ii,jj;
if (ms<1) ms=1;
for(ii=0;ii<ms;ii++)
for(jj=0;jj<4006;jj++); //48MHz--1ms
}
/*---------------end of file----------------------*/
void SetBusCLK_48M(void)
{
CLKSEL = 0X00; //disengage PLL to system
PLLCTL_PLLON = 1; //turn on PLL
SYNR = 0xc0 | 0x05;
REFDV = 0xc0 | 0x01;
POSTDIV = 0x00; //pllclock=2*osc*(1+SYNR)/(1+REFDV)=80MHz;
_asm(nop); //BUS CLOCK=48M
_asm(nop);
while(!(CRGFLG_LOCK == 1)); //when pll is steady ,then use it;
CLKSEL_PLLSEL = 1; //engage PLL to system;
}
/*-----------------ms 级延时---------------------*/
void DE_48M_ms(int ms)
{
int ii,jj;
if (ms<1) ms=1;
for(ii=0;ii<ms;ii++)
for(jj=0;jj<4006;jj++); //48MHz--1ms
}
/*---------------end of file----------------------*/
发表评论 评论 (1 个评论)