打印
[ZLG-MCU]

Stellaris系列单片机在晶振被拔去后还能工作,不会死机!

[复制链接]
7163|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zlgmcu|  楼主 | 2007-12-26 17:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
Stellaris系列单片机在晶振被拔去后能够自动切换到内部振荡器,继续工作,不会死机!

  Luminary公司的Stellaris系列单片机拥有3个时钟验证电路,该电路使用定时器通过一个慢速时钟来检验快速时钟:
    ● 主振荡器检验PLL
    ● 主振荡器检验内部振荡器
    ● 内部振荡器除以64检验主振荡器

  其中,PLL和内部振荡器都在芯片内部,是完全可靠的,实际上没有必要对其进行检测。但是主振荡器外接的晶体可能会偶然失效。时钟验证电路能够自动检测出晶体失效,会使系统时钟自动切换到工作时钟,并向控制器发出中断。在中断里可以采取某种对策。

  以下是一个演示程序。

  在程序运行后,配置为主振荡器MOSC+外部6MHz晶体,并使能MOSC失效检测功能,在主循环里工作指示灯WORK_LED慢速闪烁。
  当拔去晶体时,会自动检测到MOSC失效,并触发中断。在中断里,系统时钟改为内部12MHz的振荡器IOSC,并点亮错误指示灯ERROR_LED,随后退出中断。
  在退出中断后,我们发现LED快速闪烁,速度大约是原来的2倍。

  由此可见,在Stellaris系列单片机里,正在工作的晶体即使被突然拔去,也不会造成死机,芯片可以自动切换到内部振荡器继续工作!


#include  "hw_types.h"
#include  "hw_memmap.h"
#include  "hw_ints.h"
#include  "hw_sysctl.h"
#include  "hw_gpio.h"
#include  "src/interrupt.h"
#include  "src/sysctl.h"
#include  "src/gpio.h"

// 将较长的标识符定义为较短的形式
#define  SysCtlPeriphEn         SysCtlPeripheralEnable
#define  SysCtlMOSCVeriSet      SysCtlMOSCVerificationSet
#define  GPIOPinTypeIn          GPIOPinTypeGPIOInput
#define  GPIOPinTypeOut         GPIOPinTypeGPIOOutput

// 定义LED指示灯,均为低电平点亮
#define  WORK_LED               GPIO_PORTB_BASE, GPIO_PIN_0
#define  ERROR_LED              GPIO_PORTB_BASE, GPIO_PIN_1

// 定义LED操作宏
#define  WorkLedOn()            GPIOPinWrite(WORK_LED, 0x00)
#define  WorkLedOff()           GPIOPinWrite(WORK_LED, 0x01)
#define  ErrorLedOn()           GPIOPinWrite(ERROR_LED, 0x00)
#define  ErrorLedOff()          GPIOPinWrite(ERROR_LED, 0x02)

// LED初始化
void  LedInit(void)
{
    SysCtlPeriphEn(SYSCTL_PERIPH_GPIOB);                // 使能GPIOB端口
    GPIOPinTypeOut(WORK_LED);                           // 设置WORK_LED所在管脚为输出
    GPIOPinTypeOut(ERROR_LED);                          // 设置WORK_LED在管脚为输出
    WorkLedOff();                                       // 初始化时熄灭WORK_LED
    ErrorLedOff();                                      // 初始化时熄灭ERROR_LED
}

// 时钟初始化
void  ClockInit(void)
{
    SysCtlClockSet(SYSCTL_USE_OSC   |                   // 采用MOSC+6MHz晶体
                   SYSCTL_OSC_MAIN  |
                   SYSCTL_XTAL_6MHZ);
    SysCtlMOSCVeriSet(true);                            // 使能IOSC/64验证MOSC功能
    SysCtlIntEnable(SYSCTL_INT_MOSC_FAIL);              // 使能MOSC失效中断
    IntEnable(INT_SYSCTL);                              // 使能系统控制中断
    IntMasterEnable();                                 // 使能处理器中断
}

// 延时
void  TimeDelay(unsigned long  ulVal)
{
    do {
    } while ( --ulVal != 0 );
}

