Alex_Golubev 0 12 апреля, 2021 Опубликовано 12 апреля, 2021 · Жалоба Нужно сделать отчет времени на таймере типа таймаут. Какое событие произойдет быстрее таймер досчитает и вызовет вектор прерывания или успеем получить ответь. Попытался сделать вот так: Скрытый текст MODIFY_REG(RCC->APB2ENR, RCC_APB2ENR_TIM16EN, 0x1 << RCC_APB2ENR_TIM16EN_Pos); // включение тактирования таймера TIM16 while(!(RCC->APB2ENR & RCC_APB2ENR_TIM16EN)); // ждем когда включиться TIM16->CR1 |= TIM_CR1_OPM; TIM16->DIER = TIM_DIER_UIE; TIM16->PSC = 5730 - 1; TIM16->ARR = 20; TIM16->CNT = 0; TIM16->CCR1 = 0xffff; NVIC_SetPriority(TIM16_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0, 0)); // включение прерывания таймера TIM16 NVIC_EnableIRQ(TIM16_IRQn); TIM16->CR1 |= TIM_CR1_CEN; Проблема не знаю как остановить если получил ответ раньше чем досчитал таймер. Отключения таймера 'TIM16->CR1 &= ~TIM_CR1_CEN;' не помогает происходит вызов вектора прерывания. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 42 12 апреля, 2021 Опубликовано 12 апреля, 2021 · Жалоба 17 minutes ago, Alex_Golubev said: Отключения таймера 'TIM16->CR1 &= ~TIM_CR1_CEN;' не помогает происходит вызов вектора прерывания. Сначала запретите прерывание, а потом останавливайте. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex_Golubev 0 12 апреля, 2021 Опубликовано 12 апреля, 2021 · Жалоба Запретить глобально или локально в регистре таймера TIM16->DIER &= ~TIM_DIER_UIE. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 42 12 апреля, 2021 Опубликовано 12 апреля, 2021 · Жалоба 5 minutes ago, Alex_Golubev said: Запретить глобально или локально в регистре таймера TIM16->DIER &= ~TIM_DIER_UIE. конечно в таймере Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Plain 163 12 апреля, 2021 Опубликовано 12 апреля, 2021 · Жалоба 1 час назад, Alex_Golubev сказал: сделать отчет времени на таймере типа таймаут Если таки имеется ввиду отсчёт таймером, а не отчёт от таймера, то такое обычно делают его компаратором. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex_Golubev 0 12 апреля, 2021 Опубликовано 12 апреля, 2021 · Жалоба И какая получается логика работы? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Plain 163 12 апреля, 2021 Опубликовано 12 апреля, 2021 · Жалоба Читаете таймер, прибавляете таймаут, пишете в компаратор, и по тому событию под названием "получил ответ" читаете флаг компаратора, а если то событие аппаратное, проще его защёлкой того же таймера ловить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex_Golubev 0 12 апреля, 2021 Опубликовано 12 апреля, 2021 · Жалоба Чета не смог понять в чем может быть дело. Период вызова вектора прерывания 500 мкС. Должно быть 960 мкС. Входная частота 120 МГц. 120 *10^6/5730 = 20945 1/20945 = 47 *10^-6 47 *10^-6 * 20 = 954 *10^-6 Вот код: Скрытый текст MODIFY_REG(RCC->APB2ENR, RCC_APB2ENR_TIM16EN, 0x1 << RCC_APB2ENR_TIM16EN_Pos); // включение тактирования таймера TIM16 while(!(RCC->APB2ENR & RCC_APB2ENR_TIM16EN)); // ждем когда включитьс TIM16->DIER = TIM_DIER_UIE; TIM16->PSC = 5730 - 1; TIM16->ARR = 20 - 1; TIM16->CNT = 0; TIM16->RCR = 1 - 1; TIM16->SR = 0; NVIC_SetPriority(TIM16_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0, 0)); // включение прерывания таймера TIM16 NVIC_EnableIRQ(TIM16_IRQn); TIM16->CR1 |= TIM_CR1_CEN; Посмотрите где я ошибся. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 42 12 апреля, 2021 Опубликовано 12 апреля, 2021 · Жалоба 13 minutes ago, Alex_Golubev said: Посмотрите где я ошибся. Либо у вас на самом деле не 120 МГц, а 240 Мгц. Либо вам следует внимательно посмотреть раздел 7.5.6 System clock (sys_ck) в Reference Manual. В зависимости от настройки делителя шины, частота таймера может быть удвоенной частотой шины. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex_Golubev 0 12 апреля, 2021 Опубликовано 12 апреля, 2021 (изменено) · Жалоба Входная 120 МГц. Нет множителя. не нашел множитель шина на 2 в stm32h743. Изменено 12 апреля, 2021 пользователем Alex_Golubev Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 42 12 апреля, 2021 Опубликовано 12 апреля, 2021 · Жалоба 29 minutes ago, Alex_Golubev said: Входная 120 МГц. Нет множителя. не нашел множитель шина на 2 в stm32h743. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex_Golubev 0 13 апреля, 2021 Опубликовано 13 апреля, 2021 · Жалоба Еще проблема таймер при первом включение имеет ложное срабатывания. То есть когда только проинициализировал и сделал включение 'TIM16->CR1 |= TIM_CR1_CEN' таймер сразу вызывает прерывании и устанавливает бит 'TIM_DIER_UIE'. Далее все нормально по крайней мере не заметил. Проверил осциллографом перед включение ставлю 1 после отключения 0 на порту. Скрытый текст TIM16->CR1 |= TIM_CR1_OPM; TIM16->DIER = TIM_DIER_UIE; TIM16->PSC = 11520 - 1; TIM16->ARR = 20; TIM16->CNT = 0; TIM16->CCR1 = 0; TIM16->RCR = 1 - 1; TIM16->SR = 0; NVIC_SetPriority(TIM16_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0, 0)); NVIC_EnableIRQ(TIM16_IRQn); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 42 13 апреля, 2021 Опубликовано 13 апреля, 2021 · Жалоба 1 hour ago, Alex_Golubev said: Еще проблема таймер при первом включение имеет ложное срабатывания. Перед NVIC_EnableIRQ(TIM16_IRQn); сделайте сброс регистра статуса таймера, сделать сброс прерывания в NVIC, установить бит UDIS в регистре CR1 таймера. Если все это не поможет, то инициализируйте регистр CNT таймера единичкой, а не нулем. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex_Golubev 0 13 апреля, 2021 Опубликовано 13 апреля, 2021 (изменено) · Жалоба Я установил 'TIM_CR1_UDIS' и у меня вызов прерываний пропал. Когда заносишь число ну например 100 в регистр cnt то прерывание вызывается не сразу а через какое то время. Ну например для cnt = 100 время выхода составляет по осциллографу 225 мкС. Для сnt = 1 пример 1 мкС. Сброс делаю регистра sr TIM16->SR = 0; TIM16->SR &= ~TIM_SR_UIF; Изменение регистра CCR не на что не влияет. Почему при cnt = 100 время ложного 225 мкС не знаю. Изменено 13 апреля, 2021 пользователем Alex_Golubev Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 42 13 апреля, 2021 Опубликовано 13 апреля, 2021 · Жалоба 16 minutes ago, Alex_Golubev said: Я установил 'TIM_CR1_UDIS' и у меня вызов прерываний пропал. Извиняюсь, бит URS. А вообще, вам самому не мешало бы более внимательно изучить документацию. Тем более таймер не такой уж и сложный периферийный модуль. Тем более, судя по вашему коду, который вы здесь приводите, вы в эту документацию уже заглядывали. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться