Перейти к содержанию
    

STM32 управление мостами

Может чтобы обойти проблему со считыванием из флеша длинного кода попробовать по-другому: взять два цикла с одним и с двумя НОПами, и в зависимости от величины задержки крутить оба цикла с разной длиной параметров.

 

Я попробовал это на другой архитектуре (esp32), не могу сказать, что стоит как вкопанное, так как много другого дергается попутно, но у Вас может и будет с точностью до такта получаться.

 

Сам код:

 

#pragma GCC push_options
#pragma GCC optimize ("Ofast")

#include <stdio.h>
#include <math.h>
#include <Arduino.h>


static int NOP_Param_1=6;
static int NOP_Param_2=6;

void nop_delay1(unsigned int t1, unsigned int t2)
{ unsigned int i;
  i=t1;
  while(i>0)
  { asm("nop");
    i--;
  }
  i=t2;
  while(i>0)
  { asm("nop");
    asm("nop");
    i--;
  }
  return;
}

// total time is: t1*C1 + t2*(C1+1) + C2, where NOP_Param_1 = C1, NOP_Param_2 = C2.
// (t1+t2)*C1 + t2 = time - C2;
void nop_delay(unsigned int time)
{ unsigned int q = time - NOP_Param_2;
  unsigned int q2 = q/NOP_Param_1;
  unsigned int q1 = q - q2*NOP_Param_1;
  nop_delay1(q1, q2-q1);
}


unsigned int nop_delay_ini1(unsigned int time)
{ unsigned int begin, end;
  RSR(CCOUNT, begin);
  nop_delay(time);
  RSR(CCOUNT, end);
  return end-begin-1;
}


void test()
{ unsigned int TestVal[]={1000, 10000, 20000, 1999, 8999, 12345};

  for(int j=0; j<3; j++)
    for(int i=0; i<sizeof(TestVal)/sizeof(TestVal[0]); i++)
      Serial.printf("%d %d\n", TestVal[i], nop_delay_ini1(TestVal[i]));
}


void setup()
{ Serial.begin(115200);
  Serial.printf("Starting ini\n");
}

int count=0;

void loop()
{ test();
  Serial.printf("count=%d\n", count++);
  delay(2000);
}

#pragma GCC pop_options

 

В коде два важных параметра (NOP_Param_1, NOP_Param_2) которые надо подобрать под ваш контроллер - первый - длительность в тактах цикла с одним НОПом, второй - общая задержка. Также замечу, что код не сможет работать если надо отмерить только несколько тактов и примерно работает от 30-40 тактов задержек (если NOP_Param_1/2 как у меня).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

46 minutes ago, iiv said:

Я попробовал это на другой архитектуре

Любое while моментально увеличивает шаг до 30кгц, это описано в самом первом моем посте, тут счет идет на единичные такты,

для более низкой частоты while может и пройдет но на 500кгц нет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 minutes ago, whale said:

Любое while моментально увеличивает шаг до 30кгц, это описано в самом первом моем посте, тут счет идет на единичные такты,

вы все-таки хотя бы немного задумайтесь что именно я вам советую. Я же не зря специально для вашего случая пару часов кодил и тестировался. У меня точность в один такт разрешение моего таймера получается.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Just now, iiv said:

в один такт разрешение моего таймера получается.

где тут один такт ? 

 

while(i>0)
  { asm("nop");
    i--;
  }

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, whale said:

где тут один такт ? 

Прочитайте внимательно что я вам посоветовал не выдирая из всего кода кусочки, и вам обязательно откроется тайна одного такта 🙂

