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

AVI-crak

Участник
  • Постов

    367
  • Зарегистрирован

  • Посещение

Сообщения, опубликованные AVI-crak


  1. On 7/24/2022 at 4:08 PM, tonyk_av said:

    Я ведь не просто так прошу именно для STM32F7

    В SPI ничего сложного нет, а вот в ногах запутаться очень легко. Давай полное название чипа без экономии чернил, например stm32f769bgt6.

  2. STLINK-V3MINI уже не патриотично?

    Для F103 мне даже J-link жалко распаивать, тем более что ценник у них почти равный. Но для F и H серии вполне терпимо, особенно для жирных корпусов.

  3. 1 hour ago, Arlleex said:

    Вы о чем?

    Входные цепи должны иметь максимальную стабильность характеристик, чтоб не плавало само по себе. А насчёт качания PLL, у меня для вас плохие новости - у вас 1 пропущенный параграф доки.

     

    28 minutes ago, bolmoe said:

    Попробую впаять генератор

     Кроме кварца, нужно ещё ldo на VDDA. Там детальки мелкие, не знаю как у вас получится. Питание аналоговой части должно быть независимым, и идеально стабильным.

  4. 3 hours ago, bolmoe said:

    На табло отображается время отсчета сек и до десятых мс.

    Там до миллионных долей можно разогнать: малошумящие компараторы, оптика, и отдельный ldo на VDDA. 

    И ещё, настройку PLL лучше делать руками и через регистры. Халл включает качание PLL для уменьшения эми помех.

     

  5. 1 hour ago, Arlleex said:

    А какая разница какая там последовательность?

    Есть разница. В случае совпадения порядка нескольких бит (допустим 3,4,5) - имеет смысл двигать весь регистр и использовать маску. В остальных случаях использовать UBFX + BFI.

    На си получается классика: (x) старая позиция, (y) новая позиция.

    out = 0;
    tmp = (in >> (x)) & 1;
    out |= tmp << (y); 

    Временный регистр обязателен, именно с ним получаются те 2 команды на асме. Для ускорения использовать два регистра, потому как сдвиг в ARM требует два такта конвейера. 

  6. On 4/18/2022 at 10:49 PM, Arlleex said:

    Смысл в том, что в некотором простом алгоритме обрабатываются бинарные данные, причем сразу "пачками" по разрядности регистра (32 бита).

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

    В случае автономной клавиатуры, со своим мк - имеет смысл переложить на него всю обработку кнопок. Сырые данные никому не нужны.

    Я так и не услышал самого важного - последовательности сортировки. Например 31,1,2,16,0,3,4,5,6,7,8,9,10,11,12,13,14,15,17,18,19,20,21,22,23,24,25,26,27,28,29,30. Потому как сам алгоритм сортировки всегда подгоняется под реальную задачу. Там нет идеальных универсальных решений.

  7. 22 hours ago, std said:

    Так вот, чем можно сесть вообще на ВСЕ прерывания в системе чтобы понять, какое из них дубасит столь часто?

    Оценивать количество вызовов прерываний отладчиком - физически невозможно. Когда просматриваешь код отладчиком - выполнение кода встаёт колом, все независимые прерывания накапливаются в очереди, и после нового шага отладчика - ломануться выполняться всем скопом.

    Можно поступить хитро, добавить простейший программный счётчик. Завести переменную, которую в вашем подозрительном прерывании увеличивать на 1. Используя рабочий таймер на 1 секунду (проще аппаратный) - считывать переменную во внешний показатор результата, а переменную после этого обнулять.  

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

  8. 9 hours ago, medved91ru said:

    Кто-нибудь знает, что случилось с Миландром?

    Возможно рыночные отношения утопили все провальные направления, корпуса в золоте и керамике - по цене взлетающего боинга. 

    Но мне интересно, как они чипы делают в условиях войны. Об этом вообще полная тишина.

  9. 14 hours ago, std said:

    любые другие прерывания всегда прерывают короткий SysTick_Handler (и он не может перебивать другие прерывания)

    Это нормальное состояние для SysTick_Handler, который почти всегда используется для вызова более сильного прерывания - для переключения контекста. Отсутствие вытеснения слабых прерываний - гарантия сохранения чистого стека, что очень важно для переключения задач.

    Вопрос в другом, как оно работало раньше??? 

  10. 15 minutes ago, do_not_know_Linux said:

    уже подпоялся я

    Там вариантов ошибки не так уж и много, контакты J1 подписаны прямо на плате, ещё и картинок в интернетах полно. Подпаиваться питанием не обязательно, и даже вредно - у платы есть свой usb разъём питания. Кстати, без программатора должно шится по udf - usb шнурком через куб_иде. Но оно в линуксах не работает.

  11. 11 hours ago, Alexandr54 said:

    С какой точностью можно посчитать сколько периодов тактовой частоты проходит между двумя событиями, ...

    STM32F7, 24МГц

      CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
      DWT->LAR = 0xC5ACCE55;
      DWT->CYCCNT = 0;
      DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
    --------------
              __memory();
            timz1 = DWT->CYCCNT;
            ваш код
            timz2 = DWT->CYCCNT;
            __memory();
            timz3 = timz2 -timz1; /// время в тиках

    Для внешних событий нужно использовать таймер в режиме захвата, у него есть аппаратные триггеры по входу.

  12. 56 minutes ago, a123-flex said:

    Там на матрицу подается несколько напряжений

    Кроме наличия питания - очень важна последовательность включения линий, в доке на дисплей есть картинка с таймингами. Из неприятностей: рандомное выгорание пикселей, иногда целых строк. Стандартный драйвер на одном boost ключе имеет детали выполняющие сразу несколько функций одновременно: задержка, ограничение тока, перекачка энергии. Я к тому что менять номиналы деталей в этой схеме не нужно, и даже опасно.

  13. #define HEXFLOAT(x) ((union {uint32_t i; float f;}) {x}.f)
    #define F_value HEXFLOAT(0x3e4ccccd)
    #define F_value2 0x0.CCCCCDp-2
      
    int main(void){
      printo(F_value,"\n");
      printo(F_value2,"\n"); 
      /// 200.00000298e-3
      /// 200.00000298e-3

    Работает!!!

    Хотя мне нужно это https://stackoverflow.com/questions/4825824/hexadecimal-floating-constant-in-c

    Теперь осталось понять как записать отрицательное число с плавающей точкой. 

  14. Константа и объединение - это разные вещи. К тому-же мне не требуется иного применения кроме изначального задуманного float. 

    #define  F_value  0x3e4ccccd

    F_value будет использоваться как int32_t, а мне нужно чтоб использовалось как float.

  15. Посмотреть знаю как, мне нужно чтобы точно было, без вариантов. Числа float очень редко имеют точное представление в десятичной системе. Например 0.2f храниться как 0.20000000298023223876953125f с ошибкой к 0.2f в 2.98023223876953125e-9. Очень очень длинные числа.

    А мне нужно записать константу без вариантов двойного преобразования, сразу  0x3e4ccccd. Но так чтобы GCC не матерился.

  16. Подскажите плиз как это записать.

    Нечто специфическое и редкое, которое точно существует. Выглядит наверное так:

    #define  ttgg  0f4a52bc77

    Где-то слышал что подобный хак применялся в библиотеках математики, а вот теперь надо - а вспомнить не могу.

  17. Я рассчитывал увидеть подключение проводками, аля аурдино. 

    Вдруг поможет...

    Spoiler
    
    ///Install SDRAM
        FMC_Bank5_6 -> SDCR[0] =    FMC_SDCR1_NC_10bits|
                                    FMC_SDCR1_NR_13bits|
                                    FMC_SDCR1_MWID_16bits|
                                    FMC_SDCR1_NB_4banks|
                                    FMC_SDCR1_CAS_2cycle|
                                //|FMC_SDCR1_SDCLK_3x|
                                    FMC_SDCR1_SDCLK_2x|
                                    FMC_SDCR1_RBURST|
                                    FMC_SDCR1_WP|
                                    FMC_SDCR1_RPIPE_2delay; //FMC_SDCR1_RPIPE_1delay FMC_SDCR1_RPIPE_3delay
    
    
        FMC_Bank5_6->SDTR[0] =  _VAL2FLD(FMC_SDTR1_TRCD, 2)|    /// TRCD время между подачей команды ACTIVATE и появлением данных на шинеС/1  /2
                                _VAL2FLD(FMC_SDTR1_TRP, 2)|     /// TRP  минимальное время закрытия строки
                                _VAL2FLD(FMC_SDTR1_TWR, 2)|     /// TWR  время записи данных
                                _VAL2FLD(FMC_SDTR1_TRC, 6)|     /// TRC  минимальное время между активацией строк одного банка
                                _VAL2FLD(FMC_SDTR1_TRAS, 4)|    /// TRAS минимальное время активности строки
                                _VAL2FLD(FMC_SDTR1_TXSR, 6)|    /// TXSR время между SELF-REFRESHING и ACTIVATE (exit self-refresh mode)/5  /7
                                _VAL2FLD(FMC_SDTR1_TMRD, 1);    /// TMRD время между записью в MODE-REGISTER и ACTIVATE/1  /2
    
    ///TWR>=TRAS-TRCD and TWR>=TRC-TRCD-TRP  TRC=TRAS+TRP
      FMC_Bank5_6->SDCMR = FMC_SDCMR_CTB1 | FMC_SDCMR_MODE_Config_Enable; // 0x00000011;
      tmp = 15;
      timeout = 0xFFFF;
      while((tmp != 0) && (timeout > 0))
      {
        tmp = FMC_Bank5_6->SDSR & FMC_SDSR_BUSY; timeout-- ;
      }
    
    delay(100000);
    /// PALL command
      FMC_Bank5_6->SDCMR = FMC_SDCMR_CTB1 | FMC_SDCMR_MODE_PALL; //0x00000012;
      timeout = 0xFFFF; tmp = 10;
      while((tmp != 0) && (timeout > 0))
      {
        tmp = FMC_Bank5_6->SDSR & FMC_SDSR_BUSY; timeout-- ;
      }
    /// Auto refresh command
      FMC_Bank5_6->SDCMR = _VAL2FLD(FMC_SDCMR_NRFS, 3)|
                            FMC_SDCMR_CTB1|
                            FMC_SDCMR_MODE_Self_refresh; //0x00000073; FMC_SDCMR_MODE_Self_refresh  FMC_SDCMR_MODE_Auto_refresh
    /// Количество рефлеш минимум 2
      timeout = 0xFFFF; tmp = 10;
      while((tmp != 0) && (timeout > 0))
      {
        tmp = FMC_Bank5_6->SDSR & FMC_SDSR_BUSY; timeout-- ;
      }
    /// MRD register program
      tmp = ((216000)*64)/8192; // 48тактов
      FMC_Bank5_6->SDCMR = _VAL2FLD(FMC_SDCMR_MRD, (216000 * 64)/8192)|
                            FMC_SDCMR_CTB1|
                            FMC_SDCMR_MODE_Load_Mode ;
    /// 64mc/(размер блока Row Addresses(8192)) * (тактовая частота чипа)
      timeout = 0xFFFF; tmp = 10;
      while((tmp != 0) && (timeout > 0))
      {
        tmp = FMC_Bank5_6->SDSR & FMC_SDSR_BUSY; timeout-- ;
      }
      FMC_Bank5_6->SDRTR |= _VAL2FLD(FMC_SDCMR_MRD, (216000 * 64)/8192)|
                            FMC_SDRTR_REIE; // время регена + вкл регена
    /// Refresh rate = (COUNT) * SDRAM clock frequency
    /// SDRAM refresh period = 64 mc
    /// COUNT = (SDRAM refresh period / Number of rows )
    /// Refresh rate = 0.064 / (8192rows + 4) ) * 84000000 , ~ 656 ( 0x290 )
    
      FMC_Bank5_6->SDCR[0] &= (~FMC_SDCR1_WP);// снятие защиты от записи
      timeout =0;
    
     // uint32_t* tmp3; uint32_t* tmp4;
     // tmp3 = (uint32_t*)0xc0000000; tmp4 = (uint32_t*)0xC3FFFFFC;
     // do{ *tmp3++ = 0;} while(tmp3 != tmp4);

     

     

  18. 32 minutes ago, MDD said:

    Или как-то сложнее?

    Даже проще. Энкодеры как правило имеют гораздо большую степень свободы чем требуется двигателю, и оно не всегда совпадает с желаемым результатом. По этому все вычисления переводятся в относительные числа, даже дробь не всегда нужна. Показания счётчика энкодера считываются по общему счётчику, допустим каждые 100мкс (10КГц), для большей точности (время) - через дма. Из старого значения отнимаем новое - получаем перемещение, которое уже можно сделать абсолютным (счётчик двойной точности), и масштабировать текущую позицию для более удобных расчётов. Получаются те самые электронные шестерёнки.

    Ну а дальше сравнение текущей позиции с требуемой, и корректировка.

    4 minutes ago, MX_Master said:

    Куда сложнее на лету рассчитывать траекторию на основе контрольных точек из G кода и затем, учитывая все ускорения, делить полученное на одинаковые мелкие кусочки по времени.

    кхм, одна операция сложения и проверка флага переполнения -это сложно?

  19. 7 minutes ago, jcxz said:

    Ещё раз, по слогам:

    Повторяю ещё раз - дробный счётчик. На этот раз будем считать на пальцах, как начальных классах. :biggrin:

    Счётчик без целой части, только дробная - количество значений 5 (подсказка - это одна рука). Нам нужно за 10 сложений подняться на 3 ступеньки, то-есть должно быть 3 явных переполнения одной руки. 5*3/10=1.5~2 целых пальца.

    2+2+2+2+2+2+2+2+2+2

    2=4=1=3=5=2=4=1=3=5   5 - остаток дробной части, который дальше участвует в вычислениях.

    0=0=1=0=0=1=0=1=0=0  3 ступеньки/переполнения.

  20. 3 minutes ago, jcxz said:

    И как же это??

    Это не при 144МГц, а при 10КГц общего счётчика, используя дробные значения для каждого программного счётчика. Каким образом -это я уже в трёх вариантах написал, но могу ещё проще.

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

  21. 9 minutes ago, jcxz said:

    Ничего не понял - о чём это?

    О том что G код для кривых выдаёт позиции реперных точек, а всё промежуточное контролёр должен рассчитать сам. Там нет таких команд типа "подать частоту шага на двигатель". Ну вот совсем нет, и никогда не было. 

    15 minutes ago, jcxz said:

    нужно выдать последовательность импульсов длительностью 28799 и 28800 тактов

    В этом случае будет 199,993055us и 200us. Допустим двигается только одна ось с переменной частотой. В этом случае у меня будет всего одна ступенька в произвольном месте, когда позиция уже не будет совпадать с возможностями механики. А у тебя явная граница перехода, железобетонная. С дополнительным накоплением ошибки от второй оси.

    И ещё, допустим нужна скорость перемещения близкая к нулю - сколько будет делитель у таймера? А если просто остановиться?

    Для дробного счётчика таких проблем не существует вообще. А для режима стоп вообще всё красиво, значение перемещения ноль - и мы сохраняем позицию без накопления ошибки.

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