Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

Re: Энкодер и STM32

Ср июн 21, 2023 15:42:49

Вот в чем дело: в коде будут участки на небольшой промежуток времени когда будут отключаться все прерывания, поэтому первый таймер не должен сбрасываться совсем, там должно оставаться фактическое значение, второй должен генерить прерывания. До DMA пока не дошёл, с таймерами не до конца ещё разобрался.
Но почему вам так не нравится тема: сопряжения 2 таймеров, если это заложено в камень?
Камень будет хорошо нагружен, поэтому я стараюсь всё лишнее максимально скинуть на аппаратную часть, чтобы прерывания были как можно реже и выходить из них как можно быстрее, выставил флаг и вышел, время появилось - обрабатываем флаг.

Re: Энкодер и STM32

Ср июн 21, 2023 20:14:42

alex_ писал(а):Но почему вам так не нравится тема: сопряжения 2 таймеров, если это заложено в камень?

Исходя из того, в каком виде озвучен вопрос, складывается стойкое ощущение, что ТС не понимает ни что ему нужно, ни работу таймеров. Ещё и пишет этот вопрос в нескольких темах.

У меня в проекте управления конвейером как раз таймеры соединены каскадами. Первый таймер формирует рампу разгона и торможения конвейера, что ессно, означает постоянное изменение частоты импульсов на его выходе, а второй считает импульсы на его выходе. Изменение частоты на первом таймере сделал программно, ибо при имеющихся параметрах оборудования хватает 3-7 ступеней переключения частоты, хотя, по-умному, можно сделать и через DMA, но выигрыш в быстродействии не стоит затрат времени на его реализацию.

Всё крутится под FreeRTOS, ессно, активно используются критические секции, что предполагает запрет прерываний, поэтому настроил приоритеты прерываний и организовал работу с периферией так, чтобы не возникало никаких блокировок и пропуска критических для работы оборудования сигналов. И да, таких пар таймеров работает 3 штуки, потому что кроме самого конвейера есть еще всякие податчики, плюс ещё 2 таймера со ступенчатым разгоном-торможением, когда частота изменяется через интервалы времени, отсчитываемые другим отдельным таймером. А ещё Эзернет, а ещё...
Камень будет хорошо нагружен,

Цикл обхода конечного автомата, управляющего всем этим, укладывается в 70мкс даже с отключенной оптимизацией и логгированием работы.

Рекомендую чётко сформулировать хотелки, ибо пока сам не можешь объяснить чё те надо, сделать это по-человечески не получится.

Re: Энкодер и STM32

Ср июн 21, 2023 23:21:22

Исходя из того, в каком виде озвучен вопрос, складывается стойкое ощущение, что ТС не понимает ни что ему нужно, ни работу таймеров.
Всё я понимаю, а вот стыковкой таймеров и их тактированием сталкиваюсь в первые. Была такая тема как синхронное использование таймеров(для шима вроде поднимался данный вопрос), вопрос в том что возможно ли это при подключении энкодера?
Поизучав мануал, пришёл к выводу, что в общую схему выходят только уже после делителя(переполнение счётчика или по сравнению со значением), жаль что этот такт нельзя напрямую проклучить на другой таймер :(
Ещё и пишет этот вопрос в нескольких темах.

Жалко тебе что ли, если ещё умные люди подлючатся,
А ещё Эзернет, а ещё...

Эзернет у меня тоже есть
Рекомендую чётко сформулировать хотелки, ибо пока сам не можешь объяснить чё те надо, сделать это по-человечески не получится.

В кратце: скорость транспортёра 1 м/с энкодер 5000 имп/оборот успевает сделать 3 оборота за 1 сек, 40 каналов АЦП в 12бит, считывать данные с АЦП нужно через каждый мм, и после того как объект выйдет из зоны датчиков, нужно все данные обработать в промежуточный результат и отправить всё по эзернету на пк(на это всего 100мс), на котором программа оптимизатор вычисляет что можно из этого сделать и передаёт данные на PLC, который это всё и сделает.
Такое описание подойдёт? Да и операционку не использую.

Добавлено after 50 minutes 33 seconds:
До этого было реализовано на pic32 80 МГц и каналов АЦП было в 3 раза меньше, работает он в притык, поэтому для этого проекта была выбрана STM32f407 но поскольку с STM до этого сталкивался, но мало работал, функционал и тактовая в 2 раза больше меня подкупили.
PIC довольно скудны в начинке, таймеров раза в 3 меньше и нет входа для энкодера, поэтому импульсы считает по прерыванию :?

Re: Энкодер и STM32

Чт июн 22, 2023 06:03:12

alex_ писал(а):вопрос в том что возможно ли это при подключении энкодера?

Можно. Просто меняется источник тактирования и способ счёта.
alex_ писал(а):жаль что этот такт нельзя напрямую проклучить на другой таймер

Потому что это не нужно. Не понятно, _для_чего_ нужен второй таймер. Есть таймер, есть модуль сравнения- что ещё надо?
alex_ писал(а):40 каналов АЦП в 12бит, считывать данные с АЦП нужно через каждый мм

Это можно сделать аппаратно, да ещё и через DMA, правда, с внешней обвязкой, ибо 40 каналов, да ещё и с Эзернетом, в МК не завести. Программно будет медленней, но не так уж чтобы это сильно нагрузило МК.
alex_ писал(а):В кратце...

Очень похоже на то, что было у меня, за исключением АЦП.

Re: Энкодер и STM32

Чт июн 22, 2023 07:44:34

Можно. Просто меняется источник тактирования и способ счёта.
С этого момента по подробнее, что надо на что поменять?
Не понятно, _для_чего_ нужен второй таймер.
Я художник, я так вижу :)))
Это можно сделать аппаратно, да ещё и через DMA
Можно только смысла особо нет, считываем данные с нескольких каналов АЦП, пересчитываем в физические значения, если они получились реальными(не мусор и не сбой датчика) тогда записываем в массив, после сканирования этот массив ещё раз обрабатывается, сжимая ещё в несколько раз данные, чтобы потом передать по Ethernet. Основная нагрузка здесь не чтение датчиков, а больше вычисления :solder:
Ethernet и АЦП внешние, на шине SPI

Re: Энкодер и STM32

Чт июн 22, 2023 09:07:39

alex_ писал(а):Я художник, я так вижу :)))

Тогда продолжайте сексоваться с таймерами дальше без шанса на взаимность.

Re: Энкодер и STM32

Чт июн 22, 2023 17:27:47

раз нужно - ну и разведите энкодер к обоим таймерам.

интереса ради: шаг Вашего энкодера - один импульс или последовательная смена 4-х состояний?

Re: Энкодер и STM32

Чт июн 22, 2023 22:18:59

Промышленный на 4 состояния, если я правильно понял физически подать на ножки контроллера 2 таймеров?
Была такая костыльная идея в моей голове))

Добавлено after 1 hour 43 minutes 23 seconds:
Правда не совсем хороший вариант получается.

Re: Энкодер и STM32

Пт июн 23, 2023 09:19:42

хотите позабористей, поехали
"кручу-верчу запутать хочу"...

открываем RM0090 смотрим TIMx_CR2 поле MMS[2:0]
че тут возьмешь, ну разве что Update.
берем первый таймер (TIM1) - ему в зубы энкодер: "так смотри за ним, досчитаешь до 5 дергай веревочку TIM1_TRGO".
так кто тут у нас за нее может подержаться - ага TIM2 и TIM3.
"ребята ходь сюды, держать TIM1_TRGO, дернется - пухнуть на щаг, а чтоб не забыли вот вам в душу TIMx_SMCR: TS[2:0]=000 и SMS[2:0]=111;
один пухни на сколько влезет, второй - вот тебе иголка, не вздумай раздуться больше чем в TIMx_ARR укажу"

как такая фантазия
:))

Re: Энкодер и STM32

Пт июн 23, 2023 10:48:23

Да вроде не плохая фантазия, пару моментов хотел уточнить:
- таймер обязательно должен быть Т1?
- в данном случае получается что по входу будет делитель на 5 а далее потом ещё Т2 и Т3 со своими делителями?
Кстати такая идея меня тоже посещала, повесить энкодер на один таймер, и дальше с него на два других, но тут я упёрся в тот момент что не получиться учитывать направление движения и использовать фактическое значение счётчика энкодера.
Как бы странно не звучало, но товарищ tonyk, предложил вариант не идеальный но пока ничего лучше мне не удалось найти.
Что получаем в итоге: на одну ногу 2 альтернативные функции повесить нельзя, а через счётчик это сразу попадаем на делитель, а если передаём следующему таймеру то лишаемся функционала режима энкодера(направление и фактическое положение)

Re: Энкодер и STM32

Пн июн 26, 2023 13:57:40

Решил реализовать вариант с регистром сравнения, хотел завести все 4 регистра, ну мало ли проскочу случайно. Вроде работает но смутило одно: почему то прерывание получаю только по каналам 3 и 4, 1 и 2 не вызывают обработчик прерывания :dont_know:
Как и должно быть или я в конфигурации накосячил?
Спойлер
Код:
   /* Encoder Initialization */
   /* TIM4 Clock */
   RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
   /* 01: CC1 channel is configured as input, IC1 is mapped on TI1
    * 01: CC2 channel is configured as input, IC2 is mapped on TI2 */
   TIM4->CCMR1 |= (TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0);
   TIM4->CCMR1 &= ~(TIM_CCMR1_CC1S_1 | TIM_CCMR1_CC2S_1);
   /* 00: noninverted/rising edge */
   TIM4->CCER &= ~(TIM_CCER_CC1P | TIM_CCER_CC2P);
   TIM4->CCER &= ~(TIM_CCER_CC2NP | TIM_CCER_CC2NP);
   /* 001: Encoder mode 1 - Counter counts up/down on TI2FP1 edge depending on TI1FP2 level */
   TIM4->SMCR |= TIM_SMCR_SMS_0;  // 001 считаем только по входу TI1 , ели надо по обоим то 011
   TIM4->SMCR |= TIM_SMCR_SMS_1;
   TIM4->SMCR &= ~TIM_SMCR_SMS_2;
   /* 1111: fSAMPLING = fDTS / 32, N = 8 */
   TIM4->CCMR1 |= (TIM_CCMR1_IC1F_0 | TIM_CCMR1_IC1F_1 | TIM_CCMR1_IC1F_2); //| TIM_CCMR1_IC1F_3);
   TIM4->CCMR1 |= (TIM_CCMR1_IC2F_0 | TIM_CCMR1_IC2F_1 | TIM_CCMR1_IC2F_2); //| TIM_CCMR1_IC2F_3);

   TIM4->CCMR1 &=~TIM_CCMR1_IC1F_3;//уменьшили уже не 32x8
   TIM4->CCMR2 &=~TIM_CCMR1_IC2F_3;

   /* Auto-Reload Register (MAX counter number) */
   TIM4->ARR = 0xffff;//30;


   //разрешаем прерывание от таймера 4
   NVIC_EnableIRQ(TIM4_IRQn);
   NVIC_SetPriority (TIM4_IRQn, 5);

   TIM4->DIER |= TIM_DIER_CC1IE | TIM_DIER_CC2IE | TIM_DIER_CC3IE | TIM_DIER_CC4IE;// включаем прерывание по совпадению

   TIM4->CCR1 = 1000;
   TIM4->CCR2 = 2000;
   TIM4->CCR3 = 3000;
   TIM4->CCR4 = 4000;

   /* 1: Counter enabled */
   TIM4->CR1 |= TIM_CR1_CEN;
//----------
//ну и сам обработчик прерывания
void TIM4_IRQHandler(void)
{

   sprintf(txt, "%d", (unsigned int)TIM4->CNT);
   UART3_Write_Text((unsigned char*)txt);UART3_Write_Text((unsigned char*)"\t");

   if(TIM4->SR & TIM_SR_UIF){
      TIM4->SR = ~TIM_SR_UIF;

   }

   if(TIM4->SR & TIM_SR_CC1IF){
      TIM4->SR = ~TIM_SR_CC1IF;
      UART3_Write_Text((unsigned char*)"CC1IF\r\n");
      LED2_INV();
   }

   if(TIM4->SR & TIM_SR_CC2IF){
      TIM4->SR = ~TIM_SR_CC2IF;
      UART3_Write_Text((unsigned char*)"CC2IF\r\n");
      LED2_INV();
   }

   if(TIM4->SR & TIM_SR_CC3IF){
      TIM4->SR = ~TIM_SR_CC3IF;
      UART3_Write_Text((unsigned char*)"CC3IF\r\n");
      LED2_INV();
   }

   if(TIM4->SR & TIM_SR_CC4IF){
      TIM4->SR = ~TIM_SR_CC4IF;
      UART3_Write_Text((unsigned char*)"CC4IF\r\n");
      LED2_INV();
   }


}
Ответить