|
|
  |
STM32F4+таймеры+захват |
|
|
|
Mar 17 2016, 09:14
|
Группа: Участник
Сообщений: 7
Регистрация: 23-12-14
Пользователь №: 84 246

|
Всем привет! Изучаю таймеры. Перешел к изучению режима захвата. В программе дрыгаю светодиодами с задержкой 5 сек. попутно таймером TIM3 первый канал которого находится на PA6 пытаюсь захватить сигнал со светодиода, что живет на PD12. Просто замыкаю эти две ноги. CODE #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 сек. Где я мог ошибиться?
Сообщение отредактировал IgorKossak - Mar 17 2016, 09:41
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!
|
|
|
|
|
Mar 18 2016, 14:41
|
Профессионал
    
Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439

|
Цитата(TmYAG @ Mar 17 2016, 13:14)  Прерывания разрешили? Остановите в отладчике и посмотрите содержимое регистра разрешения -- флаг разрешения и флаг прерывания. Если нет хотя бы одного, то прерывания не будет. То какого нет даст информацию, что не сделано.
Сообщение отредактировал IgorKossak - Mar 18 2016, 18:15
Причина редактирования: бездумное цитирование
|
|
|
|
|
Mar 19 2016, 07:57
|
Частый гость
 
Группа: Участник
Сообщений: 132
Регистрация: 6-02-16
Из: г. Баку
Пользователь №: 90 364

|
Цитата(Alechek @ Mar 18 2016, 19:04)  Чтобы не плодить темы... Вот думаю, как АТОМАРНО считать значение таймера и обнулить его? Потеря счетных импульсов недопустима! Вот я думал-думал и так и не придумал зачем может такая вещь понадобиться? Это получается, что "все равно, что считываю из Таймера - лишь бы как только считал значение, то сразу обнулился бы этот Таймер!". Так получается. Т.е. тут будут какие-то программные задержки на обращение/считывание значения из Таймера и Вам на них плевать, а обнулить все равно хочется точно в момент считывания. Если Вам нужно организовать подсчет длины внешнего импульса и по возникшему прерыванию считываете значение Таймера (сразу его обнулив при этом), то лучше напрямую захват сделать! А если Вы какие-то длительности внутренних процессов подсчитываете, то все равно так не делают ка Вы хотите.
|
|
|
|
|
Mar 20 2016, 16:20
|
Профессионал
    
Группа: Свой
Сообщений: 1 241
Регистрация: 15-11-05
Из: Челябинск
Пользователь №: 10 882

|
Вредная привычка экономить память и процессорные такты... Да, видимо, буду запоминать. Есть, правда, мысля еще попробовать запретить работу таймера, считать-сбросить, разрешить работу. При разрешении, таймер, возможно, отработает смену входного уровня, если она произойдет.
|
|
|
|
|
Mar 21 2016, 05:57
|
Группа: Участник
Сообщений: 7
Регистрация: 23-12-14
Пользователь №: 84 246

|
Проблема была в том, что я неверно настроил пин на альтернативную функцию. Код GPIOA->MODER = GPIO_MODER_MODER6_1; должно быть А вот насчет установки предделителя PSC и значения ARR не уверен, что обязательно устанавливать. У меня и так и так работает. То есть мк уходит в прерывание. Может кто объяснить надо ли для захвата их настраивать? Далее решил разобраться а как же определить период сигнала. По идее в обработчике прерывания необходимо (сбросить флаг само собой) записать в переменную значение TIM3->CCR1, а затем вычислить разницу между предыдущим и следующим значениями. Код capture1 = capture2 = 0; capture2 = TIM3->CCR1; t = capture2 - capture1; Верно? Но почему-то t какая-то фигня пишется. HEX в DEC не забываю перевести.
Сообщение отредактировал TmYAG - Mar 21 2016, 07:04
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|