113 3 26 мая, 2014 Опубликовано 26 мая, 2014 · Жалоба Суть: Проц 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 0 26 мая, 2014 Опубликовано 26 мая, 2014 · Жалоба После некоторого количества перепрошивок (отлаживаю), частота интервалов увеличивается в 8 раз. ~skip~ Что может быть причиной такого поведения? Как вариант. В процессе стирания кроме основной памяти вы стираете и область INFO, где хранятся калибровочные данные для DCO. Может эта частота где-то в вашей программе используется? Как вы проверяете частоту WDT? Для контроля частоты кварца выведите ACLK на пин P1.0 и проконтролируйте частоту. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
113 3 27 мая, 2014 Опубликовано 27 мая, 2014 (изменено) · Жалоба Заметил, что при включении от БП плата заводится, а если проводами коммутировать - нет. Посмотрел: у БП фронт ~2 мс, а при коммутации проводами резкий выброс до 4 В, а потом спад до 3,2. На питание стоит LM317. Емкости все на месте. Впаял 10 Ом между LM317 и MSP - выброс пропал, фронт стал ~500 мкс при коммутации проводами. Теперь заводится и включением БП и коммутацией проводов, НО: при включении от блока (длинный фронт) частота срабатывания = номинальная*8 (см. первый пост), а при старте от коммутации проводов (короткий фронт) частота срабатывания еще выше (номинальная*8*8). Похоже что проц не выдержал бросков до 4В (может и чуть больше было во время испытаний "в поле"), и как следствие так странно сейчас себя ведет? Код на всякий случай (мигает светиком): //****************************************************************************** #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 (это осциллографом смотрю). В процессе стирания кроме основной памяти вы стираете и область INFO, где хранятся калибровочные данные для DCO Это вряд ли, точнее даже если они и потрутся, у меня таймер запущен от кварцевого генератора, а не от DCO. Для контроля частоты кварца выведите ACLK на пин P1.0 и проконтролируйте частоту. При коротком фронте - 32К, при длинном - 4К... Чего то я не понимаю. Изменено 27 мая, 2014 пользователем 113 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
113 3 27 мая, 2014 Опубликовано 27 мая, 2014 · Жалоба Заработало. Добавил задержку в начале программы: //=========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 Теперь обе платы работают идентично. Похоже кварц не успевал заводиться, и поэтому проблемы были. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться