msp 430 нужна помощь

по МК и не только

msp 430 нужна помощь

Сообщение Jukki » 27 авг 2012, 21:43

Добрый день. Хелп, пожалуйста. Микроконтроллер msp430. Среда разработки IAR. Есть три модуля - модуль опроса термодатчиков, модуль записи во flash и модуль связи с внешним устройством(ПК) по modbus. При записи в память (по команде от ПК) происходит запись в память, потом микроконтроллер перезагружается и не успевает выслать ответ.

Сбросы watchdog-ов вроде везде понаставлены.
Размер стека по умолчанию стоит 80. При увеличении стека(до 100) возникают ошибки
Error[Pe136]: struct "<unnamed>" has no field "P4DIR_0"
Error[Pe136]: struct "<unnamed>" has no field "P4SEL_0"
Error[Pe136]: struct "<unnamed>" has no field "P4OUT_0"
Error[Pe136]: struct "<unnamed>" has no field "P4OUT_0"

в одном из модулей объявлено
#define P_RTENB_IN P4IN_bit.P4IN_0
#define P_RTENB_OUT P4OUT_bit.P4OUT_0
#define P_RTENB_DIR P4DIR_bit.P4DIR_0
#define P_RTENB_SEL P4SEL_bit.P4SEL_0
я не знаю, как избежать этих эрроров.

main.c :
...
while (1) { //main loop, never ends.
wdgRst();
recieveModbus(deviceAddress, mes); // прием команды с ПК
wdgRst();
switch (mes->cmd) { // mes->cmd - команда
...
case write_single_register:
if (mes->startAddr >=0x2001 && mes->startAddr <= 0x200A)
{
flashWrite(&intialSettings.term.filterTime[num],
&mes->value,
sizeof(mes->value));
}
...
transmitModbus(mes,deviceAddress); // передача ответа
...

------------------------------------------------------------------------------------------------------------------------------------
flash.c:

__ramfunc void flashEraseSeg (const void *segPtr)
{
unsigned int old_wdt = WDTCTL & 0x00ff;;
WDTCTL = WDTPW + WDTHOLD;

__disable_interrupt();

while(BUSY&FCTL3); // i?iaa?ea BUSY
FCTL2=FWKEY|FSSEL_0|FN2|FN4; // Clock = ACLK/20
FCTL3=FWKEY; // Lock = 0
FCTL1=FWKEY|ERASE; // ERASE = 1
*(char *)segPtr = 0; // Oeeoeaiay caienu
while(BUSY&FCTL3); // i?iaa?ea BUSY
FCTL1=FWKEY; // ERASE = 0
FCTL3=FWKEY|LOCK; // Lock = 1

WDTCTL = WDTPW + old_wdt;
__enable_interrupt();
}

__ramfunc int flashWrite (const void *flashAdr, void *data, int size)
{
unsigned int startAdr = ((int)flashAdr & 0xff80);
unsigned char adr = (int)flashAdr - startAdr;

if(adr + size > SEG_LEN)
return -1;

unsigned char i, offset;
char buf[SEG_LEN];

memcpy(buf, (void *)startAdr, SEG_LEN); // Neiie?iaaou ec naaiaioa a aooa?
flashEraseSeg((void *)startAdr);

memcpy (buf+adr, data, size);

// Caienu aeieia
unsigned int old_wdt = WDTCTL & 0x00ff;;
WDTCTL = WDTPW + WDTHOLD;

__disable_interrupt();

while(BUSY&FCTL3); // i?iaa?ea BUSY

FCTL2=FWKEY|FSSEL_0|FN2|FN4; // Clock = ACLK/20
FCTL3=FWKEY; // Lock = 0

for(offset = 0; offset < SEG_LEN; offset += BLOCK_LEN)
{
FCTL1=FWKEY|WRT|BLKWRT; // WRT = BLKWRT = 1

for(i = 0; i < BLOCK_LEN; i++)
{
// Caienu neiaa
*((char *)startAdr + offset + i) = buf[offset + i];
while(!(WAIT&FCTL3)); // i?iaa?ea WAIT
}

FCTL1=FWKEY; // WRT = BLKWRT = 0
while(BUSY&FCTL3); // i?iaa?ea BUSY
}

FCTL3=FWKEY|LOCK; // Lock = 1



WDTCTL = WDTPW | old_wdt;

wdgRst();
__enable_interrupt();

wdgRst();
if(memcmp((void *)startAdr, buf, SEG_LEN)) // здесь и происходит сброс мк
return -1;

wdgRst();

return size;
}


При замене (memcmp((void *)startAdr, buf, SEG_LEN) на
const char *dst = (const char *) startAdr;
char *src = (char *) buf;
for(int i = 0; i < SEG_LEN; ++i)
{
wdgRst();
if(src[i] != dst[i])
break;
}
проблема не исчезает.



Периодически идет прерывание от таймера А (модуль опроса термодатчиков)

#pragma vector=TIMERA1_VECTOR
__interrupt static void isr_TACCR0() // Обработчик прерывания Timer A
{
TACTL &= ~TAIFG; // Запрета прерываний

static Tstate state = discharge;
static int num = 0;

switch(state)
{

case charge:

if((TACCTL0 & CCIFG) && !TERCOMMPIN) // Проверка разрядки
{
if(term[num].counter > 0) // Задержка при аварии
--term[num].counter;

term[num].cur_term = TACCR0; // Зафиксировать время разрядки
TACCTL0 &= ~CCIFG;

if(!term[num].counter) // Установка статуса после выхода из аварии
tdata[num].status = norm;

if(term[num].cur_term < T_KZ) // Проверка на КЗ
{
term[num].counter = COUNTER_CONST; // Ввести задержку
tdata[num].status = kz;
tdata[num].term = KZ;
}
else
{
// Вычисление занчения т-ры
if(num && (term[0].counter < COUNTER_CONST))
{
float Rterm = (float) term[num].cur_term / term[0].cur_term * R_REF;
tdata[num].rt = A*Rterm + B;
float temp = A2*Rterm*Rterm +A1*Rterm + A0;

// Инициализация фильтра
if (term[num].counter == COUNTER_CONST-1)
{
tdata[num].term = temp;

if (tdata[num].term < T_MIN) // Инициализация зоны
tdata[num].zone = low;
else
if (tdata[num].term > T_MAX)
tdata[num].zone = high;
else
tdata[num].zone = norm;
}
else
{
// Фильтрация
tdata[num].term = (K*tdata[num].term + temp)/(K + 1);

// Гистерезис
switch (tdata[num].zone)
{
case low:
if (tdata[num].term > T_MAX + DELTA_T)
tdata[num].zone = high;
else
if (tdata[num].term > T_MIN + DELTA_T)
tdata[num].zone = norm;
break;

case norm:
if (tdata[num].term < T_MIN - DELTA_T)
tdata[num].zone = low;
else
if (tdata[num].term > T_MAX + DELTA_T)
tdata[num].zone = high;
break;

case high:
if (tdata[num].term < T_MIN - DELTA_T)
tdata[num].zone = low;
else
if (tdata[num].term < T_MAX - DELTA_T)
tdata[num].zone = norm;
break;
} // switch(zone)
} // else
} // if(num && (term[0].counter < COUNTER_CONST))
} // else KZ
} // if((TACCTL0 & CCIFG) && !TERCOMMPIN)
else
{
term[num].counter = COUNTER_CONST; // Задержка при обрыве
tdata[num].status = obryv;
tdata[num].term = OBRYV;
}

// Настройка Term[num] на вход
term[num].reg->pdir &= ~term[num].mask;

if (++num == TERM_COUNT) // Проверка кол-ва проверенных термодатчиков
num = 0;

// Настройка Term[num] на выход
term[num].reg->pdir |= term[num].mask;

// Зарядка кондера от Term[num]
term[num].reg->pout |= term[num].mask;

state = discharge;
break;

case discharge:

if (!TERCOMMPIN) // Проверка на ошибку зарядки
{
term[num].counter = COUNTER_CONST; // Задержка при обрыве
// term[num].cur_term = 0xffff;
}
else
// Разрядка кондера
term[num].reg->pout &= ~term[num].mask;

state = charge;
break;
}
}


Добрые люди, помогите, пожалуйста, кто чем может! ;)
Jukki
 
Сообщения: 2
Зарегистрирован: 27 авг 2012, 09:32

Re: msp 430 нужна помощь

Сообщение Jukki » 28 авг 2012, 09:01

C ошибками типа Error[Pe136]: struct "<unnamed>" has no field "P4DIR_0" все выяснилось - возникли из-за пересборки проекта в другой версии IAR :)
Jukki
 
Сообщения: 2
Зарегистрирован: 27 авг 2012, 09:32


Вернуться в Общие вопросы



Кто сейчас на конференции

Зарегистрированные пользователи: Yahoo [Bot]