sith633 0 12 ноября, 2021 Опубликовано 12 ноября, 2021 · Жалоба Приветствую, может, кто сталкивался с такой проблемой? Принимаю ИК посылку из стартового бита и четырех бит команды. Вот инит таймера. static void TIM2_init(void) { NVIC_EnableIRQ (TIM2_IRQn); NVIC_SetPriority(TIM2_IRQn, 0); /* Включаем тактирование на порту А GPIO */ RCC->AHBENR |= (1<<17); /*Выставляем альтернативную функцию на РА1*/ GPIOA->MODER |= GPIO_MODER_MODER1_1; GPIOA->PUPDR |= GPIO_PUPDR_PUPDR1_0; /*Задаем AF2 для PА1*/ GPIOA->AFR[0] |= (1<<5); RCC->APB1ENR |=(1<<0); //включаем тактирование таймера 2 TIM2->PSC = 7; //предделитель для получения тактовой частоты 1 МГц TIM2->CR1 |= TIM_CR1_ARPE; //TIM2_ARR register is buffered TIM2->ARR = 9100; /*настраиваем СC1 на вход TI2*/ TIM2->CCMR1 |= TIM_CCMR1_CC1S_1; TIM2->CCMR1 &= ~TIM_CCMR1_CC1S_0; //TIM2->CCER &= ~TIM_CCER_CC1NP ; //активная полярность канала передний фронт TIM2->CCER &= ~(TIM_CCER_CC1NP | TIM_CCER_CC1P); /*настраиваем СС2 на вход TI2*/ TIM2->CCMR1 |= TIM_CCMR1_CC2S_0; TIM2->CCMR1 &= ~TIM_CCMR1_CC2S_1; /*Устанавливаем срабатывание по заднему фронту (активная полярность)*/ TIM2->CCER |= TIM_CCER_CC2P; TIM2->CCER |= TIM_CCER_CC1E ; //разрешаем захват /*Выбрать TI2FP2 в качестве входа триггера */ TIM2->SMCR |= (TIM_SMCR_TS_1| TIM_SMCR_TS_2); TIM2->SMCR &= ~TIM_SMCR_TS_0; /*reset mode*/ TIM2->SMCR |= TIM_SMCR_SMS_2 ; TIM2->SMCR &= ~TIM_SMCR_SMS_0 | TIM_SMCR_SMS_1; //TIM2->EGR |= TIM_EGR_UG; TIM2->DIER |= TIM_DIER_CC1IE; TIM2->EGR = TIM_EGR_UG; TIM2->SR; TIM2->SR = 0; TIM_EnableCounter(TIM2); } А вот сам обработчик void TIM2_IRQHandler(void) { uint32_t sr = TIM2->SR; TIM2->SR = ~sr; if(sr & TIM_SR_CC1IF) { period = (TIM2->CCR1); } else if ((TIM2->SR & TIM_SR_CC1OF) != 0) /* Check the overflow */ { TIM2->SR = ~(TIM_SR_CC1OF | TIM_SR_CC1IF); /* Clear the flags */ return; } printf("period is %lu\n", period); __ISB(); } Первый раз посылка принялась нормально, но все остальные разы принимается стартовый бит и первый. Анализатор показывает, что посылка приходит полностью. В чем может быть затык? Заранее спасибо. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 12 ноября, 2021 Опубликовано 12 ноября, 2021 · Жалоба 55 minutes ago, sith633 said: В чем может быть затык? Как минимум в принте в обработчике прерывания. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sith633 0 12 ноября, 2021 Опубликовано 12 ноября, 2021 (изменено) · Жалоба Чем же он мешает? Меня предупреждали, что это плохо, но не смертельно. Я его выносил в тело основной функции, но результат был примерно тем же Изменено 12 ноября, 2021 пользователем sith633 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 43 12 ноября, 2021 Опубликовано 12 ноября, 2021 · Жалоба 6 minutes ago, sith633 said: Чем же он мешает? Меня предупреждали, что это плохо, но не смертельно. Я его выносил в тело основной функции, но результат был примерно тем же Пока идет печать может произойти несколько событий. И еще. У вас в обработчике конструкция else if. Если одновременно произойдут оба события, то второе вы потеряете. Уберите else. И к тому же, вы сначала сбрасываете флаги в регистре статуса, а потом проверяете это регистр статуса. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sith633 0 12 ноября, 2021 Опубликовано 12 ноября, 2021 · Жалоба uint32_t sr = TIM2->SR; TIM2->SR = ~sr; Вместо этого была строчка TIM2->SR =~TIM_SR_UIF; Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sith633 0 12 ноября, 2021 Опубликовано 12 ноября, 2021 · Жалоба void TIM2_IRQHandler(void) { TIM2->SR = ~TIM_SR_UIF; if ((TIM2->SR & TIM_SR_CC1IF) != 0) { period = (TIM2->CCR1); } if ((TIM2->SR & TIM_SR_CC1OF) != 0) /* Check the overflow */ { TIM2->SR = ~(TIM_SR_CC1OF | TIM_SR_CC1IF); /* Clear the flags */ return; } __ISB(); } При таком виде обработчика принимается только стартовый бит Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 197 12 ноября, 2021 Опубликовано 12 ноября, 2021 · Жалоба 2 часа назад, sith633 сказал: Чем же он мешает? Меня предупреждали, что это плохо, но не смертельно. Если вы даже не понимаете почему printf() там в принципе недопустим, то прерываниями вам вообще рано заниматься. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Wasserati 0 12 ноября, 2021 Опубликовано 12 ноября, 2021 (изменено) · Жалоба Если тут сброс бита подразумевается: TIM2->SR = ~TIM_SR_UIF; то он не так делается, а так: TIM2->SR &= ~TIM_SR_UIF; В остальных местах та же ситуация. Изменено 12 ноября, 2021 пользователем Wasserati Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 197 12 ноября, 2021 Опубликовано 12 ноября, 2021 · Жалоба 1 минуту назад, Wasserati сказал: Если тут сброс бита подразумевается: TIM2->SR = ~TIM_SR_UIF; то он не так делается, а так: TIM2->SR &= ~TIM_SR_UIF; В остальных местах та же ситуация. Может вам всё-таки почитать мануал? Вместо того чтобы нести чушь. Сброс бита UIF так и делается, как было: TIM2->SR = ~TIM_SR_UIF; А то что вы изобразили - это сброс случайных битов в SR. Которым не повезло. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Wasserati 0 12 ноября, 2021 Опубликовано 12 ноября, 2021 · Жалоба 9 minutes ago, jcxz said: Может вам всё-таки почитать мануал? Вместо того чтобы нести чушь. Сброс бита UIF так и делается, как было: TIM2->SR = ~TIM_SR_UIF; А то что вы изобразили - это сброс случайных битов в SR. Которым не повезло. Я бы поспорил. Что-либо сбросить случайно второй вариант в принципе не может. А вот посмотрев даташит могу утверждать, что обе конструкции дадут идентичный эффект, тут разницы не будет, да. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 197 12 ноября, 2021 Опубликовано 12 ноября, 2021 · Жалоба 2 минуты назад, Wasserati сказал: Я бы поспорил. Что-либо сбросить случайно второй вариант в принципе не может. А вот посмотрев даташит могу утверждать, что обе конструкции дадут идентичный эффект, тут разницы не будет, да. да ладно? А если немного подумать? Ничего что &= - это чтение-модификация-запись? И что будет, если в момент чтения какой-то другой бит-флаг был =0, а сразу после чтения он установился =1? Что с ним сделает команда записи? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Sergey_Aleksandrovi4 1 12 ноября, 2021 Опубликовано 12 ноября, 2021 · Жалоба Переменная period объявлена с квалификатором volatile? Ещё такой тупой совет. Сделайте в обработчике прерывания инверсию какого-либо свободного GPIO выхода и посмотрите логическим анализатором на то, как и когда вызывается обработчик при захвате сигнала. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sith633 0 12 ноября, 2021 Опубликовано 12 ноября, 2021 · Жалоба 1 час назад, Sergey_Aleksandrovi4 сказал: Переменная period объявлена с квалификатором volatile? Да Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Wasserati 0 13 ноября, 2021 Опубликовано 13 ноября, 2021 · Жалоба 21 hours ago, jcxz said: да ладно? А если немного подумать? Ничего что &= - это чтение-модификация-запись? И что будет, если в момент чтения какой-то другой бит-флаг был =0, а сразу после чтения он установился =1? Что с ним сделает команда записи? Если подумать, то согласен, что приведенный мной вариант не правильный. Возможность изменения статусных бит за время чтения-модификации-записи я не учел. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sith633 0 15 ноября, 2021 Опубликовано 15 ноября, 2021 · Жалоба 12.11.2021 в 20:35, Sergey_Aleksandrovi4 сказал: Переменная period объявлена с квалификатором volatile? Ещё такой тупой совет. Сделайте в обработчике прерывания инверсию какого-либо свободного GPIO выхода и посмотрите логическим анализатором на то, как и когда вызывается обработчик при захвате сигнала. Совет оказался дельным, я, признаться, об этом как-то не подумал. Прерывания срабатывали как надо, все дело в printf было и в методе отладки(я использовал семихостинг и тыкал эти принты куда только можно) Разобравшись в том почему printf недопустима, я ее отовсюду убрал и... Все тут же заработало. Всем откликнувшимся спасибо. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться