#include "sgm51652hx.h" #include "gd32h7xx_gpio.h" #include "FreeRTOS.h" #include "task.h" /*! \brief 初始化SGM51652HX芯片 \param[in] dev: 芯片设备结构体指针 \param[in] spi_dev: SPI设备结构体指针 \param[out] none \retval 0: 成功, -1: 失败 */ int sgm51652hx_init(sgm51652hx_dev_t *dev, spi_dev_t *spi_dev) { if (!dev || !spi_dev || !spi_dev->initialized) { return ERR_INVALIDPARAMETER; } /* 初始化设备结构体 */ dev->spi_dev = *spi_dev; dev->initialized = 1; return ERR_OK_SGM; } /*! \brief 去初始化SGM51652HX芯片 \param[in] dev: 芯片设备结构体指针 \param[out] none \retval 0: 成功, -1: 失败 */ int sgm51652hx_deinit(sgm51652hx_dev_t *dev) { if (!dev || !dev->initialized) { return ERR_INVALIDPARAMETER; } /* 复位芯片 */ spi_rst_control(&dev->spi_dev, 1); dev->initialized = 0; return ERR_OK_SGM; } /*! \brief 向SGM51652HX芯片写入寄存器 \param[in] dev: 芯片设备结构体指针 \param[in] reg: 寄存器地址 \param[in] value: 要写入的值 \param[out] none \retval 0: 成功, -1: 失败 */ int sgm51652hx_write_reg(sgm51652hx_dev_t *dev, uint8_t reg, uint8_t value) { if (!dev || !dev->initialized) { return ERR_INVALIDPARAMETER; } /* 选中芯片 */ spi_cs_control(&dev->spi_dev, 1); /* 开启发送 */ spi_master_transfer_start(dev->spi_dev.spi, SPI_TRANS_START); /* 发送写命令:寄存器地址 << 1 | 1 */ uint8_t cmd = (reg << 1) | 1; spi_transmit_receive_byte(dev->spi_dev.spi, cmd); //TBD:经测试,调用发送接收函数,后续采样正常,如果只调用发送函数,后续采样不正常;但另一版程序没有此问题,原因待定 lyn260411 /* 发送数据 */ spi_transmit_receive_byte(dev->spi_dev.spi, value); /* 发送两个空字节 */ spi_transmit_receive_byte(dev->spi_dev.spi, 0x00); spi_transmit_receive_byte(dev->spi_dev.spi, 0x00); /* 取消片选 */ spi_cs_control(&dev->spi_dev, 0); return ERR_OK_SGM; } /*! \brief 从SGM51652HX芯片读取寄存器 \param[in] dev: 芯片设备结构体指针 \param[in] reg: 寄存器地址 \param[out] value: 读取的值 \retval 0: 成功, -1: 失败 */ int sgm51652hx_read_reg(sgm51652hx_dev_t *dev, uint8_t reg, uint8_t *value) { if (!dev || !dev->initialized || !value) { return ERR_INVALIDPARAMETER; } /* 选中芯片 */ spi_cs_control(&dev->spi_dev, 1); /* 开启发送 */ spi_master_transfer_start(dev->spi_dev.spi, SPI_TRANS_START); /* 发送读命令:寄存器地址 << 1 | 0 */ uint8_t cmd = (reg << 1) | 0; spi_transmit_byte(dev->spi_dev.spi, cmd); /* 发送空字节 */ spi_transmit_byte(dev->spi_dev.spi, 0x00); /* 读取数据 */ *value = spi_receive_byte(dev->spi_dev.spi); /* 读取最后一个空字节 */ spi_receive_byte(dev->spi_dev.spi); /* 取消片选 */ spi_cs_control(&dev->spi_dev, 0); return ERR_OK_SGM; } /*! \brief 设置SGM51652HX芯片通道量程 \param[in] dev: 芯片设备结构体指针 \param[in] channel: 通道号 (0-7) \param[in] range: 量程配置值 \param[out] none \retval 0: 成功, -1: 失败 */ int sgm51652hx_set_range(sgm51652hx_dev_t *dev, uint8_t channel, sgm51652hxRngVlu_e range) { if (!dev || !dev->initialized || channel > 7) { return ERR_INVALIDPARAMETER; } /* 计算量程寄存器地址 */ uint8_t reg = 0x05 + channel; /* RANGE_CH0 = 0x05 */ /* 写入量程配置 */ return sgm51652hx_write_reg(dev, reg, (uint8_t)range); } /*! \brief 从SGM51652HX芯片读取通道数据 \param[in] dev: 芯片设备结构体指针 \param[in] channel: 通道号 (0-7) \param[out] value: 读取的16位ADC值 \retval 0: 成功, -1: 失败 */ int sgm51652hx_read_channel(sgm51652hx_dev_t *dev, uint8_t channel, uint16_t *value) { if (!dev || !dev->initialized || !value || channel > 7) { return ERR_INVALIDPARAMETER; } /* 计算通道命令 */ uint16_t cmd = 0xC000 + (channel * 0x400); /* MAN_CH_0 = 0xC000 */ /* 选中芯片 */ spi_cs_control(&dev->spi_dev, 1); /* 开启发送 */ spi_master_transfer_start(dev->spi_dev.spi, SPI_TRANS_START); /* 发送命令 */ spi_transmit_receive_byte(dev->spi_dev.spi, (cmd >> 8) & 0xFF); //cmd高 spi_transmit_receive_byte(dev->spi_dev.spi, cmd & 0xFF); // spi_transmit_receive_byte(dev->spi_dev.spi, 0x00); //MSB格式,接收高8位 spi_transmit_receive_byte(dev->spi_dev.spi, 0x00); //接收低8位 /* 取消片选 */ spi_cs_control(&dev->spi_dev, 0); // /* ADC芯片需要转换时间,添加延时确保数据就绪 */ vTaskDelay(pdMS_TO_TICKS(1)); // 延时1毫秒 /* 再次选中芯片,读取数据 */ spi_cs_control(&dev->spi_dev, 1); /* 发送四个空字节,同时读取数据 */ uint8_t rxbuf[4] = {0}; rxbuf[0] = spi_transmit_receive_byte(dev->spi_dev.spi, 0x00); rxbuf[1] = spi_transmit_receive_byte(dev->spi_dev.spi, 0x00); rxbuf[2] = spi_transmit_receive_byte(dev->spi_dev.spi, 0x00); rxbuf[3] = spi_transmit_receive_byte(dev->spi_dev.spi, 0x00); /* 取消片选 */ spi_cs_control(&dev->spi_dev, 0); /* 合并16位数据 */ *value = (rxbuf[2] << 8) | rxbuf[3]; //printf("spix recv:%d %d %d %d\n", rxbuf[0], rxbuf[1], rxbuf[2], rxbuf[3]); return ERR_OK_SGM; } /*! \brief 根据原始ADC值和量程配置计算电压 芯片引脚真实电压 \param[in] adc_val: 原始ADC值 \param[in] range: 量程配置值 \param[out] none \retval 计算后的电压值 (V) */ float sgm51652hx_calc_voltage(uint16_t adc_val, sgm51652hxRngVlu_e range) { float voltage = 0.0f; switch(range) { // ==================== 双极性 Bipolar ==================== case RGVL_BP_1024: // ±10.24V voltage = (int16_t)adc_val * 10.24f / 32768.0f; break; case RGVL_BP_512: // ±5.12V voltage = (int16_t)adc_val * 5.12f / 32768.0f; break; case RGVL_BP_256: // ±2.56V voltage = (int16_t)adc_val * 2.56f / 32768.0f; break; // ==================== 单极性 Unipolar ==================== case RGVL_UP_1024: // 0~10.24V voltage = (float)adc_val * 10.24f / 65535.0f; break; case RGVL_UP_512: // 0~5.12V voltage = (float)adc_val * 5.12f / 65535.0f; break; default: // 错误配置 voltage = 0.0f; break; } return voltage; }