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

Re: частотомер на GD32f303c

Ср ноя 08, 2023 22:26:26

На двух таймерах 32 бит все просто, нужно так называемый обратный счет реализовать на таймерах 16 бит, желательно без старт стопов.

Re: частотомер на GD32f303c

Чт ноя 09, 2023 12:26:56

linkov1959, для реализации обратного счета только аппаратными средствами МК нужны минимум 3 таймера, 2 из которых должны быть 32х битные. Полноценный 32х битный таймер легко делается из двух 16ти битных аппаратным объединением.

Вот как сделано в RLC-71:
- входной сигнал заведён на каналы захвата таймеров T1, T2. Захваты по фронту.
- T1. Входной триггер - запуск от канала захвата (Trigger Mode). Выходной триггер - активация при включении (Enable(CNT_EN)). Тактовый сигнал - системная частота. Этот таймер только запускает и останавливает остальную связку синхронно с входным сигналом.
- T2 (32х битный). Входной триггер (ITR0 от T1) - тикаем пока активно (Gated Mode). Тактовый сигнал - системная частота. Этот таймер подсчитывает количество перепадов опорной частоты от первого до последнего фронта входного сигнала. Бит переполнения можно использовать в качестве полноценного 33го бита счётчика. В МК STM32F303 этот таймер можно тактировать частотой, вдвое большей, чем системная.
- T4. Входной триггер (ITR0 от T1) - тикаем пока активно (Gated Mode). Выходной триггер - переполнения (Update).Тактовый сигнал - нога ETR. Этот таймер подсчитывает количество входных фронтов, младшая часть.
- T3. Входной триггер (ITR3 от T4) - тактирование. Старшая часть T4. Бит переполнения можно использовать в качестве полноценного 33го бита счётчика.

Алгоритм измерения (все таймеры остановлены):
1. обнуляем регистры.
2. разрешаем TRGI таймера T1.
3. следующим фронтом входного сигнала Т1 запускается сам и запускает остальную связку.
4. ничего не делаем требуемый интервал измерения, но не больше, чем двойное переполнение T2.
5. запрещаем TRGI таймера T1, затем останавливаем его.
6. из T2_CCRx вытаскиваем количество перепадов опорной частоты на момент последнего фронта входного сигнала.
7. из T3,T4 вытаскиваем количество пришедших входных фронтов.
8. вычисляем частоту и идём на п.1.

А алгоритм без остановки таймеров это по сути конвейерный режим. Даже на достаточно развесистом STM32F446 без дополнительного обвеса мне такого не удалось. Только с внешней логикой.

ЗЫ: кстати при измерении частоты методом обратного счёта, асинхронные входные делители не уменьшают разрядность результата.

Re: частотомер на GD32f303c

Чт ноя 09, 2023 19:32:29

Andrey_B, это то, что нужно, займусь стартстопом на GD. Но должен сказать что на 401м на таймерах 32бит конвейерный режим работает без всяких ухищрений. Будет отдельная тема со всеми подробностями. Будет вариант на 743м.

Re: частотомер на GD32f303c

Пт ноя 10, 2023 15:27:22

Andrey_B, //- T1. Входной триггер - запуск от канала захвата (Trigger Mode).// А источник ETR?
//- T2 (32х битный). Входной триггер (ITR0 от T1) - тикаем пока активно (Gated Mode). Тактовый сигнал - системная частота.// Это из него берем CCR. Канал input capture включаем? Тогда три входа выходит?
Для отсчета интервала измерения ещё нужен один таймер и в прерывании пишем прогу начиная с п.5 и заканчивая п.2?
Как разрешить TRGI?

Re: частотомер на GD32f303c

Пт ноя 10, 2023 19:27:45

linkov1959, входной сигнал, кроме T1_CCR1 и T2_CCR1 заведён ещё и на T4_ETR. Да, входной сигнал приходит на 3 пина МК, не указал это явно.

Интервал можно чем угодно отсчитывать, хоть программно. Его выдерживать точно не нужно, он всё равно будет немного "гулять" в зависимости от числа целых периодов входного сигнала, которые в него уложатся. В прерывании это сделать или тупо в функции вывода значения на дисплей - не важно.

