rezident (15.06.2012 20:07 - 20:21, просмотров: 214) ответил Vit на Вот
Вот такую программу протестировал. #include <msp430f5438a.h>
#include <stdint.h>
#define TA0_10mS (32768UL/100UL-1UL)
#define TA0_100mS (32768UL/10UL-1UL)
#define TA0_1000mS (32768UL/1UL-1UL)
void Timer_A_Init(void)
{
TA0CTL = TASSEL_1 | TACLR;// ACLK, clear TAR
TA0CCR0 = TA0_100mS;
TA0CCTL0 = CCIE; //TA0CCR0 interrupt enabled
TA0CCR1 = TA0_100mS+TA0_100mS; //
TA0CCTL1 = CCIE; //TA0CCR1 interrupt enabled
TA0CCR2 = TA0_100mS+TA0_100mS+TA0_100mS; //
TA0CCTL2 = CCIE; //TA0CCR2 interrupt enabled
TA0CCR3 = TA0_100mS+TA0_100mS+TA0_100mS+TA0_100mS; //
TA0CCTL3 = CCIE; //TA0CCR3 interrupt enabled
TA0CCR4 = TA0_100mS+TA0_100mS+TA0_100mS+TA0_100mS+TA0_100mS; //
TA0CCTL4 = CCIE; //TA0CCR4 interrupt enabled
TA0CTL |= MC_2 | TAIE;// ACLK, Cntinuous mode, overflow int - enable
}
volatile uint16_t tmp_taiv0, tmp_taiv1, soft_en;
void main (void)
{ volatile uint32_t cntr;
uint16_t reg_int=0;
WDTCTL = WDTPW + WDTHOLD;
Timer_A_Init();
for(;;)
{ tmp_taiv0 = tmp_taiv1 = 77;
if (soft_en != 0)
{ switch(reg_int)
{ case 1:
TA0CCTL0 |= CCIFG;
reg_int = 2;
break;
case 2:
TA0CCTL1 |= CCIFG;
reg_int = 3;
break;
case 3:
TA0CCTL2 |= CCIFG;
reg_int = 4;
break;
case 4:
TA0CCTL3 |= CCIFG;
reg_int = 5;
break;
case 5:
TA0CCTL4 |= CCIFG;
reg_int = 1;
break;
default:
reg_int=1;
break;
}
tmp_taiv0 = TA0IV;
}
// for (cntr=100000UL; cntr>0; cntr--);
__no_operation();
}
}
#pragma vector=TIMER0_A0_VECTOR
#pragma type_attribute=__interrupt
void TIMER0_A0_ISR (void)
{ //tmp_taiv0=TA0IV;
__no_operation();
}
#pragma vector=TIMER0_A1_VECTOR
#pragma type_attribute=__interrupt
void TIMER0_A1_ISR (void)
{ tmp_taiv1=TA0IV;
__no_operation();
}
В окне регистров TA0IV (практически) всегда как 0x0000 читается.
Если в дебаггере разрешить GIE и установить два breakpoint по одному в каждом обработчике прерывания, то попадаем в прерывания и в tmp_taiv1 последовательно принимает значения 77, 2, 4, 6, 8, 14, 77, 2, 4, 6, ... tmp_taiv0=77 постоянно.
Если запретить GIE, установить breakpoint на __no_operation() в теле main и изменить в дебаггере soft_en = 1, то tmp_taiv1 = 77, а tmp_taiv0 принимает значения 0, 2, 4, 6, 8, 0, 2, 4, 6, 8 .... Значение 14 тоже появляется, но только один раз за 65536 тактов TA0R.
Если в дебаггере изменить (сбросить) CCIE в любом из регистров CCTLx, то соответствующий вектор в TA0IV не появляется и среди значений визуализированных в tmp_taiv0 (tmp_taiv1) его тоже нет.
Резюме. Все вполне согласуется с логикой работы таймера, описанной в User's Guide. Или я так и не допер сути возникшей у вас проблемы.
P.S. тестировал в новой версии IAR EW430 5.40.7, которую сегодня анонсировала Ксения.