msp430的DCO校准值被清除后该如何处理

2019-10-23来源: eefocus关键字:msp430  DCO  校准值

起因

在调试MSP430G系列的单片机的过程,发现不怎么的,时钟频率发生了变化,时间一下都对不上了。查收些资料说,DCO的值有可能被擦除了导致时钟不对的。细想一下,好像是在调试的过程中,出现调试不了的现象就在IAR里点击的“Erase memory”。把查找的资料记录下来,所以就有这篇文章。


问题描述

因为DCO校准值在MCU出厂时保存于信息段A,一般是不允许清除信息段A的。


且示例代码中,有如下语句:


if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)     

    while(1);// If calibration constants erased

    // do not load, trap CPU!!

}

BCSCTL1 = CALBC1_1MHZ; // Set range

DCOCTL = CALDCO_1MHZ; // Set DCO step + modulation 


可以看出在启动时都先检查DCO1MHZ的校准值是否为0xFF,是则进入while(1)死循环。 

正常情况下因为信息段A不清除没问题的,但是我测试BSL下载时,故意给错误的BSL密码,导致FLASH都被擦除,发现转载DCO校准值的信息段A也被清掉了,于是程序运行到上面的代码时即进入死循环。


解决办法

针对于这种DCO数据被擦除的情况,一般的解决办法是,通过利用Timer捕捉外部的32.768K晶振或是时钟源,然后得到1M,8M或是12Mhz之类的DCO的数值,然后在直接写入segment flashA里面。 

有两个解决方案供选择:


1、外接晶体,用晶体配合timer校正DCO,TI的msp4300ware有源代码。如下:

 /*******************************************************************************

 * 

 *                       MSP430 CODE EXAMPLE DISCLAIMER

 *

 * MSP430 code examples are self-contained low-level programs that typically

 * demonstrate a single peripheral function or device feature in a highly

 * concise manner. For this the code may rely on the device's power-on default

 * register values and settings such as the clock configuration and care must

 * be taken when combining code from several examples to avoid potential side

 * effects. Also see www.ti.com/grace for a GUI- and www.ti.com/msp430ware

 * for an API functional library-approach to peripheral configuration.

 *

 * --/COPYRIGHT--

//******************************************************************************/

//  MSP430G2xx1 Demo - DCO Calibration Constants Programmer

//

//  NOTE: THIS CODE REPLACES THE TI FACTORY-PROGRAMMED DCO CALIBRATION

//  CONSTANTS LOCATED IN INFOA WITH NEW VALUES. USE ONLY IF THE ORIGINAL

//  CONSTANTS ACCIDENTALLY GOT CORRUPTED OR ERASED.

//

//  Description: This code re-programs the G2xx1 DCO calibration constants.

//  A software FLL mechanism is used to set the DCO based on an external

//  32kHz reference clock. After each calibration, the values from the

//  clock system are read out and stored in a temporary variable. The final

//  frequency the DCO is set to is 1MHz, and this frequency is also used

//  during Flash programming of the constants. The program end is indicated

//  by the blinking LED.

//  ACLK = LFXT1/8 = 32768/8, MCLK = SMCLK = target DCO

//  //* External watch crystal installed on XIN XOUT is required for ACLK *//

//

//           MSP430G2xx1

//         ---------------

//     /||            XIN|-

//      | |               | 32kHz

//      --|RST        XOUT|-

//        |               |

//        |           P1.0|--> LED

//        |           P1.4|--> SMLCK = target DCO

//

//  A. Dannenberg

//  Texas Instruments Inc.

//  May 2010

//  Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 3.42A

//******************************************************************************

#include


#define DELTA_1MHZ    244                   // 244 x 4096Hz = 999.4Hz

#define DELTA_8MHZ    1953                  // 1953 x 4096Hz = 7.99MHz

#define DELTA_12MHZ   2930                  // 2930 x 4096Hz = 12.00MHz

#define DELTA_16MHZ   3906                  // 3906 x 4096Hz = 15.99MHz


unsigned char CAL_DATA[8];                  // Temp. storage for constants

volatile unsigned int i;

int j;

char *Flash_ptrA;                           // Segment A pointer

void Set_DCO(unsigned int Delta);


int main(void)

{

  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT

  for (i = 0; i < 0xfffe; i++);             // Delay for XTAL stabilization

  P1OUT = 0x00;                             // Clear P1 output latches

  P1SEL = 0x10;                             // P1.4 SMCLK output

  P1DIR = 0x11;                             // P1.0,4 output


  j = 0;                                    // Reset pointer


  Set_DCO(DELTA_16MHZ);                     // Set DCO and obtain constants

  CAL_DATA[j++] = DCOCTL;

  CAL_DATA[j++] = BCSCTL1;


  Set_DCO(DELTA_12MHZ);                     // Set DCO and obtain constants

  CAL_DATA[j++] = DCOCTL;

  CAL_DATA[j++] = BCSCTL1;


  Set_DCO(DELTA_8MHZ);                      // Set DCO and obtain constants

  CAL_DATA[j++] = DCOCTL;

  CAL_DATA[j++] = BCSCTL1;


  Set_DCO(DELTA_1MHZ);                      // Set DCO and obtain constants

  CAL_DATA[j++] = DCOCTL;

  CAL_DATA[j++] = BCSCTL1;


  Flash_ptrA = (char *)0x10C0;              // Point to beginning of seg A

  FCTL2 = FWKEY + FSSEL0 + FN1;             // MCLK/3 for Flash Timing Generator

  FCTL1 = FWKEY + ERASE;                    // Set Erase bit

  FCTL3 = FWKEY + LOCKA;                    // Clear LOCK & LOCKA bits

  *Flash_ptrA = 0x00;                       // Dummy write to erase Flash seg A

  FCTL1 = FWKEY + WRT;                      // Set WRT bit for write operation

  Flash_ptrA = (char *)0x10F8;              // Point to beginning of cal consts

  for (j = 0; j < 8; j++)

    *Flash_ptrA++ = CAL_DATA[j];            // re-flash DCO calibration data

  FCTL1 = FWKEY;                            // Clear WRT bit

  FCTL3 = FWKEY + LOCKA + LOCK;             // Set LOCK & LOCKA bit


  while (1)

  {

    P1OUT ^= 0x01;                          // Toggle LED

    for (i = 0; i < 0x4000; i++);           // SW Delay

  }

}


void Set_DCO(unsigned int Delta)            // Set DCO to selected frequency

