a5021 тут недавно практически доказал, что для "перегрузки" байтами USARTа (т.е. для возникновения пропусков) надо создать невероятно дикую нагрузку остальной периферии, что представляется маловероятным.
a5021 там написал полнейшую галиматью, из которой только следует, что он совершенно не понял о чём шла речь. Примерно как вы не понимаете очевидных вещей - как делить поток байтов на кадры Modbus-RTU. В этом вы с ним схожи. Речь не шла ни о какой "перегрузки байтами USARTа". Выше по комментам видно, что другие люди прекрасно поняли о чём шла речь:
Как выше правильно заметили, обычно, у МК есть много более приоритетных задач, чем приём одного байта. Вот поэтому весь обмен через UART нужно строить исключительно с использованием DMA: приняли фрейм, появилось время, тогда и обработали его.
не поняли только вы на пару с a5021 Как обычно - "не в коня корм".
То есть задействование трех периферийных устройств вместо одного считается правильным и эффективным решением?! Мда... Неожиданно.
В МК множество периферийных узлов. Они предназначены чтобы разгрузить самый главный узел - CPU. Говнокодеры-ногодрыгатели всё пытаются делать ногодрыгательными методами. Чтобы не читать мануалы на эти периферийные узлы. И у них самая простая задача грузит CPU на 100%. И он только с ней кое-как справляется. Умные люди - используют разные периферийные блоки. Чтобы сэкономить главный ресурс = время CPU. И используют столько периферийных узлов, сколько нужно. И у них CPU умудряется параллельно выполнять множество задач.
И DMA - как раз один из тех узлов, которые предназначены разгрузить CPU. Вы на пару с a5021 как видно - совершенно не понимаете его предназначения. А также той простой вещи, что во множестве проектов UART - это совсем не главная вещь, на которую нужно убить всё время CPU. Что там программе нужно ещё много разных функций выполнять. И возможно - гораздо более приоритетных. И что UART-ов в проекте может быть не один, а много. И работать они могут не на 9600, а скажем - на 921600. Завтра вам с вашей реализацией на прерываниях, потребуется увеличить скорость UART. Или добавить ещё пару UART-ов в проект и.... окажется, что производительности CPU уже не хватает. Вся она ушла на перекладывание байтов в UART и из него. И будете всё переписывать по новой, в который раз.
PS: И да что значит "задействование трех периферийных устройств вместо одного"? Как именно вы делите поток байтов на кадры Modbus при помощи одного только UART? Без таймера и без использования аппаратной функции таймаута UART?
Последний раз редактировалось jcxz Вс май 04, 2025 14:05:14, всего редактировалось 2 раз(а).
как эта схема спасает от того, что в этот момент пишущий проглотил муху и выбрал не тот пункт из списка? я к чему это.. придумывать различные эксепшены можно бесконечно и всех так и не придумать. а помогаек всяких без счета сейчас: Спойлер
как эта схема спасает от того, что в этот момент пишущий проглотил муху и выбрал не тот пункт из списка?
Функция ждет аргумент типа TimSlaveMode в качестве первого параметра, любое другое значение приведет к ошибке компиляции. В худшем случае из десятка допустимых режимов можно выбрать не тот который требуется, а в рантайме там еще дополнительные проверки есть. У вас можно подставить любой аргумент который приводится к uint32_t.
a5021 писал(а):
а помогаек всяких без счета сейчас: Спойлер[spoiler]
Здорово, а букву наверно можно наугад вводить? ) И что-то маловат списочек, там должны быть все определения начинающиеся c RCC, RTC и т.д., в том числе ваши сокращения R и RT. Но тут хоть обычно понятно к чему они относятся, а чего вдруг RESET_MODE должен обязательно к таймерам относится? У USB есть поля RESET и RESETM, у CRC, GPDMA и FMAC тоже есть поле RESET... Вон в HAL символы не считают и дали режимам таймера имена начинающиеся с TIM_SLAVEMODE, в частности TIM_SLAVEMODE_RESET, а вы все оптимизациями имен по размеру занимаетесь )
Компания MEAN WELL пополнила ассортимент своей широкой линейки светодиодных драйверов новым семейством XLC для внутреннего освещения. Главное отличие – поддержка широкого спектра проводных и беспроводных технологий диммирования. Новинки представлены в MEANWELL.market моделями с мощностями 25 Вт, 40 Вт и 60 Вт. В линейке есть модели, работающие как в режиме стабилизации тока (СС), так и в режиме стабилизации напряжения (CV) значением 12, 24 и 48 В.
Итак, по сути. Модбас не укладывается в модель OSI, т.к. был придуман еще до его изобретения, если я не ошибаюсь.
Модель ISO/OSI является обобщением полученного опыта, а не высосана из пальца. И Модбас в неё укладывается. Читайте Стандарт, там есть об этом.
ARV писал(а):
Итак, по сути. Модбас... Длина пакета него переменная в принципе, хотя наиболее частая длина 8 байт, но при ошибках может быть 6, а при записи большого количества регистров-катушек, как было отмечено, может быть до 257 байт.
ARV писал(а):
tonyk писал(а): В некоторых STM32 встроены полноценные UART с аппаратной поддержкой Модбас. это вы сейчас утверждаете, или предполагаете? я пока что обнаружил встроенную поддержку аппаратного переключения RX-TX, что и применяю. но никакой дргой поддержки модбас я пока не видел (но я и видел мало, как вы уже ранее верно подметили).
Я это использую. А автоуправление DE никакого отношения к Модбас не имеет. Максимальная длина пакета в Модбас составляет 256 байт. А вот буфер для его приёма нужно делать 257 байт. Читайте внимательно то, что вам говорят.
ARV писал(а):
Не представляю, как еще можно все настроить...
А это потому, что не читаете мурзилки и гордитесь этим. Вы же хотите бездумно тыкать по галкам в КАЛе- вот и результат. Если бы читали, то знали, что полноценный UART, которого лишён попсовый STM32F103, умеет аппаратно выделять Модбас-кадр используя свой специальный таймер, отсчитывающий задержку в количестве битов. Кроме того, такой UART умеет сравнивать байт внутри кадра с заданным. Ну и до кучи можно считать CRC принятого пакета, используя аппаратный блок вычисления CRC вкупе с DMA.
ARV писал(а):
я ранее интересовался: а как же девайсы на 8-битниках двадцатилетней давности модбас тянут?!
Ну 1 или 2 порта на 9600- это не проблема. Да и восьмибитников, например, с десятью UART как у STM32, я не встречал. Встречал МК-восьмибитки с 4 UART. И, опять же, читайте внимательно, что вам пишут. А писал я, что МК, помимо 6 Модбас, тянул измерения по 12 каналам, которые не допускают пропусков, ибо на результатах их измерений построены защиты. Вот вам и приоритетные задачи. И как вишенка- рантайм ПЛК.
завести сигнал RXD на вход сброса/перезагрузки таймера
а это делается программно, или "завести на вход" следует понимать буквально - изменить схему?
jcxz писал(а):
ак именно вы делите поток байтов на кадры Modbus при помощи одного только UART? Без таймера и без использования аппаратной функции таймаута UART?
уверен, что рассказывать необязательно, т.к. вне зависимости от того, что именно я делаю, ваш вердикт все равно будет "не правильно". Однако, таймер есть, и он на самом деле ловит таймауты и паузы между пакетами.
jcxz писал(а):
Как обычно - "не в коня корм"
на минуточку: вы в теме для начинающих, так что речь не о конях и корме, а о жеребятах и бутылочке с соской. умерьте ваш гонор, а то вам поляки завидуют.
tonyk писал(а):
А автоуправление DE никакого отношения к Модбас не имеет.
к драйверу RS485 зато имеет
tonyk писал(а):
Если бы читали, то знали, что полноценный UART, которого лишён попсовый STM32F103, умеет аппаратно выделять Модбас-кадр используя свой специальный таймер, отсчитывающий задержку в количестве битов. Кроме того, такой UART умеет сравнивать байт внутри кадра с заданным. Ну и до кучи можно считать CRC принятого пакета, используя аппаратный блок вычисления CRC вкупе с DMA.
ну, вот и спасибо, теперь буду знать. но ведь DMA не может в два "приемника" данные отправлять? или может? это я к тому, что CRC считать одновременно с "перемещением байта в буфер" все равно не получится?
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
Я использую драйверы без этого сигнала, с автоопределением направления.
ARV писал(а):
но ведь DMA не может в два "приемника" данные отправлять? или может? это я к тому, что CRC считать одновременно с "перемещением байта в буфер" все равно не получится?
Дальше как в анекдоте:
Цитата:
Поймал мужик золотую рыбку - та и говорит: "Исполню твое желание, отпусти меня!" Мужик думал, думал да и говорит: "Хочу ссать водкой!" Рыбка отвечает - "Запросто!"
Пришел мужик домой, поссал в стакан, к жене : "Выпей!!" Та :"Да ты че о@ел!". Мужик сам попробовал - нормально, она следом. Ну в общем посидели до утра.
Утром жена приходит со стаканом и с огурчиком - "Опохмелиться бы"
Мужик: "Вчера была презентация - а сегодня за деньги и из горла!"
То есть задействование трех периферийных устройств вместо одного считается правильным и эффективным решением?! Мда... Неожиданно.
вы намекали, что мой подход "неэффективный". Не приводя никаких аргументов и не показывая "как будет эффективно" по вашему мнению. Какого ответа вы ещё ожидали на свой пост?
на соревнованиях базарных баб ваши шансы не вызывают сомнений.
PS: Чайники, прежде чем указывать кому-то как и что писать, научитесь хотя бы чему то, кроме как хамить. Вам тут никто ничего не должен.
Двумя руками поддерживаю jcxz. Тоже удивлён хамско-вызывающей манерой общения ARV. Думал, что это касалось только моей персоны, но оказалось, что нет, это тенденция.
Видимо, вас недооценивают ваши начальники или кто-то еще... Может, в детстве обижали... В общем, не знаю, что можно сказать хаму, обвиняющего другого в хамстве, но причина явно не техническая, а психологическая.
Я ни одного из участников темы никак не обозвал, никак не иронизировал или острил над его качествами, чего не скажешь про слова в мой адрес. Я даже сразу предложил окончить обсуждение моих качеств, признав все негативные оценки. Но остановиться вы не можете... Фрейд бы в восторге был, попадись вы ему... Жаль.
Добавлено after 9 minutes 56 seconds: P.S. для jcxz, которого я знаю лет этак 20 еще по форуму электроникс, и советами которого ранее я не пренебрегал: я начал примерно 33 года назад, и, вероятно, скоро уже закончу[сь]. А с стм32 я начал три месяца назад, и начал с того, что в первые часы реализовал собственный "оригинальный" вариант того, что активно применялось и применяется на новом месте моей работы. Так что ваши советы "начать" я не особо близко к сердцу принимаю. Но за те крохи пользы, что удалось получить в этой теме, спасибо.
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
// --- Main loop --- while (1) { // Poll RXNE (Receive Data Register Not Empty) if (USART2->SR & USART_SR(RXNE)) { // Read received byte (clears RXNE) signed char delta = (signed char)USART2->DR;
// Adjust duty cycle int duty = TIM2->CCR1 + delta; if (duty < 0) duty = 0; if (duty > TIM2->ARR) duty = TIM2->ARR; TIM2->CCR1 = duty; }
// Main loop continues immediately (non-blocking) } }
не стесняемся, подходим, критикуем, разносим в пух и прах...
все, как мы любим -- прием без прерываний и дма, неблокирующий...
ps. aх, да, сами макросы.. Спойлер
Код:
// --- Universal BITS Macro --- // Helper macro: paste together PREFIX_, REG, and FIELD to form a bitfield macro name #define _BITS_ONE(PREFIX_, REG, FIELD) PREFIX_##REG##_##FIELD
// Macro to count the number of variadic arguments (up to 16) #define _BITS_NARG(...) _BITS_NARG_(__VA_ARGS__,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1) #define _BITS_NARG_(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,N,...) N
// Macro chooser: selects the correct _BITS_N macro based on argument count #define _BITS_CHOOSER2(count) _BITS_##count #define _BITS_CHOOSER1(count) _BITS_CHOOSER2(count) #define _BITS_CHOOSER(count) _BITS_CHOOSER1(count)
// Main macro: expands to a mask of all requested bitfields for a given peripheral register #define BITS(PREFIX_, REG, ...) \ (_BITS_CHOOSER(_BITS_NARG(__VA_ARGS__))(PREFIX_, REG, __VA_ARGS__))
// --- Peripheral Type Wrappers --- // These wrappers make it easy to use the BITS macro for each peripheral type. // Example: RCC_BITS(APB2ENR, IOPAEN, AFIOEN) expands to (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN)
#define RCC_BITS(reg, ...) BITS(RCC_, reg, __VA_ARGS__) // For RCC registers #define GPIO_BITS(reg, ...) BITS(GPIO_, reg, __VA_ARGS__) // For GPIO registers #define AFIO_BITS(reg, ...) BITS(AFIO_, reg, __VA_ARGS__) // For AFIO registers #define TIM_BITS(reg, ...) BITS(TIM_, reg, __VA_ARGS__) // For TIM registers #define USART_BITS(reg, ...) BITS(USART_, reg, __VA_ARGS__) // For USART registers #define UART_BITS(reg, ...) BITS(UART_, reg, __VA_ARGS__) // For UART registers #define SPI_BITS(reg, ...) BITS(SPI_, reg, __VA_ARGS__) // For SPI registers #define I2C_BITS(reg, ...) BITS(I2C_, reg, __VA_ARGS__) // For I2C registers #define CAN_BITS(reg, ...) BITS(CAN_, reg, __VA_ARGS__) // For CAN registers #define ADC_BITS(reg, ...) BITS(ADC_, reg, __VA_ARGS__) // For ADC registers #define DAC_BITS(reg, ...) BITS(DAC_, reg, __VA_ARGS__) // For DAC registers #define CRC_BITS(reg, ...) BITS(CRC_, reg, __VA_ARGS__) // For CRC registers #define USB_BITS(reg, ...) BITS(USB_, reg, __VA_ARGS__) // For USB registers #define BKP_BITS(reg, ...) BITS(BKP_, reg, __VA_ARGS__) // For BKP registers #define PWR_BITS(reg, ...) BITS(PWR_, reg, __VA_ARGS__) // For PWR registers #define FLASH_BITS(reg, ...) BITS(FLASH_, reg, __VA_ARGS__) // For FLASH registers #define DBGMCU_BITS(reg, ...) BITS(DBGMCU_, reg, __VA_ARGS__) // For DBGMCU registers #define WWDG_BITS(reg, ...) BITS(WWDG_, reg, __VA_ARGS__) // For WWDG registers #define IWDG_BITS(reg, ...) BITS(IWDG_, reg, __VA_ARGS__) // For IWDG registers #define RTC_BITS(reg, ...) BITS(RTC_, reg, __VA_ARGS__) // For RTC registers #define EXTI_BITS(reg, ...) BITS(EXTI_, reg, __VA_ARGS__) // For EXTI registers
Проходили же это уже, или думаете поле RESET есть у множественной периферии, а с тем же DIR будет иначе? Если у TIMx это 4-й бит, то у LPTIM/HRTIM - 16-й. Молчу уже про DMA/USB/I2C...
Заголовок сообщения: Re: STM32 новичку в ARM что к чему
Добавлено: Пт май 09, 2025 23:27:22
Опытный кот
Зарегистрирован: Вс мар 23, 2025 14:56:55 Сообщений: 700
Рейтинг сообщения:0
Когда-то я кучу времени потратил на подобную наглядность, написал-переписал кучу макросов, а потом пришёл, или точнее, вернулся к словам Страуструпа: поменьше макросов и разумность в наименованиях компонентов. Стал больше тратить буков на комментарии к коду и полагаться на всякие плюшки современных IDE. Скорость работы возросла, читабельность кода через год тоже. И вместо двух строчек
Код:
GPIOA->CRL &= GPIOA->CRL |=
будет одна
Код:
GPIOA->CRL =
, а что такое 0xabcd напишется в комментарии. Хотя, при поиске ошибки, конечно, удобнее вместо 0xabcd увидеть человеческое.
Проходили же это уже, или думаете поле RESET есть у множественной периферии, а с тем же DIR будет иначе? Если у TIMx это 4-й бит, то у LPTIM/HRTIM - 16-й. Молчу уже про DMA/USB/I2C...
с макросами вида PERIPH_REG(..) будет ровно то, что описано в CMSIS заголовочнике на соотв. камень, а TIM_CR1(...) и LPTIM_CR(..) -- это разные макросы, которые порождают разные наборы битов. позиции битов пусть считают те, у кого времени много. я, как раз, пытаюсь в обратном направлении двигаться.
Ага, этот DIR и т.д. не задефайнены, а просто склеиваются, тогда в принципе можно так делать, но все равно вряд ли нужно ) Допустим было TIM_CCER_CC1E, можно навести на него мышей и получить подсказку, а если станет просто CC1E, то даже этого не будет. Опять же раньше набрал "TIM_CCER_" и видишь все поля, теперь нужно набирать вслепую. Плюс куча макросов нужна или вы для всех серий уже готовые и проверенные поставляете? )
Допустим было TIM_CCER_CC1E, можно навести на него мышей и получить подсказку, ... раньше набрал "TIM_CCER_" и видишь все поля
каким образом существование каких-либо макросов может отобрать эту возможность у IDE? и я уже говорил, что если не лениться, то показывать оно может начать чего только захочешь.
Цитата:
Плюс куча макросов нужна или вы для всех серий уже готовые и проверенные поставляете?
я написал их сегодня в ходе обдумывания концепта. не сказать, чтобы надорвался.
каким образом существование каких-либо макросов может отобрать эту возможность у IDE? и я уже говорил, что если не лениться, то показывать оно может начать чего только захочешь.
Покажите мне подсказку для CC1E, потому что у меня с решарпером ее нет, а мощнее решарпера я ничего не знаю.
a5021 писал(а):
я написал их сегодня в ходе обдумывания концепта. не сказать, чтобы надорвался.
Но писать то придется, а преимущества вашего подхода слишком незначительны чтобы компенсировать это вместе с прочими недостатками. И писали вы для одного из самых примитивных мк. Структуры для F103 в стандартном хедере занимают 420 строк, а для H563 - 1450. Для H503 хедер другой, т.е. даже в рамках одной серии не надорваться нужно раз 6, а серий полно, мне нужно хотя бы 5. По нормальному это уже нужно утилитку писать )
Это всё для темы про С/С++, так как к STM32 непосредственно не относится. Сам подход переноса специфических макросов внутрь универсальных представляется вполне логичным, но только в том случае, если одинаковые периферийные сущности в разных МК описаны разными макросами. Ранее этим, например, страдал Атмел AVR, у которых для некоторых МК таймеры описывались макросами TIMERn_****, для других TIMn_**** и так далее.
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
что такое 0xabcd напишется в комментарии. Хотя, при поиске ошибки, конечно, удобнее вместо 0xabcd увидеть человеческое.
Тут есть нюанс. При работе с кодом часто требуется оперативно копипастить и менять некоторое количество бит. Например, потребовалось применить еще один таймер. Копируется инит близкого ему по функционалу другого и оперативно изменяются настройки. Тут и открывается как удобно, а как нет. Я не программист. Я просто погулять вышел. И мне создавать макросы нахрен не облокотилось. Поэтому применяются хедеры производителя. Приступив к работе с Артери вместо СТМ, я внезапно обнаружил, что, несмотря на идентичность почти всей периферии, хедеры написаны не в дефайнах констант, а как структуры. Дефайны конечно тоже есть, но они для читабельности значений полей структур. И они не требуют перректальных инверсий и логических операций в ините. И потому очень наглядная настройка посредством определения значения поля структуры стала чрезвычайно читабельной и удобной. В отличии от. ЗЫ. К слову. У Микрочипа в XC8/XC16/XC32 сделано тоже с помощью структур.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 16
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения