diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml index 6ace92a..131c940 100644 --- a/.settings/language.settings.xml +++ b/.settings/language.settings.xml @@ -5,7 +5,7 @@ - + @@ -16,7 +16,7 @@ - + diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 7003de5..b718451 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -21,6 +21,7 @@ "USE_HAL_DRIVER", "STM32F407xx" ], + "compilerPath": "C:/ST/STM32CubeIDE_1.13.0/STM32CubeIDE/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.11.3.rel1.win32_1.1.0.202305231506/tools/bin/arm-none-eabi-g++.exe", "intelliSenseMode": "${default}" } ], diff --git a/usrc/main.cpp b/usrc/main.cpp index 42cce5d..299e5a3 100644 --- a/usrc/main.cpp +++ b/usrc/main.cpp @@ -16,13 +16,14 @@ #include "sdk\components\tmc\ic\ztmc5130.hpp" // #include "sdk\components\hardware\uart\zuart_dma_receiver.hpp" +#include "serial485_to_analog.hpp" #include "temperature_sensor.hpp" - #define TAG "main" using namespace iflytop; using namespace std; static ZCancmderSubboardIniter initer; +static Serial485ToAnalog serial485_to_analog; extern void umain(); extern "C" { @@ -77,44 +78,61 @@ static void initsubmodule() { } { /******************************************************************************* - * 温度传感器MODBUS CLIEN 初始化 * + * 温度4->20MA转485 * *******************************************************************************/ + /** + * @brief + * 串口参数: + * 115200 + * 奇偶校验位:无校验 + * 停止位:一个停止位 + */ + ZASSERT(PC_MODBUS_UART.Init.BaudRate == 115200); + ZASSERT(PC_MODBUS_UART.Init.Parity == UART_PARITY_NONE); + ZASSERT(PC_MODBUS_UART.Init.StopBits == UART_STOPBITS_1); + serial485_to_analog.initialize(&PC_MODBUS_UART, NULL, NULL); + serial485_to_analog.reg(&m_temperature_sensor[0]); + serial485_to_analog.reg(&m_temperature_sensor[1]); + serial485_to_analog.reg(&m_temperature_sensor[2]); + serial485_to_analog.reg(&m_temperature_sensor[3]); + serial485_to_analog.reg(&m_temperature_sensor[4]); + serial485_to_analog.start(); - static ZUARTDmaReceiver dmaUartReceiver; - static ZUARTDmaReceiver::hardware_config_t cfg = { - .huart = &PC_MODBUS_UART, - .dma_rx = &PC_MODBUS_UART_DMA_HANDLER, - .rxbuffersize = PC_MODBUS_UART_RX_BUF_SIZE, - .rxovertime_ms = 1, - }; - dmaUartReceiver.initialize(&cfg); + // static ZUARTDmaReceiver dmaUartReceiver; + // static ZUARTDmaReceiver::hardware_config_t cfg = { + // .huart = &PC_MODBUS_UART, + // .dma_rx = &PC_MODBUS_UART_DMA_HANDLER, + // .rxbuffersize = PC_MODBUS_UART_RX_BUF_SIZE, + // .rxovertime_ms = 1, + // }; + // dmaUartReceiver.initialize(&cfg); - static UARTSender uartSender; - uartSender.init(&PC_MODBUS_UART); + // static UARTSender uartSender; + // uartSender.init(&PC_MODBUS_UART); - ModulebusClient::Inst()->init( - &dmaUartReceiver, &uartSender, 1, // - [](uint16_t regadd, uint16_t& val) { - int32_t sendval = 0; - if (regadd == 11) { - m_temperature_sensor[0].getTemperature(sendval); - val = sendval; - } else if (regadd == 12) { - m_temperature_sensor[1].getTemperature(sendval); - val = sendval; - } else if (regadd == 13) { - m_temperature_sensor[2].getTemperature(sendval); - val = sendval; - } else if (regadd == 14) { - m_temperature_sensor[3].getTemperature(sendval); - val = sendval; - } else if (regadd == 15) { - m_temperature_sensor[4].getTemperature(sendval); - val = sendval; - } - }, // - [](uint16_t regadd, uint16_t val) {}); - OSDefaultSchduler::getInstance()->regPeriodJob([](OSDefaultSchduler::Context& context) { ModulebusClient::Inst()->loop(); }, 1); + // ModulebusClient::Inst()->init( + // &dmaUartReceiver, &uartSender, 1, // + // [](uint16_t regadd, uint16_t& val) { + // int32_t sendval = 0; + // if (regadd == 11) { + // m_temperature_sensor[0].getTemperature(sendval); + // val = sendval; + // } else if (regadd == 12) { + // m_temperature_sensor[1].getTemperature(sendval); + // val = sendval; + // } else if (regadd == 13) { + // m_temperature_sensor[2].getTemperature(sendval); + // val = sendval; + // } else if (regadd == 14) { + // m_temperature_sensor[3].getTemperature(sendval); + // val = sendval; + // } else if (regadd == 15) { + // m_temperature_sensor[4].getTemperature(sendval); + // val = sendval; + // } + // }, // + // [](uint16_t regadd, uint16_t val) {}); + // OSDefaultSchduler::getInstance()->regPeriodJob([](OSDefaultSchduler::Context& context) { ModulebusClient::Inst()->loop(); }, 1); } { // 115200 diff --git a/usrc/serial485_to_analog.cpp b/usrc/serial485_to_analog.cpp new file mode 100644 index 0000000..7d05b68 --- /dev/null +++ b/usrc/serial485_to_analog.cpp @@ -0,0 +1,64 @@ +#include "serial485_to_analog.hpp" +#include "sdk\components\modbus\modbus_basic.hpp" +using namespace iflytop; +using namespace std; + +void Serial485ToAnalog::initialize(UART_HandleTypeDef* uart, DMA_HandleTypeDef* hdma_tx, DMA_HandleTypeDef* hdma_rx) { + m_uart = uart; + m_hdma_tx = hdma_tx; + m_hdma_rx = hdma_rx; +} + +void Serial485ToAnalog::reg(TemperatureSensor* ts) { + ZASSERT(m_sensorNum < ZARRAY_SIZE(m_sensor)); + m_sensor[m_sensorNum] = ts; + m_sensorNum++; +} + +void Serial485ToAnalog::start() { + zthread.init("Serial485ToAnalog-thread"); + zthread.start([this]() { + while (!zthread.getExitFlag()) { + float temperture_i_val[5] = {0}; // 温度电流数值 + static_assert(ZARRAY_SIZE(temperture_i_val) == ZARRAY_SIZE(m_sensor)); + + for (int i = 0; i < m_sensorNum; i++) { + temperture_i_val[i] = m_sensor[i]->readCurrentVal(); + } + + // 参考 模拟量输出系列使用手册(RS485版).pdf + // 3位小数点,电压输出:分辨率0.001V。 + // 0064H 通道1 + // 0065H 通道2 + // 0066H 通道3 + // 0067H 通道4 + // 0068H 通道5 + + uint16_t write_reg_val[5] = {0}; + for (int i = 0; i < m_sensorNum; i++) { + write_reg_val[i] = (uint16_t)(temperture_i_val[i] * 1000); + } + writeReg10Muti(0x01, 0x0064, write_reg_val, m_sensorNum, 1000); + zthread.sleep(10); + } + }); +} + +int32_t Serial485ToAnalog::writeReg10Muti(uint8_t slaveAddr, uint16_t regAddr, uint16_t* regVal, uint16_t nreg, int overtimems) { + m_txbuff[0] = slaveAddr; + m_txbuff[1] = 0x10; + m_txbuff[2] = regAddr >> 8; + m_txbuff[3] = regAddr & 0xff; + m_txbuff[4] = 0x00; + m_txbuff[5] = nreg; + m_txbuff[6] = nreg * 2; // 字节数 + for (int i = 0; i < nreg; i++) { + m_txbuff[7 + i * 2] = regVal[i] >> 8; + m_txbuff[8 + i * 2] = regVal[i] & 0xff; + } + + modbus_pack_crc_to_packet(m_txbuff, 7 + nreg * 2 + 2); + HAL_UART_Transmit(m_uart, m_txbuff, 7 + nreg * 2 + 2, 1000); + + return 0; +} diff --git a/usrc/serial485_to_analog.hpp b/usrc/serial485_to_analog.hpp new file mode 100644 index 0000000..910b6b8 --- /dev/null +++ b/usrc/serial485_to_analog.hpp @@ -0,0 +1,55 @@ +// +// Created by zwsd +// + +#pragma once +#include "sdk/os/zos.hpp" +// +#include "sdk/chip/api/zi_temperature.hpp" +#include "sdk\chip\api\zi_adc.hpp" +#include "sdk\components\hardware\adc\z_simple_adc.hpp" +#include "sdk\components\zprotocols\zcancmder_v2\api\api.hpp" +#include "temperature_sensor.hpp" + +namespace iflytop { +using namespace std; + +class Serial485ToAnalog { + private: + uint8_t m_txbuff[128]; + TemperatureSensor* m_sensor[5] = {NULL}; + int m_sensorNum = 0; + + UART_HandleTypeDef* m_uart; + DMA_HandleTypeDef* m_hdma_tx; + DMA_HandleTypeDef* m_hdma_rx; + int m_baudrate; + + ZThread zthread; + + // int32_t ZADC::get_adc_value(int32_t& adcval) { + // ADC_ChannelConfTypeDef sConfig = {0}; + // sConfig.Channel = m_channel; /* 通道 */ + // sConfig.Rank = 1; + // sConfig.SamplingTime = m_samplingTime; /* 采样时间 */ + // if (HAL_ADC_ConfigChannel(m_hadc1, &sConfig) != HAL_OK) { + // return err::kmicro_adcRecvFail; + // } + // HAL_ADC_Start(m_hadc1); + // HAL_ADC_PollForConversion(m_hadc1, HAL_MAX_DELAY); + // adcval = (uint16_t)HAL_ADC_GetValue(m_hadc1); + // return 0; + // } + + public: + void initialize(UART_HandleTypeDef* uart, DMA_HandleTypeDef* hdma_tx, DMA_HandleTypeDef* hdma_rx); + void reg(TemperatureSensor* ts); + + void start(); + + private: + int32_t writeReg10Muti(uint8_t slaveAddr, uint16_t regAddr, uint16_t* regVal, uint16_t nreg, int overtimems); + void txAndRx(uint8_t* tx, uint8_t txdatalen, uint8_t* rx, uint8_t expectrxsize, uint16_t overtimems); +}; + +} // namespace iflytop \ No newline at end of file diff --git a/usrc/temperature_sensor.cpp b/usrc/temperature_sensor.cpp index 163b2a9..98ae717 100644 --- a/usrc/temperature_sensor.cpp +++ b/usrc/temperature_sensor.cpp @@ -7,6 +7,15 @@ void TemperatureSensor::initialize(ADC_HandleTypeDef* hadc1, int32_t channel) { m_adc.initialize(hadc1, channel); } +float TemperatureSensor::readCurrentVal() { + int32_t adcval = 0; + m_adc.get_adc_value(adcval); + float v = adcval * 3.3 / 4096; + float I = v / 150.0 * 1000; + + return I; +} + int32_t TemperatureSensor::_getTemperature(int32_t& sensorval) { // 4000ma->20ma ==> 0->350 // V=150*I diff --git a/usrc/temperature_sensor.hpp b/usrc/temperature_sensor.hpp index 034855e..8305080 100644 --- a/usrc/temperature_sensor.hpp +++ b/usrc/temperature_sensor.hpp @@ -49,6 +49,8 @@ class TemperatureSensor : public ZITemperature { virtual int32_t getTemperature(int32_t& sensorval); + float readCurrentVal();//读取当前电流数值 + private: int32_t _getTemperature(int32_t& sensorval); }; diff --git a/妯℃嫙閲忚緭鍑虹郴鍒椾娇鐢ㄦ墜鍐(RS485鐗).pdf b/妯℃嫙閲忚緭鍑虹郴鍒椾娇鐢ㄦ墜鍐(RS485鐗).pdf new file mode 100644 index 0000000..20370c6 Binary files /dev/null and b/妯℃嫙閲忚緭鍑虹郴鍒椾娇鐢ㄦ墜鍐(RS485鐗).pdf differ