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

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> Обработчик прерывания срабатывает сразу после запуска таймера
MaxiMuz
сообщение Apr 18 2014, 13:11
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658



Запрограммировал таймер на отчет временных интервалов:
Код
/* Настройка таймера TIM2 на событие: Прерывание при совпадении с р-ром TIM2_ARR */
    TIM2->ARR=(8000); // загрузка рег-ра для сравнения 366/8000=0,046 Hz
    TIM2->PSC=(65536-1);        // предделитель CK_CNT=24000000/65536=366 Hz
    TIM2->DIER|=(TIM_DIER_UIE); // разрешаем прерывание по срабатыванию таймера
    TIM2->CNT=1;
    TIM2->CR1|=(TIM_CR1_CEN); // Запуск Таймера

/* Разрешение прерывания TIM2 */
    NVIC_EnableIRQ(TIM2_IRQn);

Период србатывания ~21сек.
В обработчике поставил маркер срабатывания:
Код
void TIM2_IRQHandler (void)
{
    u32 i;
    TIM2->SR &=~(TIM_SR_UIF);// сброс ф.прерывания
    SWITCH_PIN(PC8);
}

При запуске программы почемуто сразу срабатывает прерывание. С какого это оно срабатывает , если событие не наступило?
Как сделать чтобы первое срабатывание было только по совпадению с рег-ом ARR ?
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Apr 18 2014, 15:18
Сообщение #2


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(MaxiMuz @ Apr 18 2014, 14:11) *
При запуске программы почемуто сразу срабатывает прерывание. С какого это оно срабатывает , если событие не наступило?
Как сделать чтобы первое срабатывание было только по совпадению с рег-ом ARR ?

Сначала вопрос, не под отладчиком ли Вы пробуете: если не предпринять мер, а именно запретить счет таймера во время остановки при отладки, то таймер будет бежать дальше.
Регистры ARR и PSC имеют теневые регистры. Команды записи модифицируют теневые регистры, которые перепишутся в рабочие, когда установится флаг обновления:
Цитата
It can be changed on the fly as this control register is buffered. The new prescaler ratio is taken into account at the next update event.

Это означает, что новые значения регистров, которые Вы записали при инициализации, не действуют, пока не наступит событие переполнения, а оно наступает быстро, т.к. по умолчанию PSC равен нулю.
Действия:
- записать, что надо, прерывание еще не разрешать,
- установить искусственно флаг UG в регистре EGR - это обновит PSC|ARR новыми значениями.
- сбросить установившиеся флаги прерываний
- только теперь разрешить прерывания и запустить таймер.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 19 2014, 14:31
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата
TIM2->SR &=~(TIM_SR_UIF);


и это стоит проверить, в том ли регистре идет сброс, и так ли он идет? Обычно делают сбросы через = а не &=(|=), по ряду причин... но это надо проверить. Если регистр не чувствителен к записи 1 или 0 - это явный намек на это
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Apr 19 2014, 19:03
Сообщение #4


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(Golikov A. @ Apr 19 2014, 15:31) *
и это стоит проверить, в том ли регистре идет сброс, и так ли он идет?

В описании регистра для бита UIF стоит /w0, что означает, что флаг сбрасывается при записи нуля. Так что все правильно. Конечно, можно замутить что-то элегантно и с bitband. Это в EFM32 есть "регистр сброса битов статуса", куда надо писать единицу для сброса бита регистра статуса в ноль. В STM32 такой подход применен только в GPIO.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 19 2014, 21:18
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



я к тому что надо писать не
TIM2->SR &= ~(TIM_SR_UIF);

а

TIM2->SR = ~(TIM_SR_UIF);

я не прав? Остальные биты регистра читаемые? Реагируют ли они на 1?

почему = лучше чем &= уже много раз обсуждали....
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Apr 19 2014, 21:42
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Golikov A. @ Apr 20 2014, 01:18) *
почему = лучше чем &= уже много раз обсуждали....

Оно не лучше, оно для разных случаев.
"&=" или "|=" вместо "=" - типичная ошибка при работе с write-only регистрами.
Но как раз в случае STM так делать нельзя, по причине наличия такого примечания
для незадействованных битов в регистрах: Reserved, must be kept at reset value.
Так что только "&=" и "|=".
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Apr 20 2014, 05:24
Сообщение #7


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(MaxiMuz @ Apr 18 2014, 19:11) *
При запуске программы почемуто сразу срабатывает прерывание. С какого это оно срабатывает , если событие не наступило?


Регистр PSC обновляется только при update event.
Если ARPE = 1, то ARR тоже обновляется только при update event (иначе сразу).