По TRGI:
Код:
#define TIM_SlaveMode_Trigger                     ((uint32_t)0x00006)

TIM1->SMCR &= (uint32_t)~TIM_SMCR_SMS; // запрет
TIM1->SMCR |= TIM_SlaveMode_Trigger; // разрешение

Re: частотомер на GD32f303c

Пт ноя 10, 2023 20:23:16

Andrey_B, Как в кубе выставить запуск TIM1 от канала захвата?
Что выбрать источником Trigger Mode?
tim1.jpg
(48.34 KiB) Скачиваний: 31

Re: частотомер на GD32f303c

Сб ноя 11, 2023 12:57:50

linkov1959,
Изображение

Re: частотомер на GD32f303c

Сб ноя 11, 2023 20:59:27

Andrey_B, В том то и дело, что TI1FP1 у меня не выбирается.
Теперь понял! Канал выбирать не нужно, он автоматом задействован.

Добавлено after 7 hours 31 minute 2 seconds:
Получилось на GD сделать частотомер с обратным счетом! Андрею спасибо!

Добавлено after 20 minutes 23 seconds:
Тактовая 256 Мгц на кварце 16Мгц. На STM32H743 больше 200Мгц таймеры не тянут, а проц дорогой. Время измерения пока простой задержкой сделал, завтра что-то придумаю, один таймер в запасе есть, а еще попробую TIM1 для этого использовать.

Re: частотомер на GD32f303c

Пн ноя 13, 2023 11:11:59

Andrey_B, На реальном сигнале гуляет фаза:(
Может тут ошибка?
/* USER CODE BEGIN 2 */
HAL_TIM_IC_Start(&htim1, TIM_CHANNEL_1);
HAL_TIM_Base_Start(&htim2);//считает импульсы пока на 1кГц без каскада.
HAL_TIM_IC_Start(&htim4, TIM_CHANNEL_1);// считает тики в каскаде с ТИМ3.
HAL_TIM_Base_Start(&htim3);

while (1)
{
TIM3->CNT=0;
TIM4->CNT=0;
TIM4->CCR1=0;
TIM1->CNT=0;
TIM2->CNT=0;

TIM1->SMCR |= ((uint32_t)0x00006); // разрешение
HAL_Delay(500);
TIM1->SMCR &= (uint32_t)~TIM_SMCR_SMS; // запрет
HAL_TIM_IC_Stop(&htim1, TIM_CHANNEL_1);
imp=TIM2->CNT;
tic = TIM4->CCR1 + (TIM3->CNT << 16);
f1=320000000.0/tic;
f1=f1*imp;
snprintf(txt, 16,"%.4fHz ", f1);
ST7735_WriteString(0, 0,txt , Font_11x18, ST7735_GREEN, ST7735_BLACK);

https://drive.google.com/file/d/1ImeL_U ... sp=sharing

Re: частотомер на GD32f303c

Вт ноя 14, 2023 00:47:38

linkov1959, TIM2 должен совершать захваты по фронтам fx и тактироваться от f0. TIM3/TIM4 тактируются от fx, захваты не совершают. Останавливать TIM1 лучше не функцией HAL, а просто сбросом бита.
Вычисления лучше выполнить так:
Код:
#define  SYSTEMCORECLOCK  256000000UL
double fx;

fx = SYSTEMCORECLOCK * (((uint64_t)TIM3->CNT << 16) + TIM4->CNT);
fx /= TIM2->CCR1;

Re: частотомер на GD32f303c

Вт ноя 14, 2023 11:01:16

Andrey_B, У меня ETR есть только у TIM2 и он считает импульсы, а TIM4 в каскаде с TIM3 считает f0 с захватом. Попробовал время измерения без Delay на таймере , фаза плывет, но очень медленно, 99% показаний стабильны. Если бы счетчик тиков был 32бит, то вообще нет проблем. На большинстве частот фаза гуляет туда-сюда и показания стабильны 100%.

Re: частотомер на GD32f303c

Вт ноя 14, 2023 11:40:27

linkov1959, тогда fx должен быть заведён на обе половинки таймера. Т.е. захват должен быть и по TIM3, и по TIM4.

Re: частотомер на GD32f303c

Вт ноя 14, 2023 14:12:57

Получилось на GD сделать частотомер с обратным счетом!

Это прямой счет, при обратном счете измеряется период, а обратная ему величина и есть искомая частота, а у вас один таймер считает тики опорной частоты и это дает время измерения(TIM2->CCR1 / SYSTEMCORECLOCK), а второй считает фронты входного сигнала пришедшие за это время.

Re: частотомер на GD32f303c

Вт ноя 14, 2023 14:38:52

Reflector, а если придёт всего 2 входных тика, между которыми будет 1000010 системных тиков, соответственно в таймерах будут значения 1 и 1000010. fx = 100МГц * 1 / 1000010 = 99.99900001Гц. Это прямой счёт или обратный?
:-)

Re: частотомер на GD32f303c

Вт ноя 14, 2023 14:53:55

а если придёт всего 2 входных тика, между которыми будет 1000010 системных тиков, соответственно в таймерах будут значения 1 и 1000010. fx = 100МГц * 1 / 1000010 = 99.99900001Гц.

Разобрался, у тебя таки обратный, потому что используется TIM2->CCR1, т.е. количество тиков опорной до последнего внешнего фронта, а у linkov1959 было TIM2->CNT - это уже прямой счет :)

