Рискну предложить свой "перелопаченный" вариант вашей тестовой программы.
CODE
#include <msp430g2452.h>
unsigned char digits[]=
{
0xBE, //0
0x84, //1
0xAB, //2
0xA7, //3
0x95, //4
0x37, //5
0x3F, //6
0xA4, //7
0xBF, //8
0xB7, //9
};
#define SYS_VALMCLKL 16000000UL //частота MCLK
#define SYS_VALSMCLK 2000000UL //частота SMCLK
#define SYS_VALACLK 12000UL //частота ACLK
/* биты управления разрядами индикатора */
#define SEG7_DIG1 (1U<<5)
#define SEG7_DIG2 (1U<<4)
#define SEG7_DIG3 (1U<<3)
#define SEG7_DIG4 (1U<<2)
/* маска битов управления разрядами */
#define SEG7_MASKDIG (SEG7_DIG1|SEG7_DIG2|SEG7_DIG3|SEG7_DIG4)
#define SEG7_MAXNUM 4 //количество разрядов индикатора
#define SEG7_REFRESH_MS 5UL //период динамической индикации [мс]
#define SYSTICKMS_ADD 1UL //приращение счетчика системных тиков [мс]
volatile unsigned int sysTickMS; //счетчик мс
unsigned char seg7_buf[4]; //буфер индикатора
unsigned int seg7_num; //номер разряда для текущего отображения
void main( void )
{
unsigned int sysTickMSStamp, time;
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer to prevent time out reset
BCSCTL3 = LFXT1S_2; //ACLK = VLOCLK
BCSCTL1 = CALBC1_16MHZ; //Проц тактируем от встроенного
DCOCTL = CALDCO_16MHZ; //генератора с калибровкой последнего на 16 мгц
BCSCTL2 = DIVM_0 | DIVS_3;//MCLK = DCOCLK, SMCLK = DCOCLK/8
P1DIR |= 0x3C; // P1 output
P2DIR |= 0xFF; // P2 output
//конфиг первого таймера
/* период: ccr0 = SYSTICKMS_ADD * (16МГц/8 / 1000мс) - 1 */
unsigned long tmp = SYS_VALSMCLK;
tmp /= 1000UL;
tmp *= SYSTICKMS_ADD;
TA0CCR0 = (unsigned int)tmp - 1;
TA0CCTL0 = CCIE; //
TACTL = TASSEL_2 | MC_1; // SMCLK, upmode
/* заполним буфер индикатора символами 1, 2, 3, 4
вообще говоря, по-уму нужна отдельная функция,
которая будет выводить строку символов в буфер индикатора
*/
seg7_buf[0] = digits[1];
seg7_buf[1] = digits[2];
seg7_buf[2] = digits[3];
seg7_buf[3] = digits[4];
sysTickMSStamp = sysTickMS; //сделаем отметку времени
__enable_interrupt();
/* main loop - большой цикл */
for(;;)
{ time = sysTickMS;
if ((time - sysTickMSStamp) >= SEG7_REFRESH_MS)
{
/* здесь делаем все, что нужно делать при динамичесй индикации */
seg7_num += 1;
if (seg7_num >= SEG7_MAXNUM) seg7_num = 0;
P1OUT &= ~(SEG7_MASKDIG); //гасим все разряды
P2OUT = seg7_buf[seg7_num]; //выводим значение символа
switch(seg7_num) //зажигаем соответствующий символ индикатора
{
case 0:
P1OUT |= SEG7_DIG1;
break;
case 1:
P1OUT |= SEG7_DIG2;
break;
case 2:
P1OUT |= SEG7_DIG3;
break;
case 3:
P1OUT |= SEG7_DIG4;
break;
}
sysTickMSStamp = sysTickMS; //обновляем значение временной отметки
}
/* не знаю, зачем вам это нужно в тестовой программе, но засыпаем */
__bis_SR_register(LPM0_bits | GIE); // Enter LPM0 w/ interrupt
}/* end main loop - конец большого цикла */
} /* end main */
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer0_A0 (void)
{
sysTickMS += SYSTICKMS_ADD; //увеличиваем счетчик мс
/* поскольку в основном цикле есть переход в режим энергосбережения, то
для того, чтобы большой цикл выполнялся нужно временно выйти из этого режима
*/
__bic_SR_register_on_exit(LPM4_bits);
}
Основные недостатки вашей программы
а) отсутствует big loop, т.е. программа не зацикливается, а перезапускается после одного-единственного прохода
б) в прерывании нужно делать минимум операций и только самые необходимые. Вызов функции обработки динамической индикации можно спокойно перенести в основной цикл. А в прерывании от таймера только увеличивать счетчик времени, который в моей версии считает миллисекунды.
в) судя по именам переменных, замысел такой был, но по факту не реализована буферизация вывода на индикатор. Я бы на вашем месте написал отдельную функцию для вывода в буфер индикатора (отметил это в комментариях).
г) старайтесь избегать "магических" чисел в исходниках. Пользуйтесь именованными константами, определенными с помощью макросов (define) и enum. Будет проще и вам самому и другим людям, которые будут разбираться с вашей программой.
д) рекомендуется поддерживать общепринятый стиль написания программ на Си. Только одними ЗАГЛАВНЫМИ символами принято обозначать макросы. Не стоит такие имена давать переменным. Имена переменным нужно давать осмысленно. Я сначала вообще хотел отдельную структуру для переменных индикатора создать, но потом подумал и ограничился лишь префиксом seg7_.