9ceb218f80
Co-authored-by: Cursor <cursoragent@cursor.com>
231 lines
6.8 KiB
C
231 lines
6.8 KiB
C
#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;
|
|
}
|