Re: частотомер на GD32f303c

Вт ноя 14, 2023 16:46:46

linkov1959, тогда fx должен быть заведён на обе половинки таймера. Т.е. захват должен быть и по TIM3, и по TIM4.

Это мысль! На счет того, что у меня не обратный счет, это фигня, просто таймеры другие. В моем конвейерном алгоритме может и так. Я бы этот метод назвал частотно-периодным.
С GD выжал 320 Мгц и с этим нужно что-то делать кроме частотомера, например фильтры, где нужно работать с Float. Хочу проверить, на что GD способны. Если тупо умножать float, то 1лимон в секунду, деление 5 раз медленнее. По даташиту GD303 поддерживает float аппаратно, с этим нужно разобраться.

Re: частотомер на GD32f303c

Ср ноя 15, 2023 12:23:13

Что бы работать с float нужно к числу добавлять f, например 1.234f, тогда быстрее даже без FPU. Если не добавлять, то FPU не работает. GD показал 3 лимона на умножении и 2 лимона на делении без FPU, в кубе не включилось. На stm401 с FPU 3.5 и 2.5 лимона в секунду. GD работал на 320 Мгц, stm401 на 125 Мгц.

Re: частотомер на GD32f303c

Чт ноя 16, 2023 12:56:13

Если в операциях использовать только переменные float без констант, то получаются другие данные. Считал операции типа f1=f1/f2, деление с присвоением.
GD303 без FPU, 320Мгц - 500000 оп/сек
STM32f401 c FPU, 125Мгц - 5000000 оп/сек
STM32h743 c FPU 400Мгц - 10000000 оп/сек(маловато что-то)
Нужно найти возможность включить FPU в GD, если оно там есть.
В CubeIDE FPU включено по умолчанию, если оно есть, никаких танцев с бубнами, но с GD куб работает, как с F1** и никаких FPU.

Добавлено after 59 minutes 10 seconds:
linkov1959, тогда fx должен быть заведён на обе половинки таймера. Т.е. захват должен быть и по TIM3, и по TIM4.

Это сработало, фаза стабильна, показания стабильны! Ура! На 320Мгц стабильны 7-8 знаков!

Re: частотомер на GD32f303c

Сб ноя 18, 2023 16:24:58

Нужно найти возможность включить FPU в GD, если оно там есть.

Даташит ни слова не говорит о наличии FPU. А даже совсем наоборот, говорит об ядре M4, а не M4F...
Важно какая величина WS у чипа. А FPU для частотомера ни разу не облокотился. Отлично все считается с фиксированной запятой.

Re: частотомер на GD32f303c

Сб ноя 18, 2023 19:52:24

FPU скорее всего в ГД303 есть.
На странице 30-31 мануала упоминается и
в оригинальной библиотеке от ГД для 303 подключается.

Если нужно FPU в Кубе наверно лучше использовать GD32F407 и прошивать под видом stm32f407.
Там и 32 бит таймера.
Разгон ГД407 не пробовал и цена не 100 руб а 350.

Задержка чтения памяти у ГД = 0 тактов до 256 кб
Ответить