Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F4+таймеры+захват
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
TmYAG
Всем привет!
Изучаю таймеры.
Перешел к изучению режима захвата.
В программе дрыгаю светодиодами с задержкой 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 сек.
Где я мог ошибиться?
esaulenka
Как минимум, ошибка здесь:

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
Цитата(TmYAG @ Mar 17 2016, 13:14) *



Прерывания разрешили?
Остановите в отладчике и посмотрите содержимое регистра разрешения -- флаг разрешения и флаг прерывания. Если нет хотя бы одного, то прерывания не будет. То какого нет даст информацию, что не сделано.
Alechek
Чтобы не плодить темы...
Вот думаю, как АТОМАРНО считать значение таймера и обнулить его? Потеря счетных импульсов недопустима!
scifi
Цитата(Alechek @ Mar 18 2016, 18:04) *
Вот думаю, как АТОМАРНО считать значение таймера и обнулить его? Потеря счетных импульсов недопустима!

Такие сферические вопросы в вакууме плохо помогают приблизиться к решению задачи. Что сделать-то надо?
А вообще вот вам сферический ответ в вакууме: сконфигурируйте таймер так, чтобы сигнал на одном из его входов вызывал и захват, и сброс. И надейтесь, что захват произойдёт раньше сброса laughing.gif
Tarbal
Цитата(Alechek @ Mar 18 2016, 19:04) *
Чтобы не плодить темы...
Вот думаю, как АТОМАРНО считать значение таймера и обнулить его? Потеря счетных импульсов недопустима!


Если вам надо измерять временные интервалы, то input capture это все что надо.
AleksBak
Цитата(Alechek @ Mar 18 2016, 19:04) *
Чтобы не плодить темы...
Вот думаю, как АТОМАРНО считать значение таймера и обнулить его? Потеря счетных импульсов недопустима!

Вот я думал-думал и так и не придумал зачем может такая вещь понадобиться? Это получается, что "все равно, что считываю из Таймера - лишь бы как только считал значение, то сразу обнулился бы этот Таймер!". Так получается. Т.е. тут будут какие-то программные задержки на обращение/считывание значения из Таймера и Вам на них плевать, а обнулить все равно хочется точно в момент считывания. Если Вам нужно организовать подсчет длины внешнего импульса и по возникшему прерыванию считываете значение Таймера (сразу его обнулив при этом), то лучше напрямую захват сделать! А если Вы какие-то длительности внутренних процессов подсчитываете, то все равно так не делают ка Вы хотите.
Alechek
Таймер в режиме счетчика. Нужен подсчет внешних импульсов. В произвольный момент берется значение и отсылается далее, далее счет начинается заново.
Пока делается отдельными операциями: считать значение таймера, обнулить значение таймера. Но, неправильно это..
scifi
Цитата(Alechek @ Mar 20 2016, 07:48) *
Таймер в режиме счетчика. Нужен подсчет внешних импульсов. В произвольный момент берется значение и отсылается далее, далее счет начинается заново.

Не нужно для этого сбрасывать счётчик. Запоминаем последнее считанное значение, в следующий раз вычитаем его. Учитываем переполнения, естественно. Сброс-то зачем?
Alechek
Вредная привычка экономить память и процессорные такты...
Да, видимо, буду запоминать.
Есть, правда, мысля еще попробовать запретить работу таймера, считать-сбросить, разрешить работу. При разрешении, таймер, возможно, отработает смену входного уровня, если она произойдет.
scifi
Цитата(Alechek @ Mar 20 2016, 19:20) *
Вредная привычка экономить память и процессорные такты...

До добра не доведёт. Бросайте это гиблое дело. Какие такие такты? Их сейчас раздают по 100 млн шт. в секунду. Не говоря уже о том, что копеечку выиграешь, а рубль потеряешь. Впрочем, мне-то что? Думайте сами laughing.gif
TmYAG
Проблема была в том, что я неверно настроил пин на альтернативную функцию.
Код
GPIOA->MODER = GPIO_MODER_MODER6_1;
должно быть
А вот насчет установки предделителя PSC и значения ARR не уверен, что обязательно устанавливать. У меня и так и так работает. То есть мк уходит в прерывание. Может кто объяснить надо ли для захвата их настраивать?

Далее решил разобраться а как же определить период сигнала.
По идее в обработчике прерывания необходимо (сбросить флаг само собой) записать в переменную значение TIM3->CCR1, а затем вычислить разницу между предыдущим и следующим значениями.
Код
capture1 = capture2 = 0;
    capture2 = TIM3->CCR1;
    t = capture2 - capture1;

Верно?
Но почему-то t какая-то фигня пишется. HEX в DEC не забываю перевести.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.