This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

不能理解if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF) 及BCSCTL1 = CALBC1_1MHZ;DCOCTL = CALDCO_1MHZ



#include "msp430x24x.h"

unsigned char value;                                 // 8-bit value to write to seg C typedef

// Function prototypes

void write_SegC(char value);

void copy_C2D(void);

void main(void)

{

 WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer

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

 {  

   while(1);                               // If calibration constants erased

                                           // do not load, trap CPU!!

 }  

 BCSCTL1 = CALBC1_1MHZ;                    // Set DCO to 1MHz        0x10FF    0x10FE

 DCOCTL = CALDCO_1MHZ;

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

 value = 0;                                // initialize value

 while(1)                                  // Repeat forever

 {

   write_SegC(value++);                    // Write segment C, increment value

   copy_C2D();                             // Copy segment C to D

   __no_operation();                       // SET BREAKPOINT HERE

 }

}

void write_SegC(char value)

{

 char *Flash_ptr;                          // Flash pointer

 unsigned int i;

 Flash_ptr = (char *)0x1040;               // Initialize Flash pointer

 FCTL3 = FWKEY;                            // Clear Lock bit

 FCTL1 = FWKEY + ERASE;                    // Set Erase bit

 *Flash_ptr = 0;                           // Dummy write to erase Flash seg

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

 for (i = 0; i < 64; i++)

 {

   *Flash_ptr++ = value;                   // Write value to flash

 }

 FCTL1 = FWKEY;                            // Clear WRT bit

 FCTL3 = FWKEY + LOCK;                     // Set LOCK bit

}

void copy_C2D(void)

{

 char *Flash_ptrC;                         // Segment C pointer

 char *Flash_ptrD;                         // Segment D pointer

 unsigned int i;

 Flash_ptrC = (char *)0x1040;              // Initialize Flash segment C ptr

 Flash_ptrD = (char *)0x1000;              // Initialize Flash segment D ptr

 FCTL3 = FWKEY;                            // Clear Lock bit

 FCTL1 = FWKEY + ERASE;                    // Set Erase bit

 *Flash_ptrD = 0;                          // Dummy write to erase Flash seg D

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

 for (i = 0; i < 64; i++)

 {

   *Flash_ptrD++ = *Flash_ptrC++;          // copy value segment C to seg D

 }

 FCTL1 = FWKEY;                            // Clear WRT bit

 FCTL3 = FWKEY + LOCK;                     // Set LOCK bit

}

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

    {  

      while(1);                               // If calibration constants erased

                                              // do not load, trap CPU!!

    }  

    BCSCTL1 = CALBC1_1MHZ;                    // Set DCO to 1MHz        0x10FF    0x10FE

    DCOCTL = CALDCO_1MHZ;

    在MSP430的information A Flash段中一般会有一些比如DCO校正信息,温度传感器校正等等的数据存在,这些是出厂设置好的!但是有时候用户会不小心把infoA擦除掉,而擦除后的内容就为0xFF了。

    背景知识介绍完了,上面程序段的作用是,判断CALBC1_1MHZ的地址内容是否被擦除了,如果擦除了,那么while(1)。

    如果没有,那么将校正信息添入相应的寄存器,可以得到精度相对高的DCO输出频率

  • 为了让内部DCO能够更加准确,在出厂前,会对DCO进行校正,其校正的参数就放在segmentA中,C编程的时候已经通过头文件定义宏CALBC1_xMHZ, CALDCO_xMHZ 来表明校正的参数值,这句话说的是如果发现segmentA对应的位置有校正参数,则继续运行将其赋值给BCSCTL1,若其里面的值没有(即使0xFF,或者有符号数-1)程序就不会执行了,因为系统时钟这个时候是说不准的,除非使用外部时钟源