Страница 1 из 1

MP430 TImerA0 compare mode простой вопрос

Добавлено: Вт дек 24, 2013 13:43:16
dzrkot
Здравствуйте, это снова я с вопросом по любимому msp430f5435

Настроил работу таймера на режим сравнения (compare), возник вопрос, если я хочу реалзовать несколько прерываний на основе TA0CCR1 - TA0CC5R(к примеру, мне просто для понимания)
ну т.е. 4 прерывания, в даташите под них выделен 1 обработчик перываний. Я правильно понимаю что мне надо в 1 обработчике вызывать if() или switch() и выполнять условия по флагам (CCIFG), и если в конце не сбросить этот флаг т.е. к примеру TA0CCTL1&=(~CCIFG) , то в след раз это прерывание не не сработает?(я думал что по переполнению таймера 0xffff всё скидывается, но видимо это не так...) Это те выводы к которым я пришёл на практике, просто мб я не прав в чём-то..
Заранее спасибо:)

Re: MP430 TImerA0 compare mode простой вопрос

Добавлено: Вт дек 24, 2013 14:11:08
BCluster
Выводы правильные, только if() использовать не надо, он медленный.
switch(), и __even_in_range использовать.

Re: MP430 TImerA0 compare mode простой вопрос

Добавлено: Вт дек 24, 2013 14:37:02
dzrkot
Спасибо, в inrinsics нашёл эту функцию
код будет выглядеть примерно так?

Код: Выделить всё

switch(__even_in_range(TA0IV, 12)) // 1 аргумент - регистр прерываний , 2 аргумент - диапазон значений?сумма используемых адресов в регистреTA0IV в десятичной сист??)
{
case 0x02:
// для TA0CCR1
break;
case 0x04:
// для TA0CCR2
break;
case 0x06:
// для TA0CCR3
break;
}

Re: MP430 TImerA0 compare mode простой вопрос

Добавлено: Вт дек 24, 2013 14:45:32
dzrkot
да, вот так всё работает

Код: Выделить всё

#pragma vector = TIMER0_A1_VECTOR //TIMER0_A0_VECTOR
__interrupt void TIMER_A0(void)                                                 // прерывание по флагу TA0CCR0 CCIFG0
{
    blinkCounter++;
switch(__even_in_range(TA0IV, 12)) 
{
    case 0x02:
              if (blinkCounter==100)
              P1OUT |= 0xA0;    
         TA0CCTL2^=CCIFG;
    break;
    case 0x04:
              if (blinkCounter==200)
              {
              P1OUT &= 0x5F;   
              blinkCounter=0;
              }
        TA0CCTL1^=CCIFG;
    break;
}
}

Re: MP430 TImerA0 compare mode простой вопрос

Добавлено: Вт дек 24, 2013 15:18:32
BCluster
Да, второй аргумент это верхняя граница диапазона. Т.е. в вашем случае от 0 до 12.

Re: MP430 TImerA0 compare mode простой вопрос

Добавлено: Вт дек 24, 2013 15:34:22
dzrkot
такой вопрос возник, а как мне обнулить счётчик, т.е. вернуться после if() в case 0x04, чтобы не считать до конца счётчика т.е. до 0xffff

Код: Выделить всё

#pragma vector = TIMER0_A1_VECTOR //TIMER0_A0_VECTOR
__interrupt void TIMER_A0(void)                                                 // прерывание по флагу TA0CCR0 CCIFG0
{
blinkCounter++;
switch(__even_in_range(TA0IV, 12)) 
{
    case 0x02:
              if (blinkCounter==10)
              P1OUT |= 0xA0;    
         TA0CCTL1^=CCIFG;
    break;
    case 0x04:
              if (blinkCounter==20)
              {
              P1OUT &= 0x5F;   
              blinkCounter=0;
              // как мне скинуть счётчик в 0? если пишу TA0R=0x0000; то зависаю
              }
        TA0CCTL2^=CCIFG;
}

}
как вариант только сделать CA0CCTL0 последним счётчиком и выбрать режим UpMode , но можно ли как-нибудь иначе? ...это любопытство опять таки))
пробовал TA0R=0x0000; -ничего хорошего не принесло

Re: MP430 TImerA0 compare mode простой вопрос

Добавлено: Вт дек 24, 2013 21:18:40
Ser60
Еще можно после обработки последнего по времени захвата пересчитывать времена захвата следующих событий путем добавки к ним текущего значения счетчика таймера.

Флаг события с наибольшим приоритетом сбрасывается автоматически при каждом обращении к регистру TAIV.

Модераторы - пора-бы уже создать отдельный форум по MSP430.