TmYAG 0 17 марта, 2016 Опубликовано 17 марта, 2016 (изменено) · Жалоба Всем привет! Изучаю таймеры. Перешел к изучению режима захвата. В программе дрыгаю светодиодами с задержкой 5 сек. попутно таймером TIM3 первый канал которого находится на PA6 пытаюсь захватить сигнал со светодиода, что живет на PD12. Просто замыкаю эти две ноги. #include "stm32f4xx.h" // Device header void init_gpio(void); void init_timer(void); void led_blinking(void); static volatile uint32_t TimeTick; volatile int capture1; volatile int capture2; void SysTick_Handler() { if(TimeTick) { TimeTick--; } } void TIM3_IRQHandler(){ if(TIM3->SR&2){ } } int main(){ SysTick_Config(SystemCoreClock/1000); init_gpio(); init_timer(); while(1){ led_blinking(); } } void init_gpio(){ /*Configure pins 12, 13, 14, 15 on port D*/ RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN; GPIOD->MODER = 0x55000000; /*Cofigure TIM3, Channel 1 (PA6)*/ RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; GPIOA->MODER = GPIO_MODER_MODER6_0; GPIOA->AFR[0] = 0x02000000; } void init_timer(){ RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; TIM3->CCMR1 |= TIM_CCMR1_CC1S_0; // CH1 to PA6 TIM3->CCMR1 |= (TIM_CCMR1_IC1F_0 | TIM_CCMR1_IC1F_1); // TIM3->CCER &= ~TIM_CCER_CC1P; TIM3->CCER &= ~TIM_CCER_CC1NP; TIM3->CCMR1 &= ~TIM_CCMR1_IC1PSC; // TIM3->CCER |= TIM_CCER_CC1E; // TIM3->DIER |= TIM_DIER_CC1IE; // TIM3->CR1 |= TIM_CR1_CEN; // NVIC_EnableIRQ(TIM3_IRQn); } void DelaymS(uint32_t time){ TimeTick = time; while(TimeTick); } void led_blinking(){ GPIOD->BSRRH = GPIO_BSRR_BS_12 | GPIO_BSRR_BS_13 | GPIO_BSRR_BS_14 | GPIO_BSRR_BS_15; //LEDs On DelaymS(5000);//Delay using SysTick GPIOD->BSRRL = GPIO_BSRR_BS_12 | GPIO_BSRR_BS_13 | GPIO_BSRR_BS_14 | GPIO_BSRR_BS_15; //LEDs Off DelaymS(5000); } Настроил порт Д и диоды. Настроил порт А и для шестой ноги определил альтернативную функцию. Настроил таймер в режиме захвата, захват по фронту. Но почему-то не заходит в прерывание. Период изменения сигнала для светодиодов 5 сек. Где я мог ошибиться? Изменено 17 марта, 2016 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 17 марта, 2016 Опубликовано 17 марта, 2016 · Жалоба Как минимум, ошибка здесь: ARR[15:0]: Prescaler value ARR is the value to be loaded in the actual auto-reload register. The counter is blocked while the auto-reload value is null Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Tarbal 4 18 марта, 2016 Опубликовано 18 марта, 2016 (изменено) · Жалоба Прерывания разрешили? Остановите в отладчике и посмотрите содержимое регистра разрешения -- флаг разрешения и флаг прерывания. Если нет хотя бы одного, то прерывания не будет. То какого нет даст информацию, что не сделано. Изменено 18 марта, 2016 пользователем IgorKossak бездумное цитирование Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alechek 0 18 марта, 2016 Опубликовано 18 марта, 2016 · Жалоба Чтобы не плодить темы... Вот думаю, как АТОМАРНО считать значение таймера и обнулить его? Потеря счетных импульсов недопустима! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 18 марта, 2016 Опубликовано 18 марта, 2016 · Жалоба Вот думаю, как АТОМАРНО считать значение таймера и обнулить его? Потеря счетных импульсов недопустима! Такие сферические вопросы в вакууме плохо помогают приблизиться к решению задачи. Что сделать-то надо? А вообще вот вам сферический ответ в вакууме: сконфигурируйте таймер так, чтобы сигнал на одном из его входов вызывал и захват, и сброс. И надейтесь, что захват произойдёт раньше сброса :laughing: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Tarbal 4 18 марта, 2016 Опубликовано 18 марта, 2016 · Жалоба Чтобы не плодить темы... Вот думаю, как АТОМАРНО считать значение таймера и обнулить его? Потеря счетных импульсов недопустима! Если вам надо измерять временные интервалы, то input capture это все что надо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AleksBak 0 19 марта, 2016 Опубликовано 19 марта, 2016 · Жалоба Чтобы не плодить темы... Вот думаю, как АТОМАРНО считать значение таймера и обнулить его? Потеря счетных импульсов недопустима! Вот я думал-думал и так и не придумал зачем может такая вещь понадобиться? Это получается, что "все равно, что считываю из Таймера - лишь бы как только считал значение, то сразу обнулился бы этот Таймер!". Так получается. Т.е. тут будут какие-то программные задержки на обращение/считывание значения из Таймера и Вам на них плевать, а обнулить все равно хочется точно в момент считывания. Если Вам нужно организовать подсчет длины внешнего импульса и по возникшему прерыванию считываете значение Таймера (сразу его обнулив при этом), то лучше напрямую захват сделать! А если Вы какие-то длительности внутренних процессов подсчитываете, то все равно так не делают ка Вы хотите. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alechek 0 20 марта, 2016 Опубликовано 20 марта, 2016 · Жалоба Таймер в режиме счетчика. Нужен подсчет внешних импульсов. В произвольный момент берется значение и отсылается далее, далее счет начинается заново. Пока делается отдельными операциями: считать значение таймера, обнулить значение таймера. Но, неправильно это.. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 20 марта, 2016 Опубликовано 20 марта, 2016 · Жалоба Таймер в режиме счетчика. Нужен подсчет внешних импульсов. В произвольный момент берется значение и отсылается далее, далее счет начинается заново. Не нужно для этого сбрасывать счётчик. Запоминаем последнее считанное значение, в следующий раз вычитаем его. Учитываем переполнения, естественно. Сброс-то зачем? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alechek 0 20 марта, 2016 Опубликовано 20 марта, 2016 · Жалоба Вредная привычка экономить память и процессорные такты... Да, видимо, буду запоминать. Есть, правда, мысля еще попробовать запретить работу таймера, считать-сбросить, разрешить работу. При разрешении, таймер, возможно, отработает смену входного уровня, если она произойдет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 20 марта, 2016 Опубликовано 20 марта, 2016 · Жалоба Вредная привычка экономить память и процессорные такты... До добра не доведёт. Бросайте это гиблое дело. Какие такие такты? Их сейчас раздают по 100 млн шт. в секунду. Не говоря уже о том, что копеечку выиграешь, а рубль потеряешь. Впрочем, мне-то что? Думайте сами :laughing: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
TmYAG 0 21 марта, 2016 Опубликовано 21 марта, 2016 (изменено) · Жалоба Проблема была в том, что я неверно настроил пин на альтернативную функцию. GPIOA->MODER = GPIO_MODER_MODER6_1; должно быть А вот насчет установки предделителя PSC и значения ARR не уверен, что обязательно устанавливать. У меня и так и так работает. То есть мк уходит в прерывание. Может кто объяснить надо ли для захвата их настраивать? Далее решил разобраться а как же определить период сигнала. По идее в обработчике прерывания необходимо (сбросить флаг само собой) записать в переменную значение TIM3->CCR1, а затем вычислить разницу между предыдущим и следующим значениями. capture1 = capture2 = 0; capture2 = TIM3->CCR1; t = capture2 - capture1; Верно? Но почему-то t какая-то фигня пишется. HEX в DEC не забываю перевести. Изменено 21 марта, 2016 пользователем TmYAG Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться