Jump to content

    

BioWolf2000

Свой
  • Content Count

    109
  • Joined

  • Last visited

Community Reputation

0 Обычный

About BioWolf2000

  • Rank
    Частый гость
  • Birthday 02/21/1980

Старые поля

  • LinkedIn
    Array

Контакты

  • Сайт
    Array
  • ICQ
    Array
  • Skype
    Array

Информация

  • Город
    Array

Recent Profile Visitors

2974 profile views
  1. Неплохо получается 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 тоже есть
  2. Привожу код, который заработал. Из-за дурацкой документации 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 )))
  3. Разобрался как принимать байты. Загрузчик работает только побайтно 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 и начали приходить адекватные ответы
  4. Добрый день. Я пытаюсь достучаться до встроенного загрузчика через другой микроконтроллер по протоколу 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 Как правильно работать с бутом по этому протоколу?
  5. Когда часто меняешь архитектуру, то уже без разницы какой камень выбирать. Больше смотришь на фичи типа потребления, периферии Мой путь был такой - 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), платка уже лежит на столе
  6. в таком корпусе вспоминаются еще PIC10F200T, PIC10F222T, PIC10F320T-I/OT И потребление в активном режиме почти на порядок меньше чем у Attiny
  7. I2C HAL DS2482

    Внутри 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.
  8. I2C HAL DS2482

    Может поможет, у меня похожая задача была - считать 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 не формируется
  9. В первую очередь на разводку земель надо обращать внимание https://www.rezonit.ru/support/articles/cad/03/ http://caxapa.ru/lib/emc_immunity.html
  10. Прошивал китайские ST-Link v2 патченным Reflash. (STLinkReflashFixed.exe)
  11. Спасибо за пояснения. Нашел в 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);
  12. Изучаю 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
  13. Уже два года сижу на Visual Studio, после Keil и IAR не нарадуюсь удобству редактирования кода
  14. Я использую макрос __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. Нашел статью, где работают с 15-омными датчиками Photocurrent Measurement of PC and PV HgCdTe Detectors