|
Обработчик прерывания срабатывает сразу после запуска таймера |
|
|
|
Apr 18 2014, 13:11
|

Местный
  
Группа: Участник
Сообщений: 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 ?
|
|
|
|
|
Apr 18 2014, 15:18
|
Знающий
   
Группа: Участник
Сообщений: 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 новыми значениями. - сбросить установившиеся флаги прерываний - только теперь разрешить прерывания и запустить таймер.
|
|
|
|
|
Apr 19 2014, 21:42
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

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

фанат дивана
     
Группа: Свой
Сообщений: 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;
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Apr 20 2014, 05:53
|
Гуру
     
Группа: Свой
Сообщений: 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); - не правильно!
|
|
|
|
|
Apr 20 2014, 09:33
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Golikov A. @ Apr 20 2014, 09:53)  может затереть возникший за эти три такта новый флаг, Если битов несколько, и есть такая вероятность, то да, может. Цитата(Golikov A. @ Apr 20 2014, 09:53)  не говоря уже о чтение битов, которые предназначены только для записи. Тут уж что-то одно - или write-only, или w0. Но никак не одновременно. Для обсуждаемого случая "&=" является вполне корректной конструкцией.
|
|
|
|
|
Apr 21 2014, 12:31
|

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

|
Цитата(aaarrr @ Apr 20 2014, 12:33)  Для обсуждаемого случая "&=" является вполне корректной конструкцией. Да , действительно , если в свойствах битов регистра " rc_w0" -означает очистка 0 , то корректнее очищать флаг: Код REG= ~(BIT_MASK); Но если используется всего один флаг , то так Код TIM2->SR &=~(TIM_SR_UIF); тоже правильно
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|