реклама на сайте
подробности

 
 
> проблемма с таймером, проблемма с таймером
jjjjjjein
сообщение Oct 31 2011, 06:01
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 41
Регистрация: 31-10-11
Пользователь №: 68 059



Хочу, что бы 2 светодиода меняли своё состояние с разным периодом. Один, раз в 100 мс, второй - в 500мс. Ошибка в обработчике прерываний. Как её исправить? подскажите, кто знает)


int main( void )
{
WDTCTL = WDTPW + WDTHOLD; // Остановка сторожевого таймера, чтобы предотвратить время сброса
_DINT(); // Запрещаем прерывания
InitializationPortIO (); // Вызов функции инициализации портов ввода/вывода микроконтроллера
InitializationTimersMSP430 (); // Вызов функции инициализации внутренних аппаратных таймеров микроконтроллера MSP430F135
_EINT(); // Разрещаем прерывания

while (1)

{
if (Flag_500ms == true) // Если поставлен флаг 500мс
{
P4OUT = ~(P4OUT & BIT4); // Состояние 3 вывода 4 порта меняется
Flag_500ms = false; // Флаг убирается
}
if (Flag_100ms == true) // Если поставлен флаг 100мс
{
P4OUT = ~(P4OUT & BIT3); // Состояние 4 вывода 4 порта меняется
Flag_100ms = false; // Флаг убирается
}
}
}
//********************************************************************************
*********************************************************************************
******************************
//********************************************************** ОБРАБОТЧИКИ ПРЕРЫВАНИЙ ********************************************************************************
*********************
#pragma vector = TIMERA0_VECTOR // Прерывание от таймера А (срабатывает каждые 10 мс)
__interrupt void isr_TACCR0() // прерывание
{
t ++;
y ++;
if ( t >= 10 )
{
Flag_100ms = true;
t = 0;
}
if ( y >= 50 )
{
Flag_500ms = true;
y = 0;
}
}
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
rezident
сообщение Nov 1 2011, 22:35
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Го-о-оспидя, как все запущено! laughing.gif
Обычно задуманное вами делается так.
Определяете прерывание с "тиком" 1 мс или 10мс или 100мс, как удобнее.. Инкрементируете в прерывании некую переменную "системных тиков" на величину веса/цены системного тика. Это будут ваши "часы", единые для всей программы. Далее в основном цикле для каждого события отводите по переменной в которых будут храниться значения временнЫх меток. Сравниваете текущее показание "часов" и значение временнОй метки путем беззнакового вычитания. Если разница больше периода возникновения события, то реализуете его (событие) и запоминаете вновь текущее значение "часов". Вот и вся недолга!
Важное замечание. Переменная "тиков" должна быть объявлена как беззнаковое целое (unsigned int) и обязательно с квалификатором volatile. Разрядность переменной "тиков" определяется требованиями к максимальному периоду событий. Если предположим, что "вес" системного тика - 1мс, то 16-и разрядная переменная типа unsigned int позволяет определить максимальный период 65,535с. Если этого мало, то используйте 32-х разрядный тип unsigned long int, тогда при том же "весе" тика (1мс) максимальный период составит немного больше 1,5 месяцев. Только в последнем случае следует обязательно обеспечить атомарность считывания переменной "тиков" потому, что она инкрементируется в прерывании, а значение ее считывается в основном цикле программы. Притом, что значение переменной превышает нативную разрядность MSP430. Если для реализации атомарности чтения не прибегать к запрету прерываний, то типовым способом является такой, как в примере ниже (функция clock_ms).

Код
...
#include <stdint.h>

#define ADD_SYSTICK_VALUE 1UL //цена системного тика - 1 мс
#define LED1_BLINKPERIOD 100UL //период мерцания LED1 [в мс]
#define LED2_BLINKPERIOD 500UL //период мерцания LED2 [в мс]

volatile uint32_t SystemTick;

uint32_t clock_ms(void)
{ uint32_t tmp1, tmp2;
  do
  { tmp1=SystemTick;
    tmp2=SystemTick;
  } while(tmp1 != tmp2);
  return tmp2;
}

void main (void)
{ uint32_t timeStampLed1, timeStampLed2;
...
  timeStampLed1 = clock_ms();
  timeStampLed2 = clock_ms();
...
  for (;;)
  {
...
    if ((clock_ms() - timeStampLed1) >= LED1_BLINKPERIOD) //проверка периода мерцания LED1
    { P4OUT ^= BIT3;
      timeStampLed1 = clock_ms();
    }
    if ((clock_ms() - timeStampLed2) >= LED2_BLINKPERIOD) //проверка периода мерцания LED2
    { P4OUT ^= BIT4;
      timeStampLed2 = clock_ms();
    }
...
  }
}

#pragma vector=TIMERA0_VECTOR
@pragma type_attrinute=__interrupt
void SYSTICK_ISR(void)
{ SystemTick += ADD_SYSTICK_VALUE; //инкремент переменной системного тика
}
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 28th July 2025 - 04:19
Рейтинг@Mail.ru


Страница сгенерированна за 0.01642 секунд с 7
ELECTRONIX ©2004-2016