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

Сергей Борщ

Модератор
  • Постов

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

  • Посещение

  • Победитель дней

    31

Сообщения, опубликованные Сергей Борщ


  1. 4 минуты назад, srf55 сказал:

    Как выполнение makefile может зависеть от операционной системы?

    Не знаю, появились ли symlinkи в виндовсах после 7, но на 7 и раньше проект, содержащий symlinkи в исходниках нуждался в копировании файлов.

  2. 19 минут назад, VaTiKaNeTs сказал:

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

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

    Ну вот положили вы размер прошивки и саму контрольную сумму куда-то в конец флеши, а дальше что? Вы потеряли одно очень удобное свойство циклической контрольной суммы - добавленная в конец блока данных она дает результирующую сумму равную нулю. То есть вам не нужно откуда-то дополнительно вычитывать ее, что-то сравнивать - просто обсчитываете блок данных с учетом размера этой контрольной суммы и проверяете результат на ноль. Положили вы размер прошивки тоже отдельно рядом с контрольной суммой - а вы не хотите его тоже защитить этой же контрольной суммой? Значит он должен лежать где-то вместе с прошивкой, в фиксированном месте (наиболее удобно - сразу после векторов, как показал dimka76).

    Есть и другие недостатки размещения контрольной суммы отдельно. Вы можете или по совету опытных товарищей сделать сразу хорошо или все эти недостатки обнаружить самостоятельно :crazy:

  3. 12 минут назад, Сергей Борщ сказал:

    либо считается через рассеиваемую мощность.

    Имеется ввиду, что если для одного выхода дают +-35, то это совсем не означает, что через 8 можно снять 35*8 = 280 мА. К сожалению, этот производитель указывает только максимальную мощность для корпуса, но не дает графиков падения напряжения на выходном ключе в зависимости от тока нагрузки, так что придется их измерить на живой микросхеме.

  4. 17 минут назад, Turgenev сказал:

    А как понять сколько максимум может выдать этот буфер на пин?

    Так следующая же строчка. +-35 мА

    17 минут назад, Turgenev сказал:

    И на все пины, если они будут включены разом

    Считайте через выделяемую мощность.

  5. 16 минут назад, Turgenev сказал:

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

    Мне кажется, вы не поняли что это за параметр. Это не выходной ток, это максимальный ток через защитные диоды (clamping current) на выходах, то есть когда вы снаружи пытаетесь тянуть выход ниже земли или выше питания.

    image.thumb.png.a252f01029f6399876cbb638064bcec3.png

    А 3.3 мА STM выдаст сам, тут HardEgor абсолютно прав

  6. 8 минут назад, Turgenev сказал:

    У нее на этот счет другое мнение.

    Чудес не бывает. На вашем левом розовом снимке экрана не установлен бит SPIEN. Если вы зашили его в такое состояние - поздравляю, ищите параллельный высоковольтный программатор. И никакие пляски с внешним тактированием тут не помогут.

  7. 2 минуты назад, Turgenev сказал:

    Там речь про CKSEL=0000, у меня CKSEL=1111.

    image.thumb.png.420f0bb0bf684a3d1c4adc70dc95784d.png

    В этом случае она должна работать и программироваться с кварцем без всяких дополнительных источников импульсов снаружи.

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

    Во всех остальных случаях оно не нужно.

  8. 37 минут назад, Turgenev сказал:

    Я про подачу тактов на XTAL1 от балды написал, не могу в ДШ найти эту информацию

    Странно.

    image.thumb.png.f6186f4eb8a17390df7a68f174ee9b48.png

    36 минут назад, Turgenev сказал:

    Зато в инетах пишут что не получилось с XTAL1, то подают на XTAL2.

    Цитаты хотите? Их есть у меня. | Роман Посторонний | Дзен

    Смотрите внимательно на картинку в начале ответа.

  9. 26 минут назад, borodach сказал:

    чё по деньгам?

    Про деньги есть другой раздел форума - "предлагаю работу". Если автор темы хочет предложить деньги - пусть нажмет кнопку "жалоба" на своем сообщении и попросит перенести тему в тот раздел.

  10. 12 минут назад, adnega сказал:

    Важно по ошибке порт закрыть, а затем открыть.

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

  11. 9 минут назад, _pv сказал:

    ам ещё есть режим так же автоматически щёлкать полярностью возбуждающих токов,

    Весь предыдущий абзац перед отцитированным вами именно об этом режиме и написан. "AC excitation mode" = "режим возбуждения переменным током".

  12. 16 часов назад, LEXis-MegaVolt сказал:

    Я конечно попытался снять разлочку как это делатет ST-link, но чувствую с этим протоколом и тем количеством данных что там прилетело

    Может попробовать ST-Link в связке с OpenOCD? Он умеет писать читаемый лог работы, разобраться в нем должно быть несложно. Да и исходники открыты, можно в них подсмотреть.

  13. 55 минут назад, Shamil сказал:

    Спасибо за ликбез конечно. :smile:

    Так, ладно, все проржались? А я целых три часа поспал!

    55 минут назад, Shamil сказал:

    Следовательно чтобы поместить в очередь что либо (например указатель на строку, как желает топикстартер),

    Думаю, все непонятки возникли от того, что kan35 в самом первом сообщении написал

    19 часов назад, kan35 сказал:

    надо передать строку через Queue.

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

  14. 25 минут назад, Obam сказал:

    если в прошивке с защитой L1 отрублен SWD.

    А это как?

    Оно же устанавливает связь по SWD с придавленным сбросом, еще до запуска программы и до того, как программа успеет его отрубить. А без запуска программы SWD отрублен только на втором уровне.

  15. 54 минуты назад, kan35 сказал:

    В данном случае при обращении к строкам они лежат друг за другом в памяти, сперва string_received[0], потом string_received[1], каждая по 64.

    Вот это меня переклинило, мама дорогая! Да, вы правы, ваш массив объявлен правильно, а мне надо больше спать. Но про передачу массива в функцию по указателю я все написал правильно, так что рассказывайте, как вы определяете, что в функцию передается только два байта строки. 

  16. 16 часов назад, гость123 сказал:

    а вот что за чоп 

    и делей нипонятно 

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

    Теперь о вопросе: входной усилитель и сам АЦП имеют напряжения смещения, которые вызывают ошибку смещения в результатах преобразования. К этой ошибке добавляется и термо-ЭДС в местах контактов разнородных металлов измерительной цепи. В режиме возбуждения переменным током ядро АЦП делает два измерения - одно с прямой подачей напряжения возбуждения с источника опорного напряжения на датчик и второе с "перевернутым" подключением - когда напряжение Vref- подается на положительный вход напряжения питания датчика, напряжение Vref+ - на отрицательный вход питания датчика. Эта коммутация осуществляется внешними ключами, управляемыми с выходов GPIO0...GPIO3 (см. рис 97 в документации). В результате получаются два результата измерения: N1 = Vin + Voffset и N2 = -Vin + Voffset. После чего ядро делает операцию (N1 - N2) / 2, что дает результат N = ((Vin + Voffset) - (-Vin + Voffset))/2 = (Vin + Voffset + Vin - Voffset)/2 = 2Vin/2 = Vin, то есть ошибка смещения взаимно уничтожается. Задержка (delay) нужна для перезаряда емкостей входного фильтра и емкостей проводов к датчику, она происходит между сменой состояния выходов GPIO0...GPIO3 и началом процесса оцифровки.

    В режиме chop то же самое происходит коммутацией входов АЦП и входного усилителя. Это устраняет смещение АЦП и входного усилителя, но не позволяет компенсировать смещение во внешних цепях.

    Добавлено: писал по памяти, слегка ошибся. Исправил.

  17. 2 часа назад, Shamil сказал:

    Топикстартер хочет класть в очередь не сами строки, а указатели на строки. 

    Читайте по губам: строку (которая есть массив символов) невозможно напрямую передать в функцию, вместо массива всегда автоматически передается указатель на этот массив. Просто потому, что так написано в Стандарте языка C. Яндкес->"передача параметра по значению", "передача параметра по указателю". Единственный способ передать строку в функцию по значению (читай -  в виде копии всего массива символов) - это обернуть этот массив в структуру либо union и передавать в функцию эту структуру/union, но в приведенном коде этого нет. Приведенный здесь код, что 

    xQueueSend(xQueueTCPRxedString, string_received[0], 0);

    что

    6 часов назад, kan35 сказал:
    xQueueSend(xQueueTCPRxedString, &string_received[0][0], 0);

    передает в функцию указатель на первый элемент массива == на первый символ строки. Без всяких лишних переменных-указателей. То есть делает именно то, что хочет автор вопроса. Другое дело, что этот код работает не так, как ожидает автор вопроса. Я уже дважды разжевал, почему это происходит,

    раз:

    3 часа назад, Сергей Борщ сказал:

    теперь сравните третью строку со своим объявлением массива:

    9 часов назад, kan35 сказал:

    Есть массив из строк:

    char string_received[2][64];

    Я сильно сомневаюсь, что вы хотели объявить 64 строки по 2 символа.

    два:

    2 часа назад, Сергей Борщ сказал:

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

    type name[cols][rows]

    а обращение осуществляется как 

    name[row][column]

     

    Повторю в третий раз: ошибка автора в том, что он неправильно объявил размерности массива, нужно написать

    char string_received[64][2];

    а не

    9 часов назад, kan35 сказал:
    char string_received[2][64];

    но, похоже, читать (или пытаться понять) это никто не хочет.

  18. 2 часа назад, Shamil сказал:

    В функцию должно передаваться не значение, помещаемое в очередь, а указатель на это значение! 

    Это было понятно и из контекста и из исходного вопроса. Но дело в том, что любые массивы в языке C всегда в функцию передаются по указателю. Имя массива всегда неявно приводится к типу "указатель на его элемент" и этот указатель содержит адрес первого (нулевого) элемента массива. Поэтому все эти шаманства с явным приведением к типу char * излишни - это приведение выполняется неявно по правилам языка и не требует никаких дополнительных действий от программиста. Точно так же, как и указатель на любой тип неявно приводится к типу void *, поэтому в вашей записи "( void * ) pxQueue->pcWriteTo" (void *) лишнее.

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

    type name[cols][rows]

    а обращение осуществляется как 

    name[row][column]

     

  19. 6 часов назад, kan35 сказал:

    Мое мнение такое, что должна возникнуть переменная, в которой будет содержаться адрес строки. И потом эту переменную скормить в QueueSend, после чего переменная может и исчезнуть

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

    6 часов назад, kan35 сказал:

    В общем, как мне видится, запись должна быть что-то в виде такого:

    xQueueSend(xQueueTCPRxedString, &((char *)string_received[0]), 0);

    Но компилятор не пропускает это, "Syntax error".

    Честно говоря, я не вижу тут синтаксической ошибки.

    6 часов назад, kan35 сказал:

    Логично, что если делать как я ранее делал

    xQueueSend(xQueueTCPRxedString, string_received[0], 0);

    то в Queue попадает первые два байта строки, что в общем не то, то нужно.

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

    Дальше была чушь, надо больше спать.

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

    char a;         // переменная типа char
    char b[64];     // массив из 64 переменных типа char
    char c[64][3];  // массив из 3 массивов, каждый из которых состоит из 64 переменных типа char
    
    char aa = a;        // чтение переменной a
    char bb = b[10];    // чтение одиннадцатой ячейки массива b
    char *pcc = c[1];   // взятие адреса второго массива c.
    char cc = c[2][20]; // чтение двадцать первой ячейки третьего массива c

    теперь сравните третью строку со своим объявлением массива:

    9 часов назад, kan35 сказал:

    Есть массив из строк:

    char string_received[2][64];

    Я сильно сомневаюсь, что вы хотели объявить 64 строки по 2 символа. Исходя из этого, а также из того, что многомерные массивы располагаются в памяти в виде непрерывной области, где строки массива идут подряд, подозреваю, что ваша проблема "в Queue попадает первые два байта строки" не в передаче адреса массива в фунуцию xQueueSend(), а в том, что при заполнении исходного массива данными они попадают совсем не туда, куда вы ожидаете. То есть когда вы пишете первую строку, вы начиная с третьего байта выходите за пределы выделенной для этой строки памяти и залезаете в ячейки второй строки, а при записи второй строки вы затираете эти вышедшие за границу байты первой.

  20. 1 час назад, kan35 сказал:

    Соотвественно, я делаю так:
     

    char * data;
    
    data = string_received[0];
    
    xQueueSend(xQueueTCPRxedString, &data, 0);

    А как объявлена xQueueSend? Она точно ожидает char ** в качестве второго параметра? Компилятор предупреждений не выдает?

     

    1 час назад, kan35 сказал:

    Я хочу передать указатель или на string_received[0] или на string_received[1]

    Телепатически предположу, что функция ожидает второй параметр в виде char (const?) * и писать нужно 

    xQueueSend(xQueueTCPRxedString, string_received[0], 0);
    xQueueSend(xQueueTCPRxedString, string_received[1], 0);

     

    1 час назад, kan35 сказал:

    - так не пойдет

    Почему? Вы же взяли адрес от указателя data чуть выше, здесь вы делаете то же самое (там тоже было неправильно, но "оно же работает").

  21. 35 минут назад, Turgenev сказал:

    но диспетчер то его четко определяет, как и программы для прошивки

    Может от входа USB до контроллера он и исправен, а от контроллера до разъема программирования что-то подпалено.

    35 минут назад, Turgenev сказал:

    5) да, попробую глянуть, а на что смотреть, завалены ли фронты?

    Смотреть наличие импульсов на RESET, SCLK, MOSI, завал фронтов и амплитуду (судя по документации при напряжении питания 5 В она должна быть не менее 0.6 * 5 = 3 В для SCLK, MOSI и 0.9 * 5 = 4.5 В для RESET, низкий уровень должен быть не более 0.2 * 5 = 1 В).

    35 минут назад, Turgenev сказал:

    У меня не 10кОм, а 9.1кОм, что не особо меняет суть.

    Если на выходе программатора последовательно стоит резистор, скажем, 4.7 к - имеет право не работать. Я бы в этом случае уменьшил резистор в программаторе омов до ста.

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