Добавьте перед запуском таймера:
Код
    // generate an update event to load the PSC and ARR values immediately
    TIM3->EGR = TIM_EGR_UG;


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 20 2014, 05:53
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата(aaarrr @ Apr 20 2014, 01:42) *
Оно не лучше, оно для разных случаев.
"&=" или "|=" вместо "=" - типичная ошибка при работе с write-only регистрами.
Но как раз в случае STM так делать нельзя, по причине наличия такого примечания
для незадействованных битов в регистрах: Reserved, must be kept at reset value.
Так что только "&=" и "|=".


нет оно именно лучше.

если в регистре несколько битов - флагов, то
&= |=
срабатывая в 3 такта
забрать значение, изменить, записать обратно
может затереть возникший за эти три такта новый флаг, не говоря уже о чтение битов, которые предназначены только для записи.

Поэтому если в регистре есть биты которые должны оставаться всегда в ресет значениях, значит это должно быть учтено при
REGISTR = SBROS, в величине SBROS, но не как не означает что надо делать &=, |=....

REGISTR = (DEFAULT_VAL & (~INTERRUPT)); - правильно
REGISTR &= (~INTERRUPT) ==== REGISTR = REGISTR & (~INTERRUPT); - не правильно!
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Apr 20 2014, 09:33
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Golikov A. @ Apr 20 2014, 09:53) *
может затереть возникший за эти три такта новый флаг,

Если битов несколько, и есть такая вероятность, то да, может.

Цитата(Golikov A. @ Apr 20 2014, 09:53) *
не говоря уже о чтение битов, которые предназначены только для записи.

Тут уж что-то одно - или write-only, или w0. Но никак не одновременно.

Для обсуждаемого случая "&=" является вполне корректной конструкцией.
Go to the top of the page
 
+Quote Post
adnega
сообщение Apr 20 2014, 15:05
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(aaarrr @ Apr 20 2014, 13:33) *
Для обсуждаемого случая "&=" является вполне корректной конструкцией.

Вряд ли. Если в момент "чтение-модификация-запись" произойдет установка какого-нибудь другого флага, то он будет сброшен без обработки.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 20 2014, 17:06
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата(adnega @ Apr 20 2014, 19:05) *
Вряд ли. Если в момент "чтение-модификация-запись" произойдет установка какого-нибудь другого флага, то он будет сброшен без обработки.


как я понял автор настаивает на том, что в этом регистре всего один флаг (или используется только он), и потому ничего нельзя затереть. Другое дело что потом понадобиться другой флаг, или будет перенос кода обработчика через ctrl-c, ctrl-v или переход на другой проц с несколькими флагами, но кто у нас об этом думает...
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Apr 20 2014, 18:20
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Golikov A. @ Apr 20 2014, 21:06) *
Другое дело что потом понадобиться другой флаг, или будет перенос кода обработчика через ctrl-c, ctrl-v или переход на другой проц с несколькими флагами, но кто у нас об этом думает...

Да мало ли способов накосячить? Это лишь один из многих.

P.S. Специально раскопал свой (целый один) проект с STM32. Таки да, прерывания в нем сбрасываю через = FLAG. Сброс более одного флага в обработчике используется только в модуле USB.
Go to the top of the page
 
+Quote Post
MaxiMuz
сообщение Apr 21 2014, 11:15
Сообщение #13


Местный
***

Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658



Цитата(KnightIgor @ Apr 18 2014, 18:18) *
Сначала вопрос, не под отладчиком ли Вы пробуете: если не предпринять мер, а именно запретить счет таймера во время остановки при отладки, то таймер будет бежать дальше.

Нет , отлаживаю все в железе по "лампочкам"
Go to the top of the page
 
+Quote Post
MaxiMuz
сообщение Apr 21 2014, 12:31
Сообщение #14


Местный
***

Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658



Цитата(aaarrr @ Apr 20 2014, 12:33) *
Для обсуждаемого случая "&=" является вполне корректной конструкцией.

Да , действительно , если в свойствах битов регистра "rc_w0" -означает очистка 0 , то корректнее очищать флаг:
Код
REG= ~(BIT_MASK);

Но если используется всего один флаг , то так
Код
TIM2->SR &=~(TIM_SR_UIF);

тоже правильно
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Apr 21 2014, 20:24
Сообщение #15


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(MaxiMuz @ Apr 21 2014, 18:31) *

Я надеюсь, что среди всех этих полезных рассуждений о способах сброса флагов вы не пропустили сообщение номер 7, в котором я объясняю причины вашей исходной проблемы и даю способ её решения? sm.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 22:53
Рейтинг@Mail.ru


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