Код
// P1.0 - OUTA Энкодер А
// P1.1 - OUTB Энкодер B
// P1.2 - Выход ШИМ
// P1.3 - Выход направления
// P1.4 - Выбор микросхемы SPI
// P1.5 - Синхросигнал SPI
// P1.6 - Данные SPI
#include <msp430x20x2.h>
unsigned int cnt = 0; // Переменная счетчик
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Чтобы не мешал Watchdog
BCSCTL1 = CALBC1_16MHZ; // Устанавливаем DCO 16MHz
DCOCTL = CALDCO_16MHZ; // Устанавливаем DCO 16MHz
// Настройка портов I/O
P1DIR &= ~0x02; // P1.0, P1.1 на вход
P1DIR |= 0x08; //P1.3 на выход
P1IE |= 0x02; // P1.1 вкл. прерывания
P1IES &= ~0x02; // P1.1 Передний фронт
P1IFG &= ~0x02; // P1.1 сбросить флаг прерывания
// Настройка таймера
P1SEL |= 0x04; // P1.3 вкл. функции переферии
P1DIR |= 0x04; // P1.3 на выход
TACCTL1 = OUTMOD_3 + CCIE; // PWM set/reset, interrupt enabled
TACTL = TASSEL_2 + MC_1 + TAIE; // SMCLK, Up to CCR0, interrupt enabled
TACCR0 = 1600;
TACCR1 = 500;
_EINT();
for(;;);
}
// Обработчик прерывания Timer A1
#pragma vector=TIMERA1_VECTOR
__interrupt void Timer_A1 (void)
{
if (TAIV==2) cnt++;
}
#pragma vector=PORT1_VECTOR
__interrupt void Port1_int (void)
{
// Выдаем на P1.3 направление вращения
if (P1IN & BIT1) P1OUT |= BIT3;
else P1OUT &= ~BIT3;
// Меняем планку ШИМ в соответствии со скоростью.
if (cnt<1590) TACCR1 = cnt;
else TACCR1 = 1590;
if (cnt<10) TACCR1 = 10;
cnt = 0;
P1IFG &= ~0x02; // P1.4 IFG cleared
}
// P1.1 - OUTB Энкодер B
// P1.2 - Выход ШИМ
// P1.3 - Выход направления
// P1.4 - Выбор микросхемы SPI
// P1.5 - Синхросигнал SPI
// P1.6 - Данные SPI
#include <msp430x20x2.h>
unsigned int cnt = 0; // Переменная счетчик
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Чтобы не мешал Watchdog
BCSCTL1 = CALBC1_16MHZ; // Устанавливаем DCO 16MHz
DCOCTL = CALDCO_16MHZ; // Устанавливаем DCO 16MHz
// Настройка портов I/O
P1DIR &= ~0x02; // P1.0, P1.1 на вход
P1DIR |= 0x08; //P1.3 на выход
P1IE |= 0x02; // P1.1 вкл. прерывания
P1IES &= ~0x02; // P1.1 Передний фронт
P1IFG &= ~0x02; // P1.1 сбросить флаг прерывания
// Настройка таймера
P1SEL |= 0x04; // P1.3 вкл. функции переферии
P1DIR |= 0x04; // P1.3 на выход
TACCTL1 = OUTMOD_3 + CCIE; // PWM set/reset, interrupt enabled
TACTL = TASSEL_2 + MC_1 + TAIE; // SMCLK, Up to CCR0, interrupt enabled
TACCR0 = 1600;
TACCR1 = 500;
_EINT();
for(;;);
}
// Обработчик прерывания Timer A1
#pragma vector=TIMERA1_VECTOR
__interrupt void Timer_A1 (void)
{
if (TAIV==2) cnt++;
}
#pragma vector=PORT1_VECTOR
__interrupt void Port1_int (void)
{
// Выдаем на P1.3 направление вращения
if (P1IN & BIT1) P1OUT |= BIT3;
else P1OUT &= ~BIT3;
// Меняем планку ШИМ в соответствии со скоростью.
if (cnt<1590) TACCR1 = cnt;
else TACCR1 = 1590;
if (cnt<10) TACCR1 = 10;
cnt = 0;
P1IFG &= ~0x02; // P1.4 IFG cleared
}
Если убрать из обработчика прерывания таймера if (TAIV==2), оставив только cnt++; перестает работать прерывание PORT1. С чем связано такое поведение?
Да и вот еще вопрос, у таймера есть 2 вектора прерывания TIMERA0_VECTOR и TIMERA1_VECTOR в каких случаях работает первый, а в каких второй?