Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: WDT на MSP430F2012
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > MSP430
113
Суть: Проц MSP430F2012, WDT работает в интервальном режиме, от 32К кварца. После некоторого количества перепрошивок (отлаживаю), частота интервалов увеличивается в 8 раз. Две идентичные платы, с одинаковыми прошивками начинают работать по-разному. Такая ситуация уже с третьей платой.
Вот кусок инициализации:
Цитата
DCOCTL = CALDCO_16MHZ; // Set DCO to 16MHz
BCSCTL1 = CALBC1_16MHZ; // MCLC = SMCLK = DCOCLK = 16MHz
BCSCTL1 &= ~0x40; //Low-frequency mode
BCSCTL1 &= ~0x30; //Divider for ACLK = 1

BCSCTL2 = 0x00;
BCSCTL3 = LFXT1S_0 + XCAP_2; // 32768KHz crystal, 10 pF

while(IFG1 & OFIFG)
{
IFG1 &= ~OFIFG;
_delay_cycles(100000);
}

WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer

WDTCTL = WDT_ADLY_1_9;

IE1 |= WDTIE;


Что может быть причиной такого поведения?
rezident
Цитата(113 @ May 26 2014, 18:31) *
После некоторого количества перепрошивок (отлаживаю), частота интервалов увеличивается в 8 раз.

~skip~

Что может быть причиной такого поведения?

Как вариант. В процессе стирания кроме основной памяти вы стираете и область INFO, где хранятся калибровочные данные для DCO. Может эта частота где-то в вашей программе используется? Как вы проверяете частоту WDT? Для контроля частоты кварца выведите ACLK на пин P1.0 и проконтролируйте частоту.
113
Заметил, что при включении от БП плата заводится, а если проводами коммутировать - нет. Посмотрел: у БП фронт ~2 мс, а при коммутации проводами резкий выброс до 4 В, а потом спад до 3,2. На питание стоит LM317. Емкости все на месте. Впаял 10 Ом между LM317 и MSP - выброс пропал, фронт стал ~500 мкс при коммутации проводами. Теперь заводится и включением БП и коммутацией проводов, НО: при включении от блока (длинный фронт) частота срабатывания = номинальная*8 (см. первый пост), а при старте от коммутации проводов (короткий фронт) частота срабатывания еще выше (номинальная*8*8). Похоже что проц не выдержал бросков до 4В (может и чуть больше было во время испытаний "в поле"), и как следствие так странно сейчас себя ведет?

Код на всякий случай (мигает светиком):
CODE
//******************************************************************************
#include "msp430x20x2.h"

#define MAX_PWM 200 //96kHz
#define STROBE_PULSE 51
#define STROBE_PERIOD 800

unsigned long int ADC_temp;
unsigned long int ADC_avg = 0;
unsigned long int i = 0;

unsigned int Threshold = 10;
signed int reg_counter = 0;
unsigned int tmp;
unsigned int wdt_counter = 0;
unsigned int flags = 0x00;

#define _delay_cycles(num) \
{for(unsigned long i = 0; i<=num; i++) \
_NOP(); \
}

//=========main fuction
void main(void)
{

WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer

//=====System Clock
DCOCTL = CALDCO_16MHZ; // Set DCO to 16MHz
BCSCTL1 = CALBC1_16MHZ; // MCLC = SMCLK = DCOCLK = 16MHz
BCSCTL1 &= ~0x40; //Low-frequency mode
BCSCTL1 &= ~0x30; //Divider for ACLK = 1

BCSCTL2 = 0x00;
BCSCTL3 = LFXT1S_0 + XCAP_2; // 32768KHz crystal, 10 pF

while(IFG1 & OFIFG)
{
IFG1 &= ~OFIFG;
_delay_cycles(100000);
}

WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
WDTCTL = WDT_ADLY_1_9;

IE1 |= WDTIE;


//=====ADC Setup

ADC10CTL0 = ADC10SHT_3 + SREF_1 + REFON + ADC10ON;
ADC10CTL1 = INCH_1 + ADC10DIV_0 + ADC10SSEL_2; // 2 A1 input
ADC10AE0 = 0x02; // P1.1 ADC option select
ADC10DTC1 = 0x001; // 1 conversion


P1DIR = 0x00; // All input
P2DIR = 0x00; // All input
P1DIR |= 0x01; // P1.0 = output
P1DIR |= 0x04; // P1.2 = output
P1SEL |= 0x04; // P1.2 = TA1 output
P1SEL &= ~0x01; // P1.0 = GPIO
P1SEL &= ~0x08; // P1.3 = GPIO
P1SEL &= ~0x10; // P1.4 = GPIO

P1OUT &= ~0x01;

P2DIR |= 0x80; // P2.7 = output
P2SEL |= 0x80; // P2.7 = Xtal
P2SEL |= 0x40; // P2.6 = Xtal

TACCTL1 = OUTMOD_7; // TACCR1 reset/set
TACCR0 = MAX_PWM; // PWM Period
TACCR1 = 0; // TACCR1 PWM Duty Cycle
TACTL = TASSEL_2 + MC_1; // SMCLK, upmode

P1IES &= ~0x08; // P1.3 lo/hi edge
P1IFG &= ~0x08; // P1.3 IFG cleared
P1IE &= ~0x08; // P1.3 interrupt disabled

_EINT();


tmp = 0;
TACCR1 = 0;


//=====main loop
while(1)
{
// some code
}

}


//==========WDT Route
#pragma vector = WDT_VECTOR
__interrupt void WDT_ISR(void)
{
wdt_counter++;
if(wdt_counter == STROBE_PERIOD - STROBE_PULSE)
P1OUT |= 0x01;
else
if(wdt_counter == STROBE_PERIOD)
{
P1OUT &= ~0x01;
wdt_counter = 0;
}
}


По миганию светика частоту и определяю. На кварце всегда 32,768 (это осциллографом смотрю).

Цитата(rezident @ May 26 2014, 19:06) *
В процессе стирания кроме основной памяти вы стираете и область INFO, где хранятся калибровочные данные для DCO


Это вряд ли, точнее даже если они и потрутся, у меня таймер запущен от кварцевого генератора, а не от DCO.

Цитата(rezident @ May 26 2014, 19:06) *
Для контроля частоты кварца выведите ACLK на пин P1.0 и проконтролируйте частоту.

При коротком фронте - 32К, при длинном - 4К... Чего то я не понимаю.
113
Заработало. Добавил задержку в начале программы:
CODE
//=========main fuction
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer

_delay(66000); //~1 sec

//=====System Clock
DCOCTL = CALDCO_16MHZ; // Set DCO to 16MHz
BCSCTL1 = CALBC1_16MHZ; // MCLC = SMCLK = DCOCLK = 16MHz
BCSCTL1 &= ~0x40; //Low-frequency mode
BCSCTL1 &= ~0x30; //Divider for ACLK = 1


Теперь обе платы работают идентично. Похоже кварц не успевал заводиться, и поэтому проблемы были.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.