// 主函数
int  main(void)
{
    // 初始化
    LedInit();
    ClockInit();

    // 在6MHz晶体下LED闪烁发光,若拔去晶体,自动改用12MHz的IOSC,闪烁加快
    for (;;) {
        WorkLedOn();
        TimeDelay(400000UL);
        WorkLedOff();
        TimeDelay(400000UL);
    }
}

// 系统控制中断服务函数
void  System_Control_ISR(void)
{
    SysCtlClockSet(SYSCTL_USE_OSC | SYSCTL_OSC_INT);    // 改用IOSC
    SysCtlMOSCVeriSet(false);                           // 禁止IOSC/64验证MOSC功能
    SysCtlIntClear(SYSCTL_INT_MOSC_FAIL);               // 清除MOSC失效中断
    ErrorLedOn();                                       // 点亮错误指示灯
}

相关帖子

沙发
s99060| | 2007-12-26 17:34 | 只看该作者

可惜,指示Stellaris系列才有

使用特权

评论回复
板凳
hotpower| | 2007-12-26 18:45 | 只看该作者

不错~~~不过在外部晶振坏时应该给出提示,否则串行通讯可能

使用特权

评论回复
地板
boy123| | 2007-12-26 19:11 | 只看该作者

时序要求严的地方呢?

使用特权

评论回复
5
AIRWILL| | 2007-12-27 00:36 | 只看该作者

可惜

才上电,不能用内部振荡器启动

使用特权

评论回复
6
zlgmcu|  楼主 | 2007-12-27 08:35 | 只看该作者

hotpower:您好!在例程里,晶振失效时会点亮ERROR_LED报警

使用特权

评论回复
7
zlgmcu|  楼主 | 2007-12-27 08:37 | 只看该作者

AIRWILL:您好!早期型号上电采用晶振,后续型号都是内部振

使用特权

评论回复
8
machunshui| | 2007-12-27 11:57 | 只看该作者

支持zlg,讨厌因为商业利益诋毁他人

支持zlg,讨厌因为商业利益诋毁他人.
做商业的原则是说自己好,但别说别人不好!

要是子虚乌有的说法,那人品就有问题了,商家的商业道德就有问题了.

使用特权

评论回复
9
AIRWILL| | 2008-1-4 10:56 | 只看该作者

感谢 ZLGMCU

那是我在 101 里的第一个试验结果

不过, 很高兴看到这个改进. 
另外我倒是还希望软件能够对内部 RC 频率进行微调.(AT MEGA 新款芯片都有这个功能)

使用特权

评论回复
10
zlgmcu|  楼主 | 2008-1-4 20:34 | 只看该作者

谢谢楼上的朋友们的支持!

内部振荡器存在一定的误差,是由于芯片制造工艺的问题,而不是内部振荡器本身不稳定。

使用特权

评论回复
11
mohanwei| | 2008-1-4 21:11 | 只看该作者

像C8051那样内部RC振荡器精度能做到2%,就不用晶振了

使用特权

评论回复
12
LPcfANS| | 2008-1-5 09:14 | 只看该作者

不用晶震就好了.毕竟不可能烧完程序在把晶震拔下去.

使用特权

评论回复
13
立体几何| | 2008-1-31 16:03 | 只看该作者

不是说用内部振荡器吗?当然不用外部晶振了。

使用特权

评论回复
14
zlgmcu|  楼主 | 2008-1-31 17:17 | 只看该作者

内部振荡器误差较大,不能完全代替外接晶振

由于IC制造工艺方面的原因,内部振荡器误差较大。因此还不能完全取代外接晶振。

(zlgmcu_wdx)

使用特权

评论回复
15
疯子8972| | 2008-2-3 16:33 | 只看该作者

哦 温漂有几个PPM?

不知道这个内部振荡,温漂有几个PPM
如果大一点的话,这个东西也就是实验玩玩的用处了
有周工的前期工作,这个开发板看来是一定要买着用用看了

使用特权

评论回复
16
xiachu| | 2013-10-4 15:52 | 只看该作者
src/gpio.h 这种头文件需要自己下吗?在哪下 困扰好久了 一直编译错误

使用特权

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

本版积分规则

81

主题

1146

帖子

0

粉丝