-
Постов
110 -
Зарегистрирован
-
Посещение
Сообщения, опубликованные BioWolf2000
-
-
Неплохо получается freemodbus+freertos+lwip. https://www.embedded-experts.at/en/produkt/modbus-slave-evaluation-version/ Без проблем зарегистрироваться и скачать. В eval версии полностью исходники и примеры для STM32 под STM32CubeMX. На первое время отладку на ПК можно делать через Modbus Poll. Датчики повесить на Inputs, управляющие сигналы на Coils, настроечные параметры - Holdings, в разборе Coils обеспечить вызов функций. Доступ к переменным через Union
union{ uint16_t arr[10]; struct{ uint16_t reg1; uint16_t reg2; // } } mbHoldings;
Модбас работает через mbHoldings.arr, программа через mbHoldings.reg1 и тд
ps. Есть перевод UM1713 на русский http://pro-interes.com/wp-content/uploads/2020/02/LwIP_TCP_IP_stack_descriptionRus.pdf
Про Modbus можно почитать тут https://habr.com/ru/post/281430/
И рекомендую поставить сниффер TCP - Wireshark. Без него никак. Там кстати плагин modbus тоже есть
- 1
-
Привожу код, который заработал. Из-за дурацкой документации AN4221, пришлось повозиться и поподбирать последовательность команд
#define GET_CMD_COMMAND 0x00U /*!< Get CMD command */ #define GET_VER_COMMAND 0x01U /*!< Get Version command */ #define GET_ID_COMMAND 0x02U /*!< Get ID command */ #define RMEM_COMMAND 0x11U /*!< Read Memory command */ #define GO_COMMAND 0x21U /*!< Go command */ #define WMEM_COMMAND 0x31U /*!< Write Memory command */ #define EMEM_COMMAND 0x44U /*!< Erase Memory command */ #define WP_COMMAND 0x63U /*!< Write Protect command */ #define WU_COMMAND 0x73U /*!< Write Unprotect command */ #define RP_COMMAND 0x82U /*!< Readout Protect command */ #define RU_COMMAND 0x92U /*!< Readout Unprotect command */ I2C_HandleTypeDef *I2cHandle; void BL_Init(I2C_HandleTypeDef *hi2c) { I2cHandle = hi2c; } HAL_StatusTypeDef BL_Transmit(uint8_t *pDat, uint16_t num) { HAL_StatusTypeDef status; while (HAL_I2C_GetState(I2cHandle) != HAL_I2C_STATE_READY) ; status = HAL_I2C_Master_Transmit_IT(I2cHandle, 0xa6, pDat, num); while (HAL_I2C_GetState(I2cHandle) != HAL_I2C_STATE_READY) ; return status; } HAL_StatusTypeDef BL_Receive(uint8_t *pDat, uint16_t num) { HAL_StatusTypeDef status; while (HAL_I2C_GetState(I2cHandle) != HAL_I2C_STATE_READY) ; status = HAL_I2C_Master_Receive_IT(I2cHandle, 0xa6, pDat, num); while (HAL_I2C_GetState(I2cHandle) != HAL_I2C_STATE_READY) ; return status; } uint8_t BL_GetVersion(void) { HAL_StatusTypeDef status; uint8_t ACK; uint8_t cmd_frame[2]; uint8_t version = 0x00U; cmd_frame[0] = GET_VER_COMMAND; cmd_frame[1] = GET_VER_COMMAND ^ 0xFFU; status = BL_Transmit(cmd_frame, 2); status = BL_Receive(&ACK, 1); if (ACK == 0x79) { status = BL_Receive(&version, 1); status = BL_Receive(&ACK, 1); if (ACK == 0x79) return version; } return 0xff; } HAL_StatusTypeDef BL_ReadMemory(uint32_t address, uint16_t nob, uint8_t *pData) { HAL_StatusTypeDef status; uint8_t ACK; uint8_t frame[5]; frame[0] = RMEM_COMMAND; frame[1] = RMEM_COMMAND ^ 0xFFU; status = BL_Transmit(frame, 2); status = BL_Receive(&ACK, 1); if (ACK == 0x79) { frame[0] = (uint8_t)((address >> 24) & 0xFFU); frame[1] = (uint8_t)((address >> 16) & 0xFFU); frame[2] = (uint8_t)((address >> 8) & 0xFFU); frame[3] = (uint8_t)(address & 0xFFU); frame[4] = xor_checksum(frame, 4U); status = BL_Transmit(frame, 5); ACK = 0; status = BL_Receive(&ACK, 1); if (ACK == 0x79) { frame[0] = (nob - 1U); frame[1] = (nob - 1U) ^ 0xFFU; status = BL_Transmit(frame, 2); ACK = 0; status = BL_Receive(&ACK, 1); if (ACK == 0x79) { status = BL_Receive(pData, nob);//data+ack ACK = 0; } else return HAL_ERROR; } else return HAL_ERROR; } else return HAL_ERROR; return HAL_OK; } HAL_StatusTypeDef BL_WriteMemory(uint32_t address, uint16_t nob, uint8_t *pData) { HAL_StatusTypeDef status; uint8_t ACK=0; uint8_t frame[258]; uint8_t checksum = xor_checksum(pData, nob) ^ (nob - 1U ); frame[0] = WMEM_COMMAND; frame[1] = WMEM_COMMAND ^ 0xFFU; status = BL_Transmit(frame, 2); ACK = 0; status = BL_Receive(&ACK, 1); if (ACK == 0x79) { frame[0] = ((uint8_t)(address >> 24) & 0xFFU); frame[1] = ((uint8_t)(address >> 16) & 0xFFU); frame[2] = ((uint8_t)(address >> 8) & 0xFFU); frame[3] = ((uint8_t) address & 0xFFU); frame[4] = xor_checksum(frame, 4U); status = BL_Transmit(frame, 5); ACK = 0; status = BL_Receive(&ACK, 1); if (ACK == 0x79) { frame[0] = nob - 1U; memcpy(&frame[1], pData, nob); frame[nob + 1] = checksum; status = BL_Transmit(frame, (uint16_t) nob + 2); status = BL_Receive(&ACK, 1); } else return HAL_ERROR; } else return HAL_ERROR; return HAL_OK; } HAL_StatusTypeDef BL_EraseMemory(uint16_t nb, uint8_t code) { HAL_StatusTypeDef status; uint8_t ACK; uint8_t frame[3]; frame[0] = EMEM_COMMAND; frame[1] = EMEM_COMMAND ^ 0xFFU; status = BL_Transmit(frame, 2); status = BL_Receive(&ACK, 1); if (ACK == 0x79) { frame[0] = (uint8_t)(nb >> 8) & 0xFFU; frame[1] = (uint8_t) nb & 0xFFU; frame[2] = frame[0] ^ frame[1]; status = BL_Transmit(frame, 3); status = BL_Receive(&ACK, 1); if (ACK == 0x79) { if ((nb >> 4) != 0xFFF) { frame[0] = (uint8_t)(code >> 8) & 0xFFU; frame[1] = code & 0xFFU; frame[2] = frame[0] ^ frame[1]; status = BL_Transmit(frame, 3); status = BL_Receive(&ACK, 1); } } else return HAL_ERROR; } else return HAL_ERROR; return HAL_OK; } static uint8_t xor_checksum(const uint8_t pData[], uint16_t len) { uint8_t sum = *pData; for (uint16_t i = 1U; i < len; i++) sum ^= pData[i]; return sum; }
В кубе в i2c не забыть поставить галочки на прерываниях.
Код для тестирования
uint8_t trsmt[256]; uint8_t recv[257];//add ack HAL_StatusTypeDef status; uint8_t tmp; for (uint16_t i = 0; i < 256; i++) trsmt[i] = i; BL_Init(&hi2c2); while (1) { tmp = BL_GetVersion(); status = BL_EraseMemory(0xffff, 1); tmp = 0; tmp = BL_GetVersion(); status = BL_ReadMemory(0x08000000, 256, recv); tmp = 0; tmp = BL_GetVersion(); status = BL_WriteMemory(0x08000000, 256, trsmt); tmp = 0; tmp = BL_GetVersion(); status = BL_ReadMemory(0x08000000, 256, recv); }
ps. Допилил http server на основном контроллере, теперь 4 слэйва обновляю через вебморду. Мастер обновляю через http IAP Bootloader )))
-
Разобрался как принимать байты. Загрузчик работает только побайтно
if (ACK == 0x79) { status = HAL_I2C_Master_Receive_IT(I2cHandle, 0xa6, &dat[0], 1); //https://www.st.com/resource/en/application_note/dm00072315-i2c-protocol-used-in-the-stm32-bootloader-stmicroelectronics.pdf //page 11 //Byte 2: Bootloader version (0 < Version ≤ 255) (for example, 0x10 = Version 1.0) while (HAL_I2C_GetState(I2cHandle) != HAL_I2C_STATE_READY) ; status = HAL_I2C_Master_Receive_IT(I2cHandle, 0xa6, &dat[1], 1); //Byte 3: ACK while (HAL_I2C_GetState(I2cHandle) != HAL_I2C_STATE_READY) ; }
Пропали залипания линии SCL и начали приходить адекватные ответы
-
Добрый день.
Я пытаюсь достучаться до встроенного загрузчика через другой микроконтроллер по протоколу I2C.
RST выставляю в 0, BOOT0 в 1 и отпускаю RST
//i2c 100kHz HAL_StatusTypeDef status; uint8_t tmp[2]; uint8_t dat[21]; uint8_t ACK; while(HAL_I2C_GetState(I2cHandle) != HAL_I2C_STATE_READY); status = HAL_I2C_Master_Transmit_IT(I2cHandle, 0xa6, dat, 1); while (HAL_I2C_GetState(I2cHandle) != HAL_I2C_STATE_READY) ; status = HAL_I2C_Master_Receive_IT(I2cHandle, 0xa6, &ACK, 1); while(1) { tmp[0] = 1;//Get Version command tmp[1] = 0xfe;//XOR tmp[0] while (HAL_I2C_GetState(I2cHandle) != HAL_I2C_STATE_READY) ; status = HAL_I2C_Master_Transmit_IT(I2cHandle, 0xa6, tmp, 2); memset(dat, 0, sizeof(dat)); while (HAL_I2C_GetState(I2cHandle) != HAL_I2C_STATE_READY) ; status = HAL_I2C_Master_Receive_IT(I2cHandle, 0xa6, &ACK, 1); if (ACK == 0x79) { while (HAL_I2C_GetState(I2cHandle) != HAL_I2C_STATE_READY) ; status = HAL_I2C_Master_Receive_IT(I2cHandle, 0xa6, dat, 2); //Практически всегда получаю нули. Иногда приходит 0x12 0xff } else if (ACK == 0x1f)//nack { //Иногда попадаю сюда } else if(ACK == 0x76)//busy { } else { } }
В документе AN2606 слэйв адрес указан 0b1010100x. У меня получилось достучаться только по адресу 0b1010011x. Это ошибка документации?
В AN4221 очень мало информации по протоколу.
По коду, что выше, слэйв часто притягивает линию SCL до 10 секунд.
ACK (0x76) получаю, иногда NACK.
В ответ в массиве нули. Иногда проскакивает 0x12 0xff
Как правильно работать с бутом по этому протоколу?
-
On 11/2/2019 at 12:58 PM, __inline__ said:
Круто конечно, но с ПИК-ами дел не имел от слова "вообще"!
Когда часто меняешь архитектуру, то уже без разницы какой камень выбирать. Больше смотришь на фичи типа потребления, периферии
Мой путь был такой - MCS-51, AVR (сначала на ASM потом на С и потом С++ баловался), PIC16, PIC18, dsPIC33, PIC32, XMC4800 ради Ethercat, STM32f1, STM32f4, STM32F7. Сейчас присматриваюсь к FPGA Xilinx Zynq 7010 SOC c DUAL CORE ARM CORTEX A9 (Хочу разобраться с Linux), платка уже лежит на столе
-
On 10/13/2019 at 1:06 PM, __inline__ said:
неудобнопаяемые ноги! )))
всё-же при наличии выбора, предпочтение отдам за SOT23-6. Такая кроха была нужна для засылки битов по SPI, затем в останов. Более не нужно.
Но за информацию всёравно - спасибо!
в таком корпусе вспоминаются еще PIC10F200T, PIC10F222T, PIC10F320T-I/OT
И потребление в активном режиме почти на порядок меньше чем у Attiny
-
On 1/31/2018 at 9:50 AM, simark1979 said:
Если есть инфа, по работе этих функций (интересует что конкретно происходит на шине, если эти функции вызывать в разных режимах:
- I2C_FIRST_FRAME
- I2C_NEXT_FRAME
- I2C_FIRST_AND_LAST_FRAME
- I2C_LAST_FRAME
Внутри stm32f7xx_hal_i2c.c есть описание
(@) These interfaces allow to manage a sequential transfer with a repeated start condition
when a direction change during transfer
[..]
(+) A specific option field manage the different steps of a sequential transfer
(+) Option field values are defined through @ref I2C_XFEROPTIONS and are listed below:
(++) I2C_FIRST_AND_LAST_FRAME: No sequential usage, functionnal is same as associated interfaces in no sequential mode
(++) I2C_FIRST_FRAME: Sequential usage, this option allow to manage a sequence with start condition, address
and data to transfer without a final stop condition
(++) I2C_FIRST_AND_NEXT_FRAME: Sequential usage (Master only), this option allow to manage a sequence with start condition, address
and data to transfer without a final stop condition, an then permit a call the same master sequential interface
several times (like @ref HAL_I2C_Master_Seq_Transmit_IT() then @ref HAL_I2C_Master_Seq_Transmit_IT()
or @ref HAL_I2C_Master_Seq_Transmit_DMA() then @ref HAL_I2C_Master_Seq_Transmit_DMA())
(++) I2C_NEXT_FRAME: Sequential usage, this option allow to manage a sequence with a restart condition, address
and with new data to transfer if the direction change or manage only the new data to transfer
if no direction change and without a final stop condition in both cases
(++) I2C_LAST_FRAME: Sequential usage, this option allow to manage a sequance with a restart condition, address
and with new data to transfer if the direction change or manage only the new data to transfer
if no direction change and with a final stop condition in both cases
(++) I2C_LAST_FRAME_NO_STOP: Sequential usage (Master only), this option allow to manage a restart condition after several call of the same master sequential
interface several times (link with option I2C_FIRST_AND_NEXT_FRAME).
Usage can, transfer several bytes one by one using HAL_I2C_Master_Seq_Transmit_IT(option I2C_FIRST_AND_NEXT_FRAME then I2C_NEXT_FRAME)
or HAL_I2C_Master_Seq_Receive_IT(option I2C_FIRST_AND_NEXT_FRAME then I2C_NEXT_FRAME)
or HAL_I2C_Master_Seq_Transmit_DMA(option I2C_FIRST_AND_NEXT_FRAME then I2C_NEXT_FRAME)
or HAL_I2C_Master_Seq_Receive_DMA(option I2C_FIRST_AND_NEXT_FRAME then I2C_NEXT_FRAME).
Then usage of this option I2C_LAST_FRAME_NO_STOP at the last Transmit or Receive sequence permit to call the oposite interface Receive or Transmit
without stopping the communication and so generate a restart condition.
(++) I2C_OTHER_FRAME: Sequential usage (Master only), this option allow to manage a restart condition after each call of the same master sequential
interface.
Usage can, transfer several bytes one by one with a restart with slave address between each bytes using HAL_I2C_Master_Seq_Transmit_IT(option I2C_FIRST_FRAME then I2C_OTHER_FRAME)
or HAL_I2C_Master_Seq_Receive_IT(option I2C_FIRST_FRAME then I2C_OTHER_FRAME)
or HAL_I2C_Master_Seq_Transmit_DMA(option I2C_FIRST_FRAME then I2C_OTHER_FRAME)
or HAL_I2C_Master_Seq_Receive_DMA(option I2C_FIRST_FRAME then I2C_OTHER_FRAME).
Then usage of this option I2C_OTHER_AND_LAST_FRAME at the last frame to help automatic generation of STOP condition.
-
Может поможет, у меня похожая задача была - считать device id FRAM MR44V100A
Device ID Read Sequence 1. Next to Start condition, send 0xF8. MR44V100A responds ACK signal. 2. Send the Slave address (WA16 and R/W are “Don’t care”). MR44V100A responds ACK signal. 3. Again next to Start condition, send 0xF9. MR44V100A responds ACK signal, then outputs 3 bytes of Device ID. 4. Send Stop condition and finish the sequence.
Решил эту проблему через HAL так
В кубе поставил галочки
и написал вот такой код
#include "MR44V100A.h" //private varibales static uint8_t device_address; static I2C_HandleTypeDef *hi2c; HAL_StatusTypeDef MR44V100A_Init(I2C_HandleTypeDef *handle_i2c, uint8_t dev_addr) { HAL_StatusTypeDef status; device_address = dev_addr; hi2c = handle_i2c; uint8_t tmp[3]; tmp[0]= (device_address << 1); status = HAL_I2C_Master_Seq_Transmit_IT(hi2c, 0xF8, &tmp[0], 1, I2C_FIRST_FRAME); if (status != HAL_OK) return status; while (HAL_I2C_GetState(hi2c) != HAL_I2C_STATE_READY) ; status = HAL_I2C_Master_Seq_Receive_IT(hi2c, 0xF9, tmp, 3, I2C_LAST_FRAME); if (status != HAL_OK) return status; while (HAL_I2C_GetState(hi2c) != HAL_I2C_STATE_READY) ; if ((tmp[0]==0x01)&&(tmp[1]==0xb0)&&(tmp[2]==0x00))//MR44V100A ID read OK return HAL_OK; else return HAL_ERROR; } HAL_StatusTypeDef MR44V100A_readByte(uint32_t register_address, uint8_t* data) { return MR44V100A_readBytes(register_address, 1, data); } HAL_StatusTypeDef MR44V100A_writeByte(uint32_t register_address, uint8_t data) { return MR44V100A_writeBytes(register_address, 1, &data); } HAL_StatusTypeDef MR44V100A_writeBytes(uint32_t register_address, uint32_t length, uint8_t* data) { assert_param((register_address + length - 1) <= 0x1FFFF); HAL_StatusTypeDef status = HAL_I2C_Mem_Write( hi2c, (device_address << 1) | (((register_address&(1 << 16)) ? 1 : 0) << 1), //add 16th bit of address(WA16) (uint16_t)register_address, I2C_MEMADD_SIZE_16BIT, data, length, 1000); while (HAL_I2C_IsDeviceReady(hi2c, (device_address << 1), 1, HAL_MAX_DELAY) != HAL_OK) ; return status; } HAL_StatusTypeDef MR44V100A_readBytes(uint32_t register_address, uint32_t length, uint8_t* data) { assert_param((register_address + length - 1) <= 0x1FFFF); return HAL_I2C_Mem_Read( hi2c, (device_address << 1) | (((register_address&(1 << 16)) ? 1 : 0) << 1), (uint16_t)register_address, I2C_MEMADD_SIZE_16BIT, data, length, 1000); }
ps Посмотрел логическим анализатором шину, после первой посылки STOP не формируется
-
В первую очередь на разводку земель надо обращать внимание
-
Прошивал китайские ST-Link v2 патченным Reflash. (STLinkReflashFixed.exe)
-
19 hours ago, HardEgor said:
Спасибо за пояснения. Нашел в HAL библиотеке функции
/* Battery control functions */
void HAL_PWREx_EnableBatteryCharging(uint32_t ResistorValue);
void HAL_PWREx_DisableBatteryCharging(void);/* Power VBAT/Temperature monitoring functions */
void HAL_PWREx_EnableMonitoring(void);
void HAL_PWREx_DisableMonitoring(void);
uint32_t HAL_PWREx_GetTemperatureLevel(void);
uint32_t HAL_PWREx_GetVBATLevel(void); -
Изучаю H7 серию и натолкнулся в описании на Low-power modes: Sleep, Stop, Standby and VBAT supporting battery charging
Означает ли это, что я могу поставить аккумулятор и не беспокоитбся о схеме зарядки?
Аккумулятор типа такого https://www.digikey.com/product-detail/en/seiko-instruments/ML414H-IV01E/728-1052-1-ND/1889213
-
On 4/30/2019 at 4:50 PM, MiklPolikov said:
И так:
по совокупности результатов, Visual Studio объявляется глючной и кривой хренью.
Невозможно просто открыть и начать работать: постоянно просит скачать какое-то обновление, после скачивания говорит, что с новым обновлением не работает что-то старое, и то же нужно обновлять, и т.п.
Иногда начинает обновляться прямо по среди работы, при хорошей скорости интернета "залипает" на 20 мин. И всё это криво и косо, каждый раз с непредсказуемым результатом.
Проекты, которые удалось откомпилировать неделю назад, уже ни один не работают, т.к. после обновлений что-то стало не совместимо.Финальный аккорд: когда стал удалять, вылезло сообщение, что сначала нужно обновить установщик .
Уже два года сижу на Visual Studio, после Keil и IAR не нарадуюсь удобству редактирования кода
-
Я использую макрос __LL_ADC_CALC_TEMPERATURE из stm32f4xx_ll_adc.h. Библиотека использует калибровочные данные из адресов
#define TEMPSENSOR_CAL1_ADDR ((uint16_t*) (0x1FFF7A2CU)) /* Internal temperature sensor, address of parameter TS_CAL1: On STM32F4, temperature sensor ADC raw data acquired at temperature 30 DegC (tolerance: +-5 DegC), Vref+ = 3.3 V (tolerance: +-10 mV). */
#define TEMPSENSOR_CAL2_ADDR ((uint16_t*) (0x1FFF7A2EU)) /* Internal temperature sensor, address of parameter TS_CAL2: On STM32F4, temperature sensor ADC raw data acquired at temperature 110 DegC (tolerance: +-5 DegC), Vref+ = 3.3 V (tolerance: +-10 mV). */Пример использования есть в STM32Cube\Repository\STM32Cube_FW_F4_V1.24.0\Projects\STM32F411RE-Nucleo\Examples_LL\ADC\ADC_TemperatureSensor\
Для F7 серии STM32Cube\Repository\STM32Cube_FW_F7_V1.15.0\Projects\STM32F767ZI-Nucleo\Examples_LL\ADC\ADC_TemperatureSensor\
F3 STM32Cube\Repository\STM32Cube_FW_F3_V1.10.0\Projects\STM32F334R8-Nucleo\Examples_LL\ADC\ADC_TemperatureSensor\
F2 STM32Cube\Repository\STM32Cube_FW_F2_V1.7.0\Projects\STM32F207ZG-Nucleo\Examples_LL\ADC\ADC_TemperatureSensor\
F1 STM32Cube\Repository\STM32Cube_FW_F1_V1.7.0\Projects\STM32F103RB-Nucleo\Examples_LL\ADC\ADC_TemperatureSensor\
F0 STM32Cube\Repository\STM32Cube_FW_F0_V1.9.0\Projects\STM32F072RB-Nucleo\Examples_LL\ADC\ADC_TemperatureSensor\
-
Нашел статью, где работают с 15-омными датчиками
-
-
-
В настройках Debug поставить вместо оптимизации -O0 - -Og и посмотреть что получится
-
Еще неплохо бы глянуть логи \Debug\EmbeddedProject1.log
-
Как-то быстро нужно было узнать температуру, так применил MAX31855 и распаял ее на макетке. Хотя для точных измерений она наверное не подойдет
-
20 minutes ago, V_G said:
Для двух ОУ обычные DC-DC c мощностью более 1 Вт - слишком жирно. Поищите по ключевым словам Charge Pump Regulator, в них нет катушек. У ti это LT1054, но там только одно выходное напряжение
Наверное имелась ввиду MAX680, но там +-2Vin. Как вариант, потом поставить 2 линейных в sot23 корпусе.
ps Входное до 6В. Не подойдет
-
Может есть возможность поставить плоский конденсатор с обратной стороны платы типа такого https://www.digikey.com/product-detail/en/elna-america/DSK-3R3H204T614-H2L/604-1147-1-ND/2171202
ps Глянул ваши конденсаторы, эти по внутреннему сопротивлению не подойдут
-
On 12/21/2018 at 2:16 PM, Arlleex said:
Хорошо. Тогда скрин первых слов памяти программ из STLink Utility можно глянуть? Там, где таблица векторов...
И да, почему бы просто не зайти под отладчиком? Сделать сброс и пройтись по шагам в ассемблерном окне?
Кстати да, где скрин? Возможно таблицы векторов просто нет. Было похожее, когда файл startup_stm32* загадочным образом из проекта исчез. В отладке сразу hardfault
-
Компилятор вместе со средой можно скачать бесплатно, для маленького кода можно использовать также бесплатно:
https://www.keil.com/download/product/
https://www.iar.com/iar-embedded-workbench/
Есть и другие среды, целиком бесплатные (на базе компилятора GCC).
Внутри любой нормальной среды есть симулятор, тогда отладочная плата для данной ситуации не обязательна.
С осциллографом измерения уже делали )
https://blog.classycode.com/esp32-floating-...ce-6e9f6f567a69
В микросекундах
Ядрa: Cortex-M1 и Cortex-M4F (что не особо важно, т.к. расчеты должны быть в формате double и плавающая запятая в Cortex-M4F не поможет)Спасибо
Можно попробовать использовать ядро Cortex-M7 с double precission FPU
Расскажите про EtherCAT
в Интерфейсы
Опубликовано · Пожаловаться
Кто-нибудь применял FIDO5200? https://www.analog.com/en/products/fido5200.html ? В документе как пример стыковка с STM32F103 приведена https://www.analog.com/media/en/technical-documentation/application-notes/AN-1554.pdf