Суть проблемы: имеется устройство с питанием от сети и возможностью питания от батарейки. При нарастании (или определенном постоянном уровне) напряжения на входе стабилизатора ток потребления микроконтроллера в режие LPM3 увеличивается, а затем снижается. Все бы ничего, но напряжение просаживается на 0,2В. Возможно из-за этого устройство иногда не выходит из спячки. Да и работа модуля SVS микроконтроллера при напряжении менее 2,5В может быть нестабильна.
Коллеги! К подскажет, в чем может быть дело? Я ничего не понимаю!



На схеме указал точки замера напряжений. Синий луч показывает увеличение тока потребления (напряжение на резисторе 1кОм инвертировано).
Помогите, пожалуйста!
Код
const unsigned char Key1 = 0x04;
const unsigned char cSWON = 0x02;
const unsigned char PJ = 0x04;
const unsigned char cLED = 0x20;
const unsigned char cTM = 0x02;
const unsigned char cRW = 0x01;
__task void main (void);
int __low_level_init (void)
{
/* Insert your low-level initializations here */
/*============================================*/
/* Choose if segment initialization */
/* should be done or not. */
/* Return: 0 to omit initialization */
/* Return: 1 to run initialization */
/*============================================*/
// Stop WDT
WDTCTL = WDTPW + WDTHOLD;
// Если возвращаемый параметр =1, то вся память RAM обнуляется, иначе - нет.
return (1);
}
// TimerA Interrupt Routine
#pragma vector = TIMERA0_VECTOR
__interrupt void TimerA0_ISR (void)
{
if ((LCDCTL & LCDON) == 0)
{
SVSCTL = 0x0F0;
}
// Часы
.....
//
if ((LCDCTL & LCDON) == 0)
{
// Выход из энергосбережения
_BIC_SR_IRQ (LPM3_bits); // Clear LPM3 bits from 0(SR)
}
}
// Bsic Timer 2 interrupt service routine
#pragma vector = BASICTIMER_VECTOR
__interrupt void basic_timer_isr (void)
{
.....
.....
.....
SVSConrol ();
}
void SVSConrol (void)
{
if ((SVSCTL & SVSOP) == SVSOP) // Если сработал супервизор, то уход в спячку
{
if ((ESPCTL & ESPEN) == ESPEN)
{
// Stop measurement (set Embedded Signal Processing into "Idle" mode)
// Set Embedded Signal Processing into "Idle" mode
set_esp_idle ();
SD16CTL = (SD16LP + SD16DIV0 + SD16DIV1 + SD16SSEL0 + SD16SSEL1);
}
// Disable USART interrupt
IE1 &= ~(URXIE0);
// Disabled USART0 TXD/RXD
U0ME &= ~(UTXE0 + URXE0);
// Stop Basic Timer
BTCTL = (BTHOLD + BTDIV);
// Запрещаем прерывания от Basic Timer
IE2 &= ~(BTIE);
// LCD OFF
LCDCTL &= ~(LCDON);
// TM OFF
P1DIR = (cLED + cRW);
// СИД ON, RW ON (Подгрузка источника питания - дополнительный гистерезис по питанию для надежного срабатывания супервизора)
P1OUT = (cTM);
// SB1 OFF
P2OUT = 0;
// Разрешаем вложенные прерывания (нас интересуют только от таймера TimerA)
_EINT (); // Enable Interrupts (глобально)
do
{
do
{
SVSCTL = VLDOFF;
while ((SVSCTL & SVSON) == SVSON);
_BIS_SR (LPM3_bits);
_NOP ();
//
SVSCTL = 0x0F0;
while ((SVSCTL & SVSON) != SVSON);
}
while ((SVSCTL & SVSOP) == SVSOP);
// Переинициализация FLL (запускаем для восстановления частоты DCO)
InitFLL ();
}
while ((SVSCTL & SVSOP) == SVSOP); // Повторный контроль для надежности
// Инициализация таймера B (TimerB)
BTCTL = (BTIP2 + BTFRFQ0); // f(LCD) = ACLK / 64 = 512 Hz, f(INTB) = 1024 Hz
// Разрешаем прерывания от Basic Timer
IE2 |= (BTIE);
}
}
void InitFLL (void)
{
SCFI0 = (FLLD_2 | FN_2); // Интегратор системной частоты - 4 МГц
FLL_CTL0 = (DCOPLUS | XCAP18PF); // Регистр управления модулем FLL. DC генератор в диапазон 1.3-12.1 МГц.
SCFQCTL = 63; // Регистр контроля тактирования системы
// Ждем некоторое время для установления частоты DCO
WaitNmks ((signed long) (32768));
}
__task void main (void)
{
InitFLL ();
for (;;)
{
_DINT ();
SVSCTL = 0x0F0;
P1DIR = (cRW + cLED + cTM); // Бит0 - R/W
// Бит1 - ТМ
// Бит5 - LED
P2DIR = (cSWON + 0x010); // Бит1 - SWON
// Бит2 - Key
// Бит4 - TXD
// Бит5 - RXD
P1OUT = (cRW + cLED + cTM);
P2OUT = (cSWON);
P1SEL = 0;
P2SEL = 0x038; // P2.4,5 = USART0 TXD enable, RXD enable
// P2.3 = SVSIN
P1IE = 0; // Disable Port 1 interrupts
P2IE = 0; // Disable Port 2 interrupts
P1IFG = 0; // Clear Port 1 interrupt Flags
P2IFG = 0; // Clear Port 2 interrupt Flags
// Конфигурирование LCD контроллера
LCDCTL = (LCDON + LCD4MUX + LCDP1 + LCDP0); // LCD config : Duty = 1/4, Bias = 1/3
// Инициализация таймера A (TimerA)
TACTL = (TASSEL0 + MC0);
TACCR0 = 32767; // Период срабатывания таймера А
TACCTL0 = (CCIE);
// Инициализация таймера B (TimerB)
BTCTL = (BTIP2 + BTFRFQ0); // f(LCD) = ACLK / 64 = 512 Hz, f(INTB) = 1024 Hz
IE2 |= (BTIE); // Разрешаем прерывания от Basic Timer
// Enable Interrupts (глобально)
_EINT ();
while (...) // Цикл выполняется пока не разрешен перезапуск системы
{
.....
.....
.....
.....
}
}
}
const unsigned char cSWON = 0x02;
const unsigned char PJ = 0x04;
const unsigned char cLED = 0x20;
const unsigned char cTM = 0x02;
const unsigned char cRW = 0x01;
__task void main (void);
int __low_level_init (void)
{
/* Insert your low-level initializations here */
/*============================================*/
/* Choose if segment initialization */
/* should be done or not. */
/* Return: 0 to omit initialization */
/* Return: 1 to run initialization */
/*============================================*/
// Stop WDT
WDTCTL = WDTPW + WDTHOLD;
// Если возвращаемый параметр =1, то вся память RAM обнуляется, иначе - нет.
return (1);
}
// TimerA Interrupt Routine
#pragma vector = TIMERA0_VECTOR
__interrupt void TimerA0_ISR (void)
{
if ((LCDCTL & LCDON) == 0)
{
SVSCTL = 0x0F0;
}
// Часы
.....
//
if ((LCDCTL & LCDON) == 0)
{
// Выход из энергосбережения
_BIC_SR_IRQ (LPM3_bits); // Clear LPM3 bits from 0(SR)
}
}
// Bsic Timer 2 interrupt service routine
#pragma vector = BASICTIMER_VECTOR
__interrupt void basic_timer_isr (void)
{
.....
.....
.....
SVSConrol ();
}
void SVSConrol (void)
{
if ((SVSCTL & SVSOP) == SVSOP) // Если сработал супервизор, то уход в спячку
{
if ((ESPCTL & ESPEN) == ESPEN)
{
// Stop measurement (set Embedded Signal Processing into "Idle" mode)
// Set Embedded Signal Processing into "Idle" mode
set_esp_idle ();
SD16CTL = (SD16LP + SD16DIV0 + SD16DIV1 + SD16SSEL0 + SD16SSEL1);
}
// Disable USART interrupt
IE1 &= ~(URXIE0);
// Disabled USART0 TXD/RXD
U0ME &= ~(UTXE0 + URXE0);
// Stop Basic Timer
BTCTL = (BTHOLD + BTDIV);
// Запрещаем прерывания от Basic Timer
IE2 &= ~(BTIE);
// LCD OFF
LCDCTL &= ~(LCDON);
// TM OFF
P1DIR = (cLED + cRW);
// СИД ON, RW ON (Подгрузка источника питания - дополнительный гистерезис по питанию для надежного срабатывания супервизора)
P1OUT = (cTM);
// SB1 OFF
P2OUT = 0;
// Разрешаем вложенные прерывания (нас интересуют только от таймера TimerA)
_EINT (); // Enable Interrupts (глобально)
do
{
do
{
SVSCTL = VLDOFF;
while ((SVSCTL & SVSON) == SVSON);
_BIS_SR (LPM3_bits);
_NOP ();
//
SVSCTL = 0x0F0;
while ((SVSCTL & SVSON) != SVSON);
}
while ((SVSCTL & SVSOP) == SVSOP);
// Переинициализация FLL (запускаем для восстановления частоты DCO)
InitFLL ();
}
while ((SVSCTL & SVSOP) == SVSOP); // Повторный контроль для надежности
// Инициализация таймера B (TimerB)
BTCTL = (BTIP2 + BTFRFQ0); // f(LCD) = ACLK / 64 = 512 Hz, f(INTB) = 1024 Hz
// Разрешаем прерывания от Basic Timer
IE2 |= (BTIE);
}
}
void InitFLL (void)
{
SCFI0 = (FLLD_2 | FN_2); // Интегратор системной частоты - 4 МГц
FLL_CTL0 = (DCOPLUS | XCAP18PF); // Регистр управления модулем FLL. DC генератор в диапазон 1.3-12.1 МГц.
SCFQCTL = 63; // Регистр контроля тактирования системы
// Ждем некоторое время для установления частоты DCO
WaitNmks ((signed long) (32768));
}
__task void main (void)
{
InitFLL ();
for (;;)
{
_DINT ();
SVSCTL = 0x0F0;
P1DIR = (cRW + cLED + cTM); // Бит0 - R/W
// Бит1 - ТМ
// Бит5 - LED
P2DIR = (cSWON + 0x010); // Бит1 - SWON
// Бит2 - Key
// Бит4 - TXD
// Бит5 - RXD
P1OUT = (cRW + cLED + cTM);
P2OUT = (cSWON);
P1SEL = 0;
P2SEL = 0x038; // P2.4,5 = USART0 TXD enable, RXD enable
// P2.3 = SVSIN
P1IE = 0; // Disable Port 1 interrupts
P2IE = 0; // Disable Port 2 interrupts
P1IFG = 0; // Clear Port 1 interrupt Flags
P2IFG = 0; // Clear Port 2 interrupt Flags
// Конфигурирование LCD контроллера
LCDCTL = (LCDON + LCD4MUX + LCDP1 + LCDP0); // LCD config : Duty = 1/4, Bias = 1/3
// Инициализация таймера A (TimerA)
TACTL = (TASSEL0 + MC0);
TACCR0 = 32767; // Период срабатывания таймера А
TACCTL0 = (CCIE);
// Инициализация таймера B (TimerB)
BTCTL = (BTIP2 + BTFRFQ0); // f(LCD) = ACLK / 64 = 512 Hz, f(INTB) = 1024 Hz
IE2 |= (BTIE); // Разрешаем прерывания от Basic Timer
// Enable Interrupts (глобально)
_EINT ();
while (...) // Цикл выполняется пока не разрешен перезапуск системы
{
.....
.....
.....
.....
}
}
}