Для тех, кто совсем в танке, повторяю: два цикла с длительностью (С) первого на один такт меньше, чем второй (С+1). Для любой величины задержки T>C^2 всегда можно выбрать такие два числа t1, t2, так, что C*t1 + (C+1)*t2 = T.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Неполное. Впрочем, перевести 39 страниц - дня на 2 работы...
Можно я гугл-транслэйтом? Мандаринский учить пока не стану (((-8Ж

Разве она чем-то отличается от SI5351 ?
https://eax.me/stm32-si5351/

Ну как-бы похожа, но что там "чайные" добавили-выкинули сходу не скажу. SiLabs доку не отдаёт, пришлось брать на стороне.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А то, что микроконтроллер помимо генерации импульсов, должен еще чето делать, про это как бы вроде бы и забывают, да?

Вообще, чето это попытка натянуть сову на глобус. Можно же взять другой МК, с более высокой тактовой частотой. У новых МК есть HRTIM, например. Или вообще даже попробовать микросхему-синтезатор сетки частот.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, EdgeAligned сказал:

А то, что микроконтроллер помимо генерации импульсов, должен еще чето делать, про это как бы вроде бы и забывают, да?

Автор сам с этим не определился еще:

В 19.08.2024 в 15:33, whale сказал:

Вы думаете процессор все это время отдыхает ? Вы заблуждаетесь.

В 19.08.2024 в 15:58, whale сказал:

На период вывода все запрещено.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

8 hours ago, iiv said:

t1, t2, так, что C*t1 + (C+1)*t2 = T.

Видно не понимаем друг друга, мне нужно генерировать меандр с временем между изменениями порта = одному такту, двум тактам, трем тактам итд а не с точностью один такт + 100500 тактов

Кто нить может объяснить как загнать функция в ram в iar а потом ее исполнить в коде, хочу попробовать.

Просто __ramfunc void (int){nop;nop; .....}

а потом вызывам delay(1); 

или еще что то нужно указать линкеру ?

Изменено пользователем whale

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Технически это возможно, если написать РАЗНЫЕ функции генерации, и желательно без циклов. То есть, где нужно быстро дергать ногой, там напрямую импульсы без циклов и условий. А там, где процессорного времени будет достаточно, там можно и циклы, и условия перехода. Только все это нужно проверять и подгонять.

Вообще, следует выбрать другой вариант решения, а не натягивать совв на глобус.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

16 minutes ago, whale said:

Видно не понимаем друг друга, мне нужно генерировать меандр с временем между изменениями порта = одному такту, двум тактам, трем тактам итд а не с точностью один такт + 100500 тактов

сделаю еще одну попытку прояснить вам мою идею. У вас stm32g070, у которого такт - 64МГц и вам нужен ногодрыг на 500кГц, то есть между переключениями у вас есть как минимум 64 такта. То, что я предлагаю, позволяет дозировать задержку с точностью до одного такта в диапазоне от 36 тактов до бесконечности. То есть вы с легкостью получите 500кГц, выставив 64 такта задержку, и 64/65/2*1000=492.3кГц, а если согласитесь на слегка не 50% форму сигнала, то и 64/129*1000=496.12кГц. Больше с этого дохлого контроллера взять не получится.

ЗЫ: хоть и мое решение занимает меньше страницы уже отлаженного кода, считаю, что ТС надо при таких хотелках задуматься о более жирном процессоре, а лучше плиске. Не рекламы ради, очень советую взять мелкий GoWin - на нем с легкостью можно сделать шаг в районе 500кГц вплоть до единиц Герцев, если конечно еще подавать слегка не равномерные длины окон тактовой.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Just now, iiv said:

500кГц

500 +-150 те 650 кгц минимум а лучше полосу  300-700 кгц.

Могу для эксперимента запрогать ваш вариант и он все покажет.

 

Ого а __ramfunc то работает без всяких бубнов, пропала неравномерность, можно считать задача решена.

Изменено пользователем whale

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Just now, iiv said:

сделаю еще одну попытку

Даже если ваш код заработает все равно он значительно больше чем текущий, и не факт что хватит до 650кгц так что до следующего раза, может кому нить еще пригодиться  )

Изменено пользователем whale

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

27 minutes ago, whale said:

300-700 кгц.

700кГц по идее должно потянуть, вернее если на вашем процессоре первый цикл тоже как у меня 6 тактов, то 888кГц и ниже все должно охватить.

 

2 minutes ago, whale said:

Даже если ваш код заработает все равно он значительно больше чем текущий

а чем он больше-то? У меня в страницу поместилось все со всеми тестами. Если говорить о том, что вам конкретно надо, так это только nop_delay1 и nop_delay2, которые займут примерно 50 байт в бинарнике. Я сомневаюсь, что простыня нопов и скачки по ним будут лучше, а то, что ваш метод дает вольность контроллеру не закачивать часть нопов из флеша, даст вам сказочные неприятности, у вас то будет работать, то не будет работать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5 hours ago, EdgeAligned said:

А то, что микроконтроллер помимо генерации импульсов, должен еще чето делать, про это как бы вроде бы и забывают, да?

Вообще, чето это попытка натянуть сову на глобус. Можно же взять другой МК, с более высокой тактовой частотой. У новых МК есть HRTIM, например. Или вообще даже попробовать микросхему-синтезатор сетки частот.

можно перемычками снаружи

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...