||
今日由于工作需要,经常背着笔记本,拿着仿真器以及BSL编程器来回奔波。
巧的是赶上了一款MSP430F2132 当采用BSL编程的时候,发现内部DCO校正参数
丢失,很麻烦。于是上网发现了以为朋友写的一个程序,借鉴过来添加到工程
里面,完全解决了DCO丢失的问题。特此感谢这位朋友!
另外也为了减少重量自己做了一个转接板,把JTAG+BSL统一到一个小板子上,
携带也方便多了,以后只需要带一个仿真器就可以了!
下面先给大家一个DCO的校正程序,然后是我自己画的小板子!
#include <msp430x21x2.h>
#define DELTA_1M 245
#define DELTA_8M 1954
#define DELTA_12M 2930
#define DELTA_16M 3906
char *pInfoFlash_A;
char AdjBCSCTL1_1M;
char AdjpDCOCTL_1M;
char AdjBCSCTL1_8M;
char AdjpDCOCTL_8M;
char AdjBCSCTL1_12M;
char AdjpDCOCTL_12M;
char AdjBCSCTL1_16M;
char AdjpDCOCTL_16M;
char tmpBCSCTL1;
char tmpDCOCTL;
void softwareDelay(unsigned int time)
{
while(--time);
}
void timeAdelay(unsigned int time)
{
TACTL = TASSEL_1 + MC_2 + TACLR; // SMCLK, cont-mode, clear
while(time)
{
while(!(TACTL &TAIFG));
TACTL &= ~TAIFG;
time--;
}
TACTL = 0;
}
void Set_DCO (unsigned int delta, char *pBcsctl1_, char *pDcoct_) // Set DCO to selected frequency
//------------------------------------------------------------------------------
{
unsigned int Compare, Oldcapture = 0;
BCSCTL1 |= DIVA_3; // ACLK= LFXT1CLK/8
BCSCTL3 |= XCAP_3;
CCTL2 = CM_1 + CCIS_1 + CAP; // CAP, ACLK
TACTL = TASSEL_2 + MC_2 + TACLR; // SMCLK, cont-mode, clear
while (1)
{
while (!(CCIFG & CCTL2)); // Wait until capture occured
CCTL2 &= ~CCIFG; // Capture occured, clear flag
Compare = CCR2; // Get current captured SMCLK
Compare = Compare - Oldcapture; // SMCLK difference
Oldcapture = CCR2; // Save current captured SMCLK
if (delta == Compare) break; // If equal, leave "while(1)"
else if (delta < Compare) // DCO is too fast, slow it down
{
DCOCTL--;
if (DCOCTL == 0xFF)
{
if (!(BCSCTL1 == (XT2OFF + DIVA_3)))
BCSCTL1--; // Did DCO roll under?, Sel lower RSEL
}
}
else
{
DCOCTL++;
if (DCOCTL == 0x00)
{
if (!(BCSCTL1 == (XT2OFF + DIVA_3 + 0x0F)))
BCSCTL1++; // Did DCO roll over? Sel higher RSEL
}
}
softwareDelay(20);
}
CCTL2 = 0; // Stop CCR2
TACTL = 0; // Stop Timer_A
*pBcsctl1_ = BCSCTL1 & (~DIVA_3);
*pDcoct_ = DCOCTL;
}
void SetDcoConn(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
_DINT();
tmpBCSCTL1 = BCSCTL1;
tmpDCOCTL = DCOCTL;
Set_DCO(DELTA_1M, &AdjBCSCTL1_1M, &AdjpDCOCTL_1M);
Set_DCO(DELTA_8M, &AdjBCSCTL1_8M, &AdjpDCOCTL_8M);
Set_DCO(DELTA_12M, &AdjBCSCTL1_12M, &AdjpDCOCTL_12M);
Set_DCO(DELTA_16M, &AdjBCSCTL1_16M, &AdjpDCOCTL_16M);
BCSCTL1 = tmpBCSCTL1;
DCOCTL = tmpDCOCTL;
FCTL2 = FWKEY + FSSEL0 + FN1; // MCLK/3 for Flash Timing Generator
FCTL1 = FWKEY + ERASE; // Set Erase bit, allow interrupts
if(FCTL3 & LOCKA)
{
FCTL3 = FWKEY + LOCKA; // Clear LOCK & LOCKA bits
}
pInfoFlash_A = (char *) 0x10C0; // Initialize Flash pointer
*pInfoFlash_A = 0; // Dummy write to erase Flash segment A
FCTL1 = FWKEY + WRT; // Set WRT bit for write operation
pInfoFlash_A = (char *) CALDCO_16MHZ_; // Initialize Flash pointer
*pInfoFlash_A++ = AdjpDCOCTL_16M;
*pInfoFlash_A++ = AdjBCSCTL1_16M;
*pInfoFlash_A++ = AdjpDCOCTL_12M;
*pInfoFlash_A++ = AdjBCSCTL1_12M;
*pInfoFlash_A++ = AdjpDCOCTL_8M;
*pInfoFlash_A++ = AdjBCSCTL1_8M;
*pInfoFlash_A++ = AdjpDCOCTL_1M;
*pInfoFlash_A = AdjBCSCTL1_1M;
FCTL1 = FWKEY; // Clear WRT bit
FCTL3 = FWKEY + LOCKA + LOCK; // Set LOCK & LOCKA bit // Set LOCK bit
}
协助软件: