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

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

|
Цитата(AHTOXA @ Apr 20 2014, 08:24)  Добавьте перед запуском таймера: Код // generate an update event to load the PSC and ARR values immediately TIM3->EGR = TIM_EGR_UG; пробывал вот так: Код /* Настройка таймера TIM2 на событие: Прерывание при совпадении с р-ром TIM2_ARR */ TIM2->ARR=(6500); // загрузка рег-ра для сравнения 366,2109375/350=1 Hz TIM2->PSC=(65535-1); // предделитель CK_CNT=24000000/65536=366,2109375 Hz TIM2->DIER|=(TIM_DIER_UIE); // разрешаем прерывание по срабатыванию таймера TIM2->EGR = TIM_EGR_UG; TIM2->SR =~(TIM_SR_UIF);// сброс ф.прерывания TIM2->CR1|=(TIM_CR1_CEN); // Запуск Таймера
/* Разрешение прерывания TIM2 */ NVIC_EnableIRQ(TIM2_IRQn); Не работает, таймер также запускается при ресет
|
|
|
|
|
Apr 22 2014, 09:17
|

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

|
Цитата(AHTOXA @ Apr 22 2014, 11:32)  Надо сгенерировать событие обновления, потом сбросить флаг, а уже потом разрешать прерывания: Код TIM2->ARR = 6500; TIM2->PSC = 65535-1; TIM2->EGR = TIM_EGR_UG; TIM2->SR = ~TIM_SR_UIF; TIM2->DIER |= TIM_DIER_UIE; TIM2->CR1 |= TIM_CR1_CEN; тоже самое Похоже что TIM2->SR =~(TIM_SR_UIF); не сбразывает сам "запрос" на прерывание
Сообщение отредактировал MaxiMuz - Apr 22 2014, 09:35
|
|
|
|
|
Apr 22 2014, 09:56
|
Знающий
   
Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725

|
Цитата(MaxiMuz @ Apr 22 2014, 10:17)  тоже самое Похоже что TIM2->SR =~(TIM_SR_UIF); не сбразывает сам "запрос" на прерывание Попробуйте еще добавить: CODE TIM2->ARR = 6500; TIM2->PSC = 65535-1; TIM2->EGR = TIM_EGR_UG; TIM2->SR = ~TIM_SR_UIF; NVIC_ClearPendingIRQ(TIM2_IRQn); TIM2->DIER |= TIM_DIER_UIE; TIM2->CR1 |= TIM_CR1_CEN;
Сообщение отредактировал KnightIgor - Apr 22 2014, 09:57
|
|
|
|
|
Apr 22 2014, 10:48
|

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

|
Выясненно опытным путем с использованием документа "Cortex-M3 programming manual". Сброс флага статусного регистра Код TIM2->SR =~(TIM_SR_UIF); не приводит к сбросу самого запроса на прерывание. Чтобы сбросить запрос на прерывания делаем: 1. После загрузки временных прарметров разрешаем прерывание по срабатыванию таймера 2. генерим событие таймера UG 3. Ждем один такт и только потом сбрасиываем флаг прерывания в регистре статуса таймера 4. Запускаем Таймер 5. Очищаем Interrupt clear-pending registers (NVIC_ICPRx) 6. И только потом включаем разрешение на прерывание Код /* Настройка таймера TIM2 на событие: Прерывание при совпадении с р-ром TIM2_ARR */ TIM2->ARR=(1500); // загрузка рег-ра для сравнения ~ 366/1500=0,244 Hz TIM2->PSC=(65535-1); // предделитель CK_CNT=24000000/65536=366,2109375 Hz
TIM2->DIER|=(TIM_DIER_UIE); // разрешаем прерывание по срабатыванию таймера TIM2->EGR = TIM_EGR_UG; // генерим событие таймера __NOP(); TIM2->SR =~(TIM_SR_UIF);// сброс ф.прерывания TIM2->CR1|=(TIM_CR1_CEN); // Запуск Таймера
NVIC_ClearPendingIRQ (TIM2_IRQn);
/* Разрешение прерывания TIM2 */ NVIC_EnableIRQ(TIM2_IRQn); Если закоментить nop, то сброс события таймера не проходит. Собственно вопрос такой , если мы в конце сбрасываем бит запроса на прерывания от таймера2 , тогда уже не важно какие события произошли до этого , прерывание по идее не ожидается, правильно ? Но если я убираю команду TIM2->EGR = TIM_EGR_UG; // генерим событие таймера , то таймер сразу после разрешения прерывания запускается.
|
|
|
|
|
Apr 22 2014, 13:19
|
Частый гость
 
Группа: Участник
Сообщений: 90
Регистрация: 12-12-13
Пользователь №: 79 587

|
Цитата(MaxiMuz @ Apr 22 2014, 14:48)  1. После загрузки временных прарметров разрешаем прерывание по срабатыванию таймера 2. генерим событие таймера UG 3. Ждем один такт и только потом сбрасиываем флаг прерывания в регистре статуса таймера 4. Запускаем Таймер 5. Очищаем Interrupt clear-pending registers (NVIC_ICPRx) 6. И только потом включаем разрешение на прерывание Как-то сложно всё это получается. Попробуйте просто: 1. Запустить таймер 2. Разрешить прерывание Именно в такой последовательности.
|
|
|
|
|
Apr 22 2014, 16:51
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Цитата Но если я убираю команду TIM2->EGR = TIM_EGR_UG; смысл команды не сгенерить прерывание смысл команды вызвать событие и обновить регистры таймера, обновление которых происходит по событию, которое в свою очередь и генерит прерывание. Прерывание в данном случае - побочный эффект от обновления таймера. Цитата Как-то сложно всё это получается. Попробуйте просто: 1. Запустить таймер 2. Разрешить прерывание Именно в такой последовательности. и будет исходная задача, без вызова события не произойдет настройки таймера, а событие вызовет прерывание, потому сразу после разрешения прерывания в вашем случае полетите либо по таймеру работающему по старыми настройкам, либо если обновили настройки, то сразу по прерыванию...
|
|
|
|
|
Apr 23 2014, 00:28
|
Местный
  
Группа: Участник
Сообщений: 226
Регистрация: 10-07-09
Пользователь №: 51 126

|
Цитата(Golikov A. @ Apr 20 2014, 08:53)  REGISTR = (DEFAULT_VAL & (~INTERRUPT)); - правильно Да тоже неправильно...  DEFAULT_VAL равно нулю...
|
|
|
|
|
Apr 23 2014, 07:38
|
Местный
  
Группа: Участник
Сообщений: 226
Регистрация: 10-07-09
Пользователь №: 51 126

|
Цитата(Golikov A. @ Apr 23 2014, 09:23)  DEFAULT_VAL равно не нулю, а тому чему оно должно быть равно для сохранения верных значений записываемых битиков.... Тогда уже лучше написать DEFAULT_VAL_MASK, где все биты с атрибутом RES должны быть нулями, а устанавливаемые флаги единицами... а не DEFAULT_VAL... Я не ради докопаться... просто на другом форуме вопрошающий уже выдал непонимание происходящего...
Сообщение отредактировал HHIMERA - Apr 23 2014, 07:39
|
|
|
|
|
Apr 23 2014, 07:49
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(HHIMERA @ Apr 23 2014, 11:38)  Тогда уже лучше написать DEFAULT_VAL_MASK, где все биты с атрибутом RES должны быть нулями, а устанавливаемые флаги единицами... Их нельзя нулями. По мануалу нужно сохранять состояние после сброса. То есть "честное" формирование DEFAULT_VAL должно быть таким: reg_def_val = reg | <все флаги типа w0c> или reg_def_val = reg & ~<все флаги типа w1c> Не уверен, что кто-то так делает, конечно  Цитата(Golikov A. @ Apr 23 2014, 10:23)  я чет не припомню проца где это было нужно (в смысле где часть битов надо было оставлять 0, а часть 1, обычно все одинаковые) Бывает, хотя в статусных регистрах тоже не встречал.
|
|
|
|
|
Apr 23 2014, 10:29
|
Местный
  
Группа: Участник
Сообщений: 226
Регистрация: 10-07-09
Пользователь №: 51 126

|
Цитата(aaarrr @ Apr 23 2014, 10:49)  Не уверен, что кто-то так делает, конечно  Да... сомнения присутствуют... А по поводу... Цитата По мануалу нужно сохранять состояние после сброса. Примеры SPL это отвергают напрочь... т.е. всё на совести и знаниях кодера...
|
|
|
|
|
Apr 23 2014, 15:13
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
да я тоже часто в ПЛИС делают некоторые резервные биты, которые не использую, и сам их нулю внутри автоматов, но на всякий случай, мало ли чего забуду, в описании требую такие биты в регистрах не трогать. Думаю тут также, если их трогать скорее всего ничего не будет, но мало ли что, потому и приписка такая, чтоб наверняка!
|
|
|
|
|
Apr 23 2014, 17:54
|
Местный
  
Группа: Участник
Сообщений: 226
Регистрация: 10-07-09
Пользователь №: 51 126

|
Цитата если их трогать скорее всего ничего не будет В каком-то таймере STM32... точно уже не помню... где по референсу бит OPM отсутствует... попробовал как-то его установить... на авось... а вдруг... Результат - таймер затыкался... т.е. все эти предупреждения... как бы и не на ровном месте...
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|