{

  unsigned int Compare, Oldcapture = 0;


  BCSCTL1 |= DIVA_3;                        // ACLK = LFXT1CLK/8

  TACCTL0 = CM_1 + CCIS_1 + CAP;            // CAP, ACLK

  TACTL = TASSEL_2 + MC_2 + TACLR;          // SMCLK, cont-mode, clear


  while (1)

  {

    while (!(CCIFG & TACCTL0));             // Wait until capture occured

    TACCTL0 &= ~CCIFG;                      // Capture occured, clear flag

    Compare = TACCR0;                       // Get current captured SMCLK

    Compare = Compare - Oldcapture;         // SMCLK difference

    Oldcapture = TACCR0;                    // Save current captured SMCLK


    if (Delta == Compare)

      break;                                // If equal, leave "while(1)"

    else if (Delta < Compare)

    {

      DCOCTL--;                             // DCO is too fast, slow it down

      if (DCOCTL == 0xFF)                   // Did DCO roll under?

        if (BCSCTL1 & 0x0f)

BCSCTL1--;

[1] [2]
关键字:msp430  DCO  校准值 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic478063.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:使用Energia开发MSP430 LAUNCHPAD学习笔记2--串口通信
下一篇:MSP430如何使用energia

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

MSP430G2553与MSP430F5336系列单片机总结[4]——比较器B的使用
比较器B是什么,顾名思义,它其实就是用来比较模拟电压+输入端和-输入端的电压大小,然后设置输出信号CBOUT的值的,如果 + 端电压高于 - 端电压,则CBOUT置高,否则置低。主要的控制寄存器有CBCTL0,CBCTL1,CBCTL2,CBCTL3,CBINT,CBIV,在MSP430G2553中没有比较器B,但是F5336中有,所以接下来的代码全都是F5336的比较器B使用程序:1.比较器B输入通道CB0接外部模拟输入信号,并且引至比较器+输入端,内部参考电压发生器利用共享电压源产生2.0V参考电压。最后当CB0输入模拟信号电压高于2.0V时,CBOUT输出高电平,当CB0输入模拟信号电压低于2.0V时,输出低电平
发表于 2019-11-06
怎么用keil5实现MSP432E401Y点灯
**第一步**先去官网下载芯片包在keil这个序列中选择TI公司相对应的芯片包下载后在pack installer->import->I agree ->finish出现绿色图标,就代表成功。第二步下载模板模板链接打开工程,选择正确的芯片出现下载失败或者没法编译时选择正确的编译器版本插好线接下来Debug的配置是选择正确的芯片flash然后点击编译下载就好了第三步下面两个网站可以下载资料开发板资料芯片资料从开发板原理图可以知道LED灯的引脚接下来是简单流水灯
发表于 2019-11-06
怎么用keil5实现MSP432E401Y点灯
MSP432E401Y-PWM的生成和占空比的调整
 * MSP432E4 Empty Project * * Description: An empty project that uses DriverLib * *                MSP432E401Y *             ------------------ *         /||          
发表于 2019-11-06
MSP432时钟系统CS
MSP432共有六个时钟源,五个时钟,下面分别由我来介绍一下时钟源分别有以下几个LFXTCLK:低频振荡器(LFXT),可与低频32768-Hz手表配套使用,晶体,标准晶体,谐振器,或外部时钟源在32千赫或以下的范围。当在旁路模式下,LFXTCLK可以由32 khz或以下的外部方波信号驱动的范围内。HFXTCLK:高频振荡器(HFXT),可与1-MHz至48-MHz范围内的标准晶体或谐振器一起使用。在旁路模式下,HFXTCLK可以通过外部方波信号驱动。DCOCLK:内部数字控制振荡器(DCO),默认频率为可编程频率和3 mhz频率。VLOCLK:内部极低功率低频振荡器(VLO),典型频率为9.4 khzREFOCLK:内部低功率
发表于 2019-11-06
MSP432E401Y单片机智能小车测速功能
 * MSP432E401Y * Description:本函数实现定时和测速功能   * 引脚:PD0->编码器输入信号 *         * Author: Robin.J***************************************************************************//* DriverLib Includes */#include <ti/devices/msp432e4/driverlib/driverlib.h>/* Standard
发表于 2019-11-06
MSP432学习笔记:IAR的环境配置(官方demo程序的测试)
近来入手一块MSP432,折腾了一天,终于把官方demo程序导入IAR,可以愉快的写代码了,以下是我个人的解决办法。首先,如果要使用IAR对TI的单片机进行开发,首先要下载对应的单片机型号的MSPWARE,本人目前使用的是TI的MSP432P401R的launchpad,对应的MSPWARE的下载地址为msp432ware下载地址,下载完成后默认路径安装即可,安装完成后可以在安装路径下找到下图的文件IAR的下载安装在这里就不做赘述了,需要注意的是IAR的版本应该为IAR for ARM版本,这个千万不能搞错,否则可能会吃很多问题,不能正常运行。正确安装完IAR后应该是这个样子的,我现在安装的是最新的版本,测试没有问题准备工作完成
发表于 2019-11-06
MSP432学习笔记:IAR的环境配置(官方demo程序的测试)
小广播
何立民专栏 单片机及嵌入式宝典

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

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