реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
TmYAG
сообщение Mar 17 2016, 09:14
Сообщение #1





Группа: Участник
Сообщений: 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] - для короткого!
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Mar 17 2016, 09:44
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Как минимум, ошибка здесь:

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


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
Tarbal
сообщение Mar 18 2016, 14:41
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439



Цитата(TmYAG @ Mar 17 2016, 13:14) *



Прерывания разрешили?
Остановите в отладчике и посмотрите содержимое регистра разрешения -- флаг разрешения и флаг прерывания. Если нет хотя бы одного, то прерывания не будет. То какого нет даст информацию, что не сделано.

Сообщение отредактировал IgorKossak - Mar 18 2016, 18:15
Причина редактирования: бездумное цитирование
Go to the top of the page
 
+Quote Post
Alechek
сообщение Mar 18 2016, 15:04
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 241
Регистрация: 15-11-05
Из: Челябинск
Пользователь №: 10 882



Чтобы не плодить темы...
Вот думаю, как АТОМАРНО считать значение таймера и обнулить его? Потеря счетных импульсов недопустима!
Go to the top of the page
 
+Quote Post
scifi
сообщение Mar 18 2016, 15:13
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



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

Такие сферические вопросы в вакууме плохо помогают приблизиться к решению задачи. Что сделать-то надо?
А вообще вот вам сферический ответ в вакууме: сконфигурируйте таймер так, чтобы сигнал на одном из его входов вызывал и захват, и сброс. И надейтесь, что захват произойдёт раньше сброса laughing.gif
Go to the top of the page
 
+Quote Post
Tarbal
сообщение Mar 18 2016, 18:15
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439



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


Если вам надо измерять временные интервалы, то input capture это все что надо.
Go to the top of the page
 
+Quote Post
AleksBak
сообщение Mar 19 2016, 07:57
Сообщение #7


Частый гость
**

Группа: Участник
Сообщений: 132
Регистрация: 6-02-16
Из: г. Баку
Пользователь №: 90 364



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

Вот я думал-думал и так и не придумал зачем может такая вещь понадобиться? Это получается, что "все равно, что считываю из Таймера - лишь бы как только считал значение, то сразу обнулился бы этот Таймер!". Так получается. Т.е. тут будут какие-то программные задержки на обращение/считывание значения из Таймера и Вам на них плевать, а обнулить все равно хочется точно в момент считывания. Если Вам нужно организовать подсчет длины внешнего импульса и по возникшему прерыванию считываете значение Таймера (сразу его обнулив при этом), то лучше напрямую захват сделать! А если Вы какие-то длительности внутренних процессов подсчитываете, то все равно так не делают ка Вы хотите.
Go to the top of the page
 
+Quote Post
Alechek
сообщение Mar 20 2016, 04:48
Сообщение #8


Профессионал
*****

Группа: Свой
Сообщений: 1 241
Регистрация: 15-11-05
Из: Челябинск
Пользователь №: 10 882



Таймер в режиме счетчика. Нужен подсчет внешних импульсов. В произвольный момент берется значение и отсылается далее, далее счет начинается заново.
Пока делается отдельными операциями: считать значение таймера, обнулить значение таймера. Но, неправильно это..
Go to the top of the page
 
+Quote Post
scifi
сообщение Mar 20 2016, 06:21
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Alechek @ Mar 20 2016, 07:48) *
Таймер в режиме счетчика. Нужен подсчет внешних импульсов. В произвольный момент берется значение и отсылается далее, далее счет начинается заново.

Не нужно для этого сбрасывать счётчик. Запоминаем последнее считанное значение, в следующий раз вычитаем его. Учитываем переполнения, естественно. Сброс-то зачем?
Go to the top of the page
 
+Quote Post
Alechek
сообщение Mar 20 2016, 16:20
Сообщение #10


Профессионал
*****

Группа: Свой
Сообщений: 1 241
Регистрация: 15-11-05
Из: Челябинск
Пользователь №: 10 882



Вредная привычка экономить память и процессорные такты...
Да, видимо, буду запоминать.
Есть, правда, мысля еще попробовать запретить работу таймера, считать-сбросить, разрешить работу. При разрешении, таймер, возможно, отработает смену входного уровня, если она произойдет.
Go to the top of the page
 
+Quote Post
scifi
сообщение Mar 20 2016, 18:38
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Alechek @ Mar 20 2016, 19:20) *
Вредная привычка экономить память и процессорные такты...

До добра не доведёт. Бросайте это гиблое дело. Какие такие такты? Их сейчас раздают по 100 млн шт. в секунду. Не говоря уже о том, что копеечку выиграешь, а рубль потеряешь. Впрочем, мне-то что? Думайте сами laughing.gif
Go to the top of the page
 
+Quote Post
TmYAG
сообщение Mar 21 2016, 05:57
Сообщение #12





Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd June 2025 - 01:42
Рейтинг@Mail.ru


Страница сгенерированна за 0.01438 секунд с 7
ELECTRONIX ©2004-2016