打印

MA805切换外部晶振问题

[复制链接]
1671|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主

如图,单片机和晶振的位置,不知道对外部晶振起振的影响大不大
我手头上有3个切换外部晶振的程序,都试过,晶振貌似都不工作,测量晶振两个电容(30PF)的电压都是4.95V和VCC一样的。
程序一:
void change_ocInit(void)        //切换外部晶振{         
    IFMT  = 0x06;           // AUXRA
        IFD   = 0x6f ;          // AUXRA = 0x6f,enable XTALE & BORSET
        ISPCR|= 0x80;           // enable ISP
        SCMD  = 0x46;
        SCMD  = 0xb9;
        _nop_();
    _nop_();
    _nop_();
        IFMT  = 0x06;           // AUXRA
        IFD   = 0x2b ;          // disable INOSC
        ISPCR|= 0x80;           // enable ISP
        SCMD  = 0x46;
        SCMD  = 0xb9;
}
程序二:
void Register_Initialization()
{
                   //CKCON0 = 0x00;  //CKCON0为时钟控制寄存器0,
                   //Bit7 = 0禁止USB时钟和USB功能,
                   //Bit6 = 0禁止时钟倍频(×8),
                   //Bit5~4倍频时钟输入选择6MHz,Bit3 = 0保留位,
                   //Bit2~0系统时钟分频器选择位为000即系统时钟SYS=MCK=22.1184MHz
                   //在设置外部晶振时需要注意:
                   //先使能外部晶振(XTAL)标志位XTALE,
                   //然后再打开并选择外部晶振MCK时钟源、OSCin时钟源XTAL,
                   //最后再关闭内部IHRCOE即内部快频RC震荡使能位,
                   //根据颜工技术支持的说法,此内部快频RC振荡使能位可以不关闭,
                   //外部时钟也会很精确,只是会让费一些额外的能耗,最好是关掉内部快频RC振荡使能位       
    EA     = 0 ;
    IFD    = 0x70; //(ISP/IAP Flash 数据寄存器)开外部晶振,置位CKCON2.Bit5位,使能XTAL振荡电路   

    IFADRH = 0x00; //注意这里的配置
    IFADRL = 0x40;

    IFMT   = 0x04;   
    ISPCR |= 0x80;
    SCMD   = 0x46;
    SCMD   = 0xB9;
    _nop_();
    ISPCR &= ~0x80;
    IFMT   = 0x00;
    IFD    = 0xFF;

    EA     = 1;
    DelayMs(5);   //延时,以待外挂晶振稳定   

    EA     = 0;

    IFD    = 0x71; //选择XTAL,置位CKCON2.Bit0位,OSCin时钟源选择XTAL

    IFADRH = 0x00; //注意这里的配置
    IFADRL = 0x40;

    IFMT   = 0x04;   
    ISPCR |= 0x80;
    SCMD   = 0x46;
    SCMD   = 0xB9;
    _nop_();
    ISPCR &= ~0x80;
    IFMT   = 0x00;
    IFD    = 0xFF;

    EA     = 1;        //下面执行写CKCON2 = 0x61的配置,即设置外部晶振时钟作为本产品的系统时钟,
                //外部晶振时钟频率22.1184MHz等于本产品的系统时钟SYSCLK                                               
    EA     = 0;    //关总中断

    IFD    = 0x61; //清零CKCON2.Bit4位,禁止内部快频RC震荡电路IHRCOE
                   //配置CKCON2 = 0x61;即将CKCON2的值0x61赋值给IFD,
                   //等待下面将IFD中的值0x61写入到IFADRL寄存器CKCON2所对应的地址0x40中,
                   //CKCON2为时钟控制寄存器2,
                   //Bit7~6 =01 XTAL振荡器增益控制寄存器,
                   //软件必须写01,Bit5 = 1使能XTAL振荡电路,Bit4 = 0禁止内部快频RC振荡电路,
                   //Bit3~2 = 00 MCK时钟源选择OSCin,
                   //Bit1~0 = 01 OSCin时钟源选择XTAL即外部晶振时钟                        
    IFADRH = 0x00; //在P页访问时,IFADRH必须设置为”00”
    IFADRL = 0x40; //IFADRL索引P页内特殊功能寄存器地址

    IFMT   = 0x04; //IFMT=04H则执行写P页操作,在SCMD激活之后IFD的数据会被载入到IFADRL索引的特殊功能寄存器,
                   //这些特殊功能寄存器在P页模式下不支持读功能
    ISPCR |= 0x80; //ISPCR为ISP控制寄存器,Bit7 ISP/IAP/P页操作使能位,=1 使能 ISP/IAP/P页编程/擦除/读功能
    SCMD   = 0x46; //SCMD为连续命令数据寄存器,SCMD是激活ISP/IAP/P页的命令口,
                   //如果SCMD连续填入0x46h,0xB9h并且ISPCR.7 = 1,ISP/IAP/P页被激活
    SCMD   = 0xB9;
    _nop_();           //延时一个_nop_()语句的时间
    ISPCR &= ~0x80;//ISPCR为ISP控制寄存器,Bit7 ISP/IAP/P页操作使能位,
                   //=0 所有的ISP/IAP/P页编程/擦除/读都是被禁止的
    IFMT   = 0x00; //IFMT为ISP/IAP闪存模式表,IFMT的作用是用来选择闪存是被用来执行众多的ISP/IAP功能
                   //还是选择P页寄存器的访问,Bit 7~4: 保留,当IFMT改写时这些位必须写入”0”,
                   //Bit3~0: ISP/IAP/Page-P操作模式选择,=0x00 备用,=0x01 AP/IAP-存储器读,
                   //=0x02 AP/IAP-存储器编程,=0x03 AP/IAP-存储器页擦除, =0x04 P页SFR写   
    IFD    = 0xFF;
                   //IFD为ISP/IAP闪存数据寄存器,IFD是ISP/IAP操作的数据端口寄存器,
                   //在ISP/IAP写操作时IFD的数据将被写入到期望的地址,
                   //在ISP/IAP读操作时IFD的值是读到期望地址的数据

    EA     = 1;           //打开总中断                       
/////////////////////
                 //AUXR2  = 0x00;                                                                                         
                 //Bit3:T1X12,当C/T=0时,定时器1时钟源选择,=0 清零选择SYSCLK/12作为时钟源;
                 //Bit2:T0X12,当C/T=0时,定时器0时钟源选择,=0 清零选择SYSCLK/12作为时钟源
                 //T2MOD  = 0x00;
                 //Bit4:T2X12,定时器2时钟源选择,=0 当T2CON.C/T2 = 0选择SYSCLK/12作为捕获和自动重载模式定时器2的时钟源       
                 //T3MOD  = 0x00;
                 //Bit4:T3X12,定时器3时钟源选择,=0 当T3CON.C/T3 = 0选择SYSCLK/12作为定时器3时钟源

}

程序三:

/*先用内部,再调用外部XTAL*/
/*实际上,先从外部调到内部,再从内部调到外部*/

#include<REG_MA805.H>
#include"intrins.h"

typedef unsigned int uint16;

uint16 k = 10;
uint16 num;

void DelayMs(uint16 ms)
{
    uint16 i, j;
    for(i = 0; i < ms; i++)
    {
        for(j = 0; j < 1320; j++);
    }
}

void T0_int(void)
{
    TMOD = 0X01;
    TH0 = 0XFC;
    TL0 = 0X66;

    ET0 = 1;
    TF0 = 0;
}

void main(void)
{  
    T0_int();

    T0_int();

    /////注意/////////
    /////注意/////////
    IFMT = 0X07;

    ISPCR |= 0X80;   
    SCMD = 0X46;
    SCMD = 0XB9;
    ISPCR &= 0X7F;
    SCMD = 0X00;

    P0 = IFD;    //把AUXR的上电复位值调出来,供我们写程序用
                 //特别是在原因的寄存器上改写的程序,会很有用的

                 //如果没有这段程序的话,我们在操作IFD的话,就不是在AUXR的基础上动作的,而是在IFD(FF)上操作的

    ///////////////
    ///////////////想想,如果没有以上的这段程序的话,结果会怎么样的?

    while(k--) //检测外挂的晶振
    {
        P2 = ~P2;
        DelayMs(1000);
    }
    k = 10;


    /*调用内置高频*/   
    IFMT = 0X06;

    IFD &= 0XFB;

    IFD |= 0X04;  //操作IFD就是操作AUXRA
                  //选择内置高频,使内置高频起振

    ISPCR |= 0X80;   
    SCMD = 0X46;
    SCMD = 0XB9;
    ISPCR &= 0X7F;
    SCMD = 0X00;

    EA = 1;
    TR0 = 1;
    while(!(num == 5)); //延时以待稳定
    num = 0;
    TR0 = 0;
    EA = 0;

    IFMT = 0X06;
    IFD &= ~0X03;  //操作IFD就是操作AUXRA
                   //选择内置高频
    IFD |= 0X00;
    ISPCR |= 0X80;   
    SCMD = 0X46;
    SCMD = 0XB9;
    ISPCR &= 0X7F;
    SCMD = 0X00;      
    /*完毕*/   


    IFMT = 0X06;
    IFD &= ~0X08;  //操作IFD就是操作AUXRA
                   //关闭外部晶振

    ISPCR |= 0X80;   
    SCMD = 0X46;
    SCMD = 0XB9;
    ISPCR &= 0X7F;
    SCMD = 0X00;

    /*完毕*/

    IFMT = 0X07;

    ISPCR |= 0X80;   
    SCMD = 0X46;
    SCMD = 0XB9;
    ISPCR &= 0X7F;
    SCMD = 0X00;

    P1 = IFD;   //检验AURXA设置后的情况

    while(k--)
    {
        P2 = ~P2;

        DelayMs(1000);        
    }  


    /*调用外部晶振*/   
    IFMT = 0X06;

    IFD |= 0X08;  //操作IFD就是操作AUXRA
                //选择外部晶振

    ISPCR |= 0X80;   
    SCMD = 0X46;
    SCMD = 0XB9;
    ISPCR &= 0X7F;
    SCMD = 0X00;

    EA = 1;
    TR0 = 1;   //延时以待晶振稳定
    while(!(num == 5));
    num = 0;
    TR0 = 0;
    EA = 0;

    IFMT = 0X06;

    IFD |= 0X03;  //操作IFD就是操作AUXRA
                  //选择外部晶振

    ISPCR |= 0X80;   
    SCMD = 0X46;
    SCMD = 0XB9;
    ISPCR &= 0X7F;
    SCMD = 0X00;

    IFMT = 0X06;

    IFD &= ~0X04;  //操作IFD就是操作AUXRA
                  //关闭内置高频

    ISPCR |= 0X80;   
    SCMD = 0X46;
    SCMD = 0XB9;
    ISPCR &= 0X7F;
    SCMD = 0X00;

    /*完毕*/

    IFMT = 0X07;

    ISPCR |= 0X80;   
    SCMD = 0X46;
    SCMD = 0XB9;
    ISPCR &= 0X7F;
    SCMD = 0X00;

    P1 = IFD;   


    while(1)
    {
        P2 = ~P2;

        DelayMs(1000);        
    }  

}

void T0_inter() interrupt 1
{
    TH0 = 0XFC;
    TL0 = 0X66;

    num++;
}



沙发
mg_sz| | 2015-1-8 09:17 | 只看该作者
回楼主, 晶振离IC 太远.而且有过孔.晶振应该是离的越近越好.楼主如果有U1,请用U1 烧录时选择用外振.看看晶振能不能振起来.做判断.
程序暂时没有发现问题.

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
mx2海贼 + 1 赞一个!
板凳
mg_sz| | 2015-1-8 09:20 | 只看该作者
MA805  内振有两个24M/22.1184 频率.而且内振很准.完全可以替代外振使用.楼主可以考虑.

使用特权

评论回复
地板
mx2海贼|  楼主 | 2015-1-8 11:08 | 只看该作者
mg_sz 发表于 2015-1-8 09:17
回楼主, 晶振离IC 太远.而且有过孔.晶振应该是离的越近越好.楼主如果有U1,请用U1 烧录时选择用外振.看看晶 ...

因为用了高精度的外部AD,感觉还是用晶振比较好,毕竟RC振荡器神马的,真不好说,我参考了前辈的一个程序,晶振调试成功了,主要是IFD那里写的不对:
void ex_clk()
{ IFD    = 0x2c;
  IFMT   = 0x06;  //AUXRA_WRITE
  ISPCR |= 0x80;
  SCMD   = 0x46;
  SCMD   = 0xb9;
        _nop_();
    _nop_();
    _nop_();
        _nop_();
        _nop_();
  IFD    = 0x2f;
  IFMT   = 0x06;
  ISPCR |= 0x80;
  SCMD   = 0x46;
  SCMD   = 0xb9;
  ISPCR  = 0x00;
  IFMT   = 0x00;
  
}
如果谁有用相同的单片机的话,参考一下可以的

使用特权

评论回复
5
ruitairt| | 2015-1-8 15:51 | 只看该作者

mg_sz 发表于 2015-1-8 09:17
回楼主, 晶振离IC 太远.而且有过孔.晶振应该是离的越近越好.楼主如果有U1,请用U1 烧录时选择用外振.看看晶 ...

因为用了高精度的外部AD,感觉还是用晶振比较好,毕竟RC振荡器神马的,真不好说,我参考了前辈的一个程序,晶振调试成功了,主要是IFD那里写的不对:
void ex_clk()
{ IFD    = 0x2c;
  IFMT   = 0x06;  //AUXRA_WRITE
  ISPCR |= 0x80;
  SCMD   = 0x46;
  SCMD   = 0xb9;
        _nop_();
    _nop_();
    _nop_();
        _nop_();
        _nop_();
  IFD    = 0x2f;
  IFMT   = 0x06;
  ISPCR |= 0x80;
  SCMD   = 0x46;
  SCMD   = 0xb9;
  ISPCR  = 0x00;
  IFMT   = 0x00;

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

11

主题

18

帖子

0

粉丝