MSP430G2553 Интервалы таймера [закрыто]

Прочитав текст около пяти раз и погуглив, я решил обратиться за помощью. В настоящее время я использую прерывание Timer_A для включения / выключения двух светодиодов с интервалами 1 секунда / 10 секунд / 1 минута по одному. Программа по умолчанию будет включать / выключать светодиоды каждую секунду, но я не могу найти способ выключить их через 10 секунд и минуту. Я могу использовать __delay_cycles (xxxx) для достижения этой цели, но, видимо, это приведет к потере цели таймера. Это мой код

#include <msp430.h>

#define RedLED BIT0
#define GreenLED BIT6

#define RedLEDToggle (P1OUT ^= RedLED)
#define GreenLEDToggle (P1OUT ^= GreenLED)

unsigned int counter = 0;


void main(void)
{
    WDTCTL = WDTPW | WDTHOLD;
    //WDTCTL = WDT_MDLY_32;

    P1DIR = RedLED | GreenLED;
    P1OUT = RedLED | GreenLED;

    TACTL = TASSEL_2 | ID_3 | MC_3 | TAIE;

    TACCR0 = 62500;

    _enable_interrupts();


    LPM1;
}

#pragma vector=TIMER0_A1_VECTOR

__interrupt void Timer_A(void)
{

if ( counter == 10)
{
switch (TAIV)
    {
    case 0x02: break;
    case 0x04: break;
    case 0x0A: RedLEDToggle | GreenLEDToggle;
        break;
    }
}
else
{
counter ++;
}       
}
 too honest for this site17 июл. 2016 г., 23:44
@ machine_1: не могли бы вы прекратить добавлять несвязанные теги, которые я уже удалил?
 machine_118 июл. 2016 г., 00:12
@ Олаф, что заставляет тебя думать, что я добавил теги? Я только улучшил форматирование ...
 CL.18 июл. 2016 г., 00:19
Отредактируйте свой вопрос, чтобы показать код со счетчиком.
 too honest for this site17 июл. 2016 г., 22:58
О, и ... в чем был вопрос?
 too honest for this site18 июл. 2016 г., 00:19
 too honest for this site17 июл. 2016 г., 22:58
Не спам теги! Это определенно не связано сCSS и нет ассемблера в вашем коде.
 Jester17 июл. 2016 г., 23:09
Увеличить счетчик и делать свои вещи, когда он достигает 10? Предполагая, что вы не хотите перепрограммировать таймер, то есть.
 TheJr17 июл. 2016 г., 23:07
Извините извините. Вопрос в том, как мне отредактировать эту программу для достижения 10-секундного интервала? Если я знаю это, я уверен, что могу кодировать 1 минуту и ​​четвертую.
 TheJr17 июл. 2016 г., 23:13
Спасибо за ответ. Я попытался использовать unsigned int counter = 0 для увеличения и переключения светодиодов после того, как он достиг 120 или 240, но секунды не изменились.
 TheJr18 июл. 2016 г., 00:39
@CL. Готово. Я установил другие значения, но все они привели к тому же 1-секундному интервалу по умолчанию.
 too honest for this site17 июл. 2016 г., 23:15
Слишком широк. Извините, но это не сайт по кодированию / обучению. Пожалуйста, укажитеконкретный проблема. Что не работает с кодом? УвидетьКак спросить, Сначала вам, очевидно, нужна частота используемого генератора, затем установите период таймера соответственно. Обратите внимание, что хорошей практикой является отключение каналов, не используемых в обработчике прерываний, если они запускаются случайно. (защитное программирование, защита).

Ответы на вопрос(3)

 TAIV

 определяет полные утверждения; Вы не должны рассматривать их как выражения, комбинируя их сXxxLEDToggleОбработчик прерываний может быть вызван из нескольких источников. На данный момент ваша программа не включает никаких других, но это, вероятно, изменится, поэтому вы должны запускать свой специфичный для TAIFG код только тогда, когда TAIFG действительно был установлен.|.

Как только вы достигли предела, вам нужно сбросить счетчик обратно на ноль.

Когда у вас есть несколько интервалов таймера, вам нужно несколько счетчиков. В противном случае при первом сбросе счет будет сброшен для всех интервалов.

Вам нужно что-то вроде этого:

MSP430G2553 Интервалы таймера [закрыто]

static unsigned int counter_10 = 0;
static unsigned int counter_60 = 0;

#pragma vector=TIMER0_A1_VECTOR
static __interrupt void Timer_A0(void)
{
    switch (TA0IV) {
    case TA0IV_TACCR1: break;
    case TA0IV_TACCR2: break;
    case TA0IV_TAIFG:
        if (++counter_10 >= 10) {
            counter_10 = 0;
            RedLEDToggle;
        }
        if (++counter_60 >= 60) {
            counter_60 = 0;
            GreenLEDToggle;
        }
        break;
    }
}
Решение Вопроса

вам нужно применить входной делитель к таймеру. Невозможно достичь 1 минуты без поддержки периферийных устройств (см. Другие ответы о том, как реализовать это с помощью программного счетчика).

Проблема заключается в том, что микроконтроллеры msp430 имеют 16-разрядные регистры, не способные хранить числовые значения, превышающие 65535. Использование низкочастотного генератора, работающего на частоте 32768 Гц (как обычно - вы не предоставляете никаких подробностей об аппаратных источниках синхронизации вашего Если система имеет другую частоту, пожалуйста, отметьте, что) регистр переполняется каждые 2 секунды, если не применяется входной делитель. Максимальное значение делителя входа на микроконтроллерах семейства MSP430x2xxx составляет 8, поэтому в будущем аппаратный таймер невозможно установить более чем на 8 * 2 = 16 секунд. Ссылаться наРуководство пользователя семейства MSP430x2xxx для дальнейших деталей.

Этот код вызывает прерывание один раз в 10 секунд:

#include <msp430.h>

#define RedLED BIT0
#define GreenLED BIT6

#define RedLEDToggle (P1OUT ^= RedLED)
#define GreenLEDToggle (P1OUT ^= GreenLED)

// 10 seconds, assuming 32768 Hz ACLK source and divider 8
#define TIMER_PERIOD (10u * (32768 / 8))

void main(void)
{
    WDTCTL = WDTPW | WDTHOLD;

    P1DIR = RedLED | GreenLED;
    P1OUT = RedLED | GreenLED;

    // reset timer A config (not strictly needed)
    TACTL = TACLR;

    // ACLK as clock source, divider 8, continuous mode, interrupt enabled
    TACTL = TASSEL_1 | ID_3 | MC_2 | TAIE;

    // set the period
    TACCR1 = TIMER_PERIOD;

    // enable capture/compare interrupts for CCR1
    TACCTL1 = CCIE;

    _enable_interrupts();

    LPM1;
}

#pragma vector=TIMER0_A1_VECTOR

__interrupt void Timer_A(void)
{
    switch (TAIV) {
    case 0x02:
        // CCR1 interrupt
        RedLEDToggle;
        GreenLEDToggle;
        // set the time of the next interrupt
        TACCR1 += TIMER_PERIOD;
        break;
    }
}
 user362924919 июл. 2016 г., 22:51
Примечание: MSP430 (IIRC) не позволяет напрямую манипулировать битами ввода / вывода через^=Таким образом, вы должны сохранить «образ» порта ввода / вывода в памяти, манипулировать этим образом, а затем записать весь порт из этого образа.

У вас есть 1 секундный таймер, который вызывает прерывание каждую 1 секунду.

Ваши другие времена кратны этой 1 секунде.

Итак, в начале вашей программы установите 10-секундный счетчик на 0 и установите 1-минутный счетчик на 0.

При каждом 1-секундном прерывании увеличивайте оба счетчика.

Каждый раз 10 секундный счетчик переходит с 9 на 10

сбросить счетчик на 0

обработать 10 секунд деятельностиКаждый раз 1-минутный счетчик переходит с 59 на 60

сбросить счетчик на 0

обработать 1 минуту активностиСпасибо за ответ! Прочитав ваш пост, я сделал это. Установите два беззнаковых целых в начале на ноль. Затем добавьте счетчик на мое односекундное прерывание, чтобы считать каждую секунду. Однако, когда я добавляю 10Second ++ в switch (taiv) {, я получаю сообщение об ошибке «Оператор недоступен».
 user362924918 июл. 2016 г., 17:36
Заголовок определяет символы для
 TheJr18 июл. 2016 г., 06:50
Пожалуйста, опубликуйте изменения в своем вопросе (включая измененный код), обязательно отметьте новый опубликованный код как правку. Затем разместите здесь комментарий, указывающий, что вы внесли изменения.

Ваш ответ на вопрос