542 lines
20 KiB
C
542 lines
20 KiB
C
#include "ad7124.h"
|
||
#include "user_spi.h"
|
||
#include "usart.h"
|
||
#include <stdint.h>
|
||
#include <stdbool.h>
|
||
#include <string.h>
|
||
/* Error codes */
|
||
#define INVALID_VAL -1 /* Invalid argument */
|
||
#define COMM_ERR -2 /* Communication error on receive */
|
||
#define AD7124_TIMEOUT -3 /* A timeout has occured */
|
||
int32_t FINESH_ID;
|
||
int32_t g_ad7124_id;
|
||
// 配置ad7124寄存器的值,根据实际项目需求配置
|
||
ad7124_st_reg_t ad7124_regs[AD7124_REG_NO] = {
|
||
{AD7124_STATUS, 0x00, AD7124_SIZE_1, AD7124_R}, /* AD7124_Status */
|
||
{AD7124_ADC_CONTROL, 0x0280, AD7124_SIZE_2, AD7124_RW}, /* AD7124_ADC_Control */
|
||
{AD7124_DATA, 0x000000, AD7124_SIZE_3, AD7124_R}, /* AD7124_Data */
|
||
{AD7124_IOCON1, 0x000000, AD7124_SIZE_3, AD7124_RW}, /* AD7124_IOCon1 */
|
||
{AD7124_IOCON2, 0x0000, AD7124_SIZE_2, AD7124_RW}, /* AD7124_IOCon2 */
|
||
{AD7124_ID, 0x02, AD7124_SIZE_1, AD7124_R}, /* AD7124_ID */
|
||
{AD7124_ERROR, 0x000000, AD7124_SIZE_3, AD7124_R}, /* AD7124_Error */
|
||
{AD7124_ERROR_EN, 0x000040, AD7124_SIZE_3, AD7124_RW}, /* AD7124_Error_En */
|
||
{AD7124_MCLK_COUNT, 0x00, AD7124_SIZE_1, AD7124_R}, /* AD7124_Mclk_Count */
|
||
{AD7124_CHANNEL_0, 0x0051, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Channel_0 */
|
||
{AD7124_CHANNEL_1, 0x0071, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Channel_1 */
|
||
{AD7124_CHANNEL_2, 0x0091, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Channel_2 */
|
||
{AD7124_CHANNEL_3, 0x00B1, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Channel_3 */
|
||
{AD7124_CHANNEL_4, 0x00D1, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Channel_4 */
|
||
{AD7124_CHANNEL_5, 0x00F1, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Channel_5 */
|
||
{AD7124_CHANNEL_6, 0x0111, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Channel_6 */
|
||
{AD7124_CHANNEL_7, 0x0131, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Channel_7 */
|
||
{AD7124_CHANNEL_8, 0x0151, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Channel_8 */
|
||
{AD7124_CHANNEL_9, 0x0171, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Channel_9 */
|
||
{AD7124_CHANNEL_10, 0x0001, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Channel_10 */
|
||
{AD7124_CHANNEL_11, 0x0001, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Channel_11 */
|
||
{AD7124_CHANNEL_12, 0x0001, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Channel_12 */
|
||
{AD7124_CHANNEL_13, 0x0001, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Channel_13 */
|
||
{AD7124_CHANNEL_14, 0x0001, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Channel_14 */
|
||
{AD7124_CHANNEL_15, 0x0001, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Channel_15 */
|
||
{AD7124_CONFIG_0, 0x01E0, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Config_0 */
|
||
{AD7124_CONFIG_1, 0x0040, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Config_1 */
|
||
{AD7124_CONFIG_2, 0x0860, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Config_2 */
|
||
{AD7124_CONFIG_3, 0x0860, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Config_3 */
|
||
{AD7124_CONFIG_4, 0x0860, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Config_4 */
|
||
{AD7124_CONFIG_5, 0x0860, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Config_5 */
|
||
{AD7124_CONFIG_6, 0x0860, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Config_6 */
|
||
{AD7124_CONFIG_7, 0x0860, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Config_7 */
|
||
{AD7124_FILTER_0, 0x060020, AD7124_SIZE_3, AD7124_RW}, /* AD7124_Filter_0 */
|
||
{AD7124_FILTER_1, 0x060180, AD7124_SIZE_3, AD7124_RW}, /* AD7124_Filter_1 */
|
||
{AD7124_FILTER_2, 0x060180, AD7124_SIZE_3, AD7124_RW}, /* AD7124_Filter_2 */
|
||
{AD7124_FILTER_3, 0x060180, AD7124_SIZE_3, AD7124_RW}, /* AD7124_Filter_3 */
|
||
{AD7124_FILTER_4, 0x060180, AD7124_SIZE_3, AD7124_RW}, /* AD7124_Filter_4 */
|
||
{AD7124_FILTER_5, 0x060180, AD7124_SIZE_3, AD7124_RW}, /* AD7124_Filter_5 */
|
||
{AD7124_FILTER_6, 0x060180, AD7124_SIZE_3, AD7124_RW}, /* AD7124_Filter_6 */
|
||
{AD7124_FILTER_7, 0x060180, AD7124_SIZE_3, AD7124_RW}, /* AD7124_Filter_7 */
|
||
{AD7124_OFFSET_0, 0x800000, AD7124_SIZE_3, AD7124_RW}, /* AD7124_Offset_0 */
|
||
{AD7124_OFFSET_1, 0x800000, AD7124_SIZE_3, AD7124_RW}, /* AD7124_Offset_1 */
|
||
{AD7124_OFFSET_2, 0x800000, AD7124_SIZE_3, AD7124_RW}, /* AD7124_Offset_2 */
|
||
{AD7124_OFFSET_3, 0x800000, AD7124_SIZE_3, AD7124_RW}, /* AD7124_Offset_3 */
|
||
{AD7124_OFFSET_4, 0x800000, AD7124_SIZE_3, AD7124_RW}, /* AD7124_Offset_4 */
|
||
{AD7124_OFFSET_5, 0x800000, AD7124_SIZE_3, AD7124_RW}, /* AD7124_Offset_5 */
|
||
{AD7124_OFFSET_6, 0x800000, AD7124_SIZE_3, AD7124_RW}, /* AD7124_Offset_6 */
|
||
{AD7124_OFFSET_7, 0x800000, AD7124_SIZE_3, AD7124_RW}, /* AD7124_Offset_7 */
|
||
{AD7124_GAIN_0, 0x500000, AD7124_SIZE_3, AD7124_RW}, /* AD7124_Gain_0 */
|
||
{AD7124_GAIN_1, 0x500000, AD7124_SIZE_3, AD7124_RW}, /* AD7124_Gain_1 */
|
||
{AD7124_GAIN_2, 0x500000, AD7124_SIZE_3, AD7124_RW}, /* AD7124_Gain_2 */
|
||
{AD7124_GAIN_3, 0x500000, AD7124_SIZE_3, AD7124_RW}, /* AD7124_Gain_3 */
|
||
{AD7124_GAIN_4, 0x500000, AD7124_SIZE_3, AD7124_RW}, /* AD7124_Gain_4 */
|
||
{AD7124_GAIN_5, 0x500000, AD7124_SIZE_3, AD7124_RW}, /* AD7124_Gain_5 */
|
||
{AD7124_GAIN_6, 0x500000, AD7124_SIZE_3, AD7124_RW}, /* AD7124_Gain_6 */
|
||
{AD7124_GAIN_7, 0x500000, AD7124_SIZE_3, AD7124_RW}, /* AD7124_Gain_7 */
|
||
};
|
||
|
||
ad7124_st_reg_t ad7124_channel_regs[AD7124_CHANNEL_EN_MAX] = {
|
||
{AD7124_CHANNEL_0, 0x8051, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Channel_0 */
|
||
{AD7124_CHANNEL_1, 0x8071, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Channel_1 */
|
||
{AD7124_CHANNEL_2, 0x8091, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Channel_2 */
|
||
{AD7124_CHANNEL_3, 0x80B1, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Channel_3 */
|
||
{AD7124_CHANNEL_4, 0x80D1, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Channel_4 */
|
||
{AD7124_CHANNEL_5, 0x80F1, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Channel_5 */
|
||
{AD7124_CHANNEL_6, 0x8111, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Channel_6 */
|
||
{AD7124_CHANNEL_7, 0x8131, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Channel_7 */
|
||
{AD7124_CHANNEL_8, 0x8151, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Channel_8 */
|
||
{AD7124_CHANNEL_9, 0x8171, AD7124_SIZE_2, AD7124_RW}, /* AD7124_Channel_9 */
|
||
};
|
||
|
||
ad7124_analog_t ad7124_analog[AD7124_CHANNEL_EN_MAX] = {NULL}; // AD通道采样结构体数组,用于存放AD通道采样数据
|
||
/**
|
||
* @brief 无校验读取AD7124寄存器
|
||
*
|
||
* 读取AD7124的寄存器值,不进行校验。
|
||
*
|
||
* @param p_reg 指向要读取的寄存器结构的指针
|
||
*
|
||
* @return 读取成功返回0,失败返回负值
|
||
*/
|
||
int32_t ad7124_no_check_read_register(ad7124_st_reg_t *p_reg)
|
||
{
|
||
int32_t ret = 0;
|
||
uint8_t buffer[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||
uint8_t add_status_length = 0;
|
||
|
||
// 构建命令字
|
||
buffer[0] = AD7124_COMM_REG_RD | AD7124_COMM_REG_RA(p_reg->addr);
|
||
|
||
// 打印调试信息
|
||
// char uart_buf[100];
|
||
// sprintf(uart_buf, "Reading register 0x%02X, command: 0x%02X\r\n", p_reg->addr, buffer[0]);
|
||
// HAL_UART_Transmit(&huart1, (uint8_t*)uart_buf, strlen(uart_buf), 100);
|
||
|
||
if ((p_reg->addr == AD7124_DATA) &&
|
||
(ad7124_regs[AD7124_ADC_CONTROL].value & AD7124_ADC_CTRL_REG_DATA_STATUS))
|
||
{
|
||
add_status_length = 1;
|
||
}
|
||
|
||
// 从设备读取数据
|
||
ret = ad7124_read_write_spi(buffer, p_reg->size + 1 + add_status_length);
|
||
if (ret < 0)
|
||
return ret;
|
||
|
||
// 解析数据(buffer[1]开始为有效数据)
|
||
if (p_reg->size == 1) {
|
||
p_reg->value = buffer[1];
|
||
} else if (p_reg->size == 2) {
|
||
p_reg->value = ((uint16_t)buffer[1] << 8) | buffer[2];
|
||
} else if (p_reg->size == 3) {
|
||
p_reg->value = ((uint32_t)buffer[1] << 16) | ((uint32_t)buffer[2] << 8) | buffer[3];
|
||
} else {
|
||
p_reg->value = 0;
|
||
}
|
||
|
||
if (add_status_length)
|
||
{
|
||
ad7124_regs[AD7124_STATUS].value = buffer[p_reg->size + 1];
|
||
}
|
||
|
||
// 仅用于调试:如果是ID寄存器,赋值到全局变量
|
||
if (p_reg->addr == AD7124_ID) {
|
||
g_ad7124_id = p_reg->value;
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
/**
|
||
* @brief 向AD7124寄存器写入数据,不进行校验
|
||
*
|
||
* 将数据写入指定的AD7124寄存器,不进行数据校验。
|
||
*
|
||
* @param reg 指向要写入数据的寄存器地址和值的指针
|
||
* @return 写入结果,成功返回0,失败返回负值
|
||
*/
|
||
int32_t ad7124_no_check_write_register(ad7124_st_reg_t *reg)
|
||
{
|
||
int32_t ret = 0;
|
||
int32_t reg_value = 0;
|
||
uint8_t wr_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||
uint8_t i = 0;
|
||
|
||
/* Build the Command word */
|
||
wr_buf[0] = AD7124_COMM_REG_WEN | AD7124_COMM_REG_WR |
|
||
AD7124_COMM_REG_RA(reg->addr);
|
||
|
||
/* Fill the write buffer */
|
||
reg_value = reg->value;
|
||
for (i = 0; i < reg->size; i++)
|
||
{
|
||
wr_buf[reg->size - i] = reg_value & 0xFF;
|
||
reg_value >>= 8;
|
||
}
|
||
|
||
/* Write data to the device */
|
||
ret = ad7124_read_write_spi(wr_buf, reg->size + 1);
|
||
FINESH_ID = ret;
|
||
return ret;
|
||
}
|
||
|
||
/**
|
||
* @brief 从AD7124寄存器读取数据
|
||
*
|
||
* 该函数用于从AD7124的指定寄存器中读取数据。
|
||
*
|
||
* @param p_reg 指向一个ad7124_st_reg_t类型的指针,其中包含了要读取的寄存器的地址。
|
||
*
|
||
* @return 返回读取到的数据,如果读取失败则返回负数。
|
||
*
|
||
* 在读取寄存器之前,会先检查ERROR寄存器的SPI_IGNORE_ERR位
|
||
*/
|
||
int32_t ad7124_read_register(ad7124_st_reg_t *p_reg)
|
||
{
|
||
int32_t ret;
|
||
|
||
// 检查寄存器地址是否不是错误地址,并且检查ERROR寄存器的SPI_IGNORE_ERR位是否被设置
|
||
if (p_reg->addr != AD7124_ERROR && (ad7124_regs[AD7124_ERROR_EN].value & AD7124_ERREN_REG_SPI_IGNORE_ERR_EN))
|
||
{
|
||
// 读寄存器之前检查ERROR寄存器的SPI_IGNORE_ERR位
|
||
ret = ad7124_wait_for_spi_ready(AD7124_RDY);
|
||
|
||
// 如果等待SPI就绪失败,则返回错误码
|
||
if (ret < 0)
|
||
return ret;
|
||
}
|
||
// 不检查ERROR寄存器的SPI_IGNORE_ERR位,直接读取寄存器
|
||
ret = ad7124_no_check_read_register(p_reg);
|
||
|
||
return ret;
|
||
}
|
||
|
||
/**
|
||
* @brief 向AD7124寄存器写入数据
|
||
*
|
||
* 将数据写入AD7124的指定寄存器。如果错误寄存器中启用了忽略SPI错误的功能,则在写入前会等待SPI接口准备就绪。
|
||
*
|
||
* @param p_reg 指向要写入数据的寄存器结构体的指针
|
||
*
|
||
* @return 返回写入操作的结果。如果操作成功,则返回0;否则返回负数表示错误。
|
||
*/
|
||
int32_t ad7124_write_register(ad7124_st_reg_t *p_reg)
|
||
{
|
||
int32_t ret;
|
||
|
||
if ((ad7124_regs[AD7124_ERROR_EN].value & AD7124_ERREN_REG_SPI_IGNORE_ERR_EN))
|
||
{
|
||
ret = ad7124_wait_for_spi_ready(AD7124_RDY);
|
||
if (ret < 0)
|
||
return ret;
|
||
}
|
||
ret = ad7124_no_check_write_register(p_reg);
|
||
|
||
return ret;
|
||
}
|
||
|
||
/**
|
||
* @brief 重置AD7124设备
|
||
*
|
||
* 该函数通过SPI接口向AD7124发送重置命令,并等待设备完成上电过程。
|
||
*
|
||
* @return 返回函数执行结果,成功返回0,失败返回错误码。
|
||
*/
|
||
int32_t ad7124_reset(void)
|
||
{
|
||
int32_t ret = 0;
|
||
uint8_t wr_buf[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // 发送64个1,复位ad7124芯片
|
||
|
||
ret = ad7124_read_write_spi(wr_buf, 8);
|
||
|
||
/* Read POR bit to clear */
|
||
ret = ad7124_wait_to_power_on(AD7124_RDY);
|
||
|
||
return ret;
|
||
}
|
||
|
||
/**
|
||
* @brief 等待SPI接口准备就绪
|
||
*
|
||
* 等待AD7124的SPI接口准备就绪,直到超时。
|
||
*
|
||
* @param timeout 超时时间(单位:毫秒)
|
||
* @return 成功返回0,超时返回AD7124_TIMEOUT
|
||
*/
|
||
int32_t ad7124_wait_for_spi_ready(uint32_t timeout)
|
||
{
|
||
int32_t ret;
|
||
int8_t ready = 0;
|
||
|
||
while (!ready && --timeout)
|
||
{
|
||
/* Read the value of the Error Register */
|
||
ret = ad7124_read_register(&ad7124_regs[AD7124_ERROR]);
|
||
if (ret < 0)
|
||
return ret;
|
||
|
||
/* Check the SPI IGNORE Error bit in the Error Register */
|
||
ready = (ad7124_regs[AD7124_ERROR].value &
|
||
AD7124_ERR_REG_SPI_IGNORE_ERR) == 0;
|
||
}
|
||
|
||
return timeout ? 0 : AD7124_TIMEOUT;
|
||
}
|
||
|
||
/**
|
||
* @brief 等待AD7124电源开启
|
||
*
|
||
* 此函数将等待AD7124设备电源开启,直到超时或检测到电源开启标志。
|
||
*
|
||
* @param timeout 超时时间
|
||
*
|
||
* @return 返回0表示成功,返回AD7124_TIMEOUT表示超时
|
||
*/
|
||
int32_t ad7124_wait_to_power_on(uint32_t timeout)
|
||
{
|
||
int32_t ret;
|
||
int8_t powered_on = 0;
|
||
|
||
while (!powered_on && timeout--)
|
||
{
|
||
ret = ad7124_read_register(&ad7124_regs[AD7124_STATUS]);
|
||
if (ret < 0)
|
||
return ret;
|
||
|
||
/* Check the POR_FLAG bit in the Status Register */
|
||
powered_on = (ad7124_regs[AD7124_STATUS].value &
|
||
AD7124_STATUS_REG_POR_FLAG) == 0;
|
||
}
|
||
|
||
return (timeout || powered_on) ? 0 : AD7124_TIMEOUT;
|
||
}
|
||
|
||
/**
|
||
* @brief 等待AD7124转换准备就绪
|
||
*
|
||
* 该函数等待AD7124完成转换并准备就绪。如果等待超时,则返回错误码。
|
||
*
|
||
* @param timeout 超时时间
|
||
* @return 成功时返回0,超时时返回AD7124_TIMEOUT
|
||
*/
|
||
int32_t ad7124_wait_for_conv_ready(uint32_t timeout)
|
||
{
|
||
int32_t ret;
|
||
int8_t ready = 0;
|
||
|
||
while (!ready && --timeout)
|
||
{
|
||
/* Read the value of the Status Register */
|
||
ret = ad7124_read_register(&ad7124_regs[AD7124_STATUS]);
|
||
if (ret < 0)
|
||
return ret;
|
||
|
||
/* Check the RDY bit in the Status Register */
|
||
ready = (ad7124_regs[AD7124_STATUS].value &
|
||
AD7124_STATUS_REG_RDY) == 0;
|
||
}
|
||
|
||
return timeout ? 0 : AD7124_TIMEOUT;
|
||
}
|
||
|
||
/**
|
||
* @brief 从AD7124读取数据
|
||
*
|
||
* 从AD7124的数据寄存器中读取数据值。
|
||
*
|
||
* @return 读取到的数据值
|
||
*/
|
||
int32_t ad7124_read_data(void)
|
||
{
|
||
int32_t read_data;
|
||
/* Read the value of the Status Register */
|
||
ad7124_read_register(&ad7124_regs[AD7124_DATA]);//读取数据寄存器
|
||
/* Get the read result */
|
||
read_data = ad7124_regs[AD7124_DATA].value;
|
||
|
||
return read_data;
|
||
}
|
||
/**
|
||
* @brief 从AD7124获取模拟信号数据
|
||
*
|
||
* 该函数通过SPI接口从AD7124芯片获取模拟信号数据,并将数据保存到ad7124_analog中。
|
||
*
|
||
* @details
|
||
* - 遍历所有模拟通道,对每个通道执行以下操作:
|
||
* - 等待AD7124完成转换。
|
||
* - 读取转换后的数据。
|
||
* - 计算电压值(单极性计算公式)。
|
||
* - 计算电流值(基于电压值和电阻值),有的通道没有电流值可以忽略。
|
||
*
|
||
* @note
|
||
* - 转换完成后,通过公式计算电压和电流值,并将结果保存到全局数组ad7124_analog中。
|
||
* - 电压计算公式:Code = (0xFFFFFF × AIN × Gain)/VREF,其中VREF为参考电压,GAIN为增益,AD_CODE为AD代码。
|
||
* - 电流计算公式:电流 = 电压 / 电阻 * 1000,其中电阻值为AD7124_RES,单位转换为mA。
|
||
*/
|
||
// void ad7124_get_analog(void)
|
||
// {
|
||
// int32_t read_data;
|
||
// uint8_t i;
|
||
// uint8_t channel;
|
||
// // for (i = STOP_NC_ADC; i < AD7124_CHANNEL_EN_MAX; i++)
|
||
// // {
|
||
// // ad7124_regs[AD7124_CHANNEL_0].value = ad7124_channel_regs[i].value;
|
||
// // ad7124_write_register(&ad7124_regs[AD7124_CHANNEL_0]);
|
||
|
||
// // ad7124_read_register(&ad7124_regs[AD7124_STATUS]);
|
||
// while (ad7124_wait_for_conv_ready(AD7124_RDY))
|
||
// ; // 等待转换完成
|
||
// channel = ad7124_regs[AD7124_STATUS].value;
|
||
// ad7124_analog[channel].channel = channel;
|
||
// read_data = ad7124_read_data();
|
||
// ad7124_analog[channel].data = read_data;
|
||
// ad7124_analog[channel].voltage = (float)(read_data * VREF / GAIN / AD_CODE); // AD7124单极性计算公式:Code = (0xFFFFFF × AIN × Gain)/VREF
|
||
// ad7124_analog[channel].current = (float)(ad7124_analog[channel].voltage / AD7124_RES * 1000); // 乘1000是为了将单位转换为mA
|
||
|
||
// // ad7124_regs[AD7124_CHANNEL_0].value = 0;
|
||
// // ad7124_write_register(&ad7124_regs[AD7124_CHANNEL_0]);
|
||
// // }
|
||
// }
|
||
void ad7124_get_analog(uint8_t channel_nr)
|
||
{
|
||
int32_t read_data;
|
||
|
||
// 设置AD7124寄存器,选择指定通道
|
||
// for (i = STOP_NC_ADC; i < AD7124_CHANNEL_EN_MAX; i++)
|
||
// {
|
||
ad7124_regs[AD7124_CHANNEL_0].value = ad7124_channel_regs[channel_nr].value;
|
||
ad7124_write_register(&ad7124_regs[AD7124_CHANNEL_0]);
|
||
|
||
// 等待转换完成
|
||
while (ad7124_wait_for_conv_ready(AD7124_RDY))
|
||
; // 等待转换完成
|
||
|
||
// 存储读取的模拟数据
|
||
ad7124_analog[channel_nr].channel = channel_nr;
|
||
read_data = ad7124_read_data();
|
||
ad7124_analog[channel_nr].data = read_data;
|
||
|
||
// 计算电压值
|
||
// AD7124单极性计算公式:Code = (0xFFFFFF × AIN × Gain)/VREF
|
||
ad7124_analog[channel_nr].voltage = (float)(read_data * VREF / GAIN / AD_CODE);
|
||
|
||
// 计算电流值,乘1000是为了将单位转换为mA
|
||
ad7124_analog[channel_nr].current = (float)(ad7124_analog[channel_nr].voltage / AD7124_RES * 1000);
|
||
|
||
// 恢复通道0寄存器为默认值
|
||
ad7124_regs[AD7124_CHANNEL_0].value = 0;
|
||
ad7124_write_register(&ad7124_regs[AD7124_CHANNEL_0]);
|
||
// }
|
||
}
|
||
/**
|
||
* @brief 配置AD7124设备
|
||
*
|
||
* 该函数负责初始化AD7124设备,初始化寄存器。
|
||
*
|
||
* @return 初始化结果,成功返回0,失败返回负数
|
||
*/
|
||
int32_t ad7124_setup(void)
|
||
{
|
||
int32_t ret;
|
||
uint8_t reg_nr;
|
||
char uart_buf[100];
|
||
|
||
// 初始化SPI
|
||
board_spi_init(AD7124);
|
||
HAL_Delay(10); // 等待SPI稳定
|
||
|
||
// 复位设备
|
||
ret = ad7124_reset();
|
||
if (ret < 0) {
|
||
sprintf(uart_buf, "AD7124 reset failed: %ld\r\n", ret);
|
||
HAL_UART_Transmit(&huart1, (uint8_t*)uart_buf, strlen(uart_buf), 100);
|
||
return ret;
|
||
}
|
||
|
||
// 等待复位完成
|
||
HAL_Delay(100); // 增加复位后的等待时间
|
||
|
||
// 等待电源稳定
|
||
ret = ad7124_wait_to_power_on(AD7124_RDY);
|
||
if (ret < 0) {
|
||
sprintf(uart_buf, "AD7124 power on timeout: %ld\r\n", ret);
|
||
HAL_UART_Transmit(&huart1, (uint8_t*)uart_buf, strlen(uart_buf), 100);
|
||
return ret;
|
||
}
|
||
|
||
// 读取ID寄存器
|
||
ret = ad7124_read_register(&ad7124_regs[AD7124_ID]);
|
||
if (ret < 0) {
|
||
sprintf(uart_buf, "Failed to read ID register: %ld\r\n", ret);
|
||
HAL_UART_Transmit(&huart1, (uint8_t*)uart_buf, strlen(uart_buf), 100);
|
||
return ret;
|
||
}
|
||
|
||
// 检查ID值
|
||
// if (ad7124_regs[AD7124_ID].value != 0x14) {
|
||
// sprintf(uart_buf, "Invalid ID: 0x%02X, expected 0x14\r\n", ad7124_regs[AD7124_ID].value);
|
||
// HAL_UART_Transmit(&huart1, (uint8_t*)uart_buf, strlen(uart_buf), 100);
|
||
// return COMM_ERR;
|
||
// }
|
||
|
||
// sprintf(uart_buf, "AD7124 ID verified: 0x%02X\r\n", ad7124_regs[AD7124_ID].value);
|
||
// HAL_UART_Transmit(&huart1, (uint8_t*)uart_buf, strlen(uart_buf), 100);
|
||
|
||
// 初始化其他寄存器
|
||
for (reg_nr = AD7124_STATUS; reg_nr < AD7124_OFFSET_0; reg_nr++) {
|
||
if (ad7124_regs[reg_nr].rw == AD7124_RW) {
|
||
ret = ad7124_write_register(&ad7124_regs[reg_nr]);
|
||
if (ret < 0) {
|
||
sprintf(uart_buf, "Failed to write register 0x%02X: %ld\r\n", reg_nr, ret);
|
||
HAL_UART_Transmit(&huart1, (uint8_t*)uart_buf, strlen(uart_buf), 100);
|
||
return ret;
|
||
}
|
||
|
||
// 验证写入
|
||
ret = ad7124_read_register(&ad7124_regs[reg_nr]);
|
||
if (ret < 0) {
|
||
sprintf(uart_buf, "Failed to verify register 0x%02X: %ld\r\n", reg_nr, ret);
|
||
HAL_UART_Transmit(&huart1, (uint8_t*)uart_buf, strlen(uart_buf), 100);
|
||
return ret;
|
||
}
|
||
|
||
// 如果读取的值与写入的值不匹配,返回错误
|
||
if (ad7124_regs[reg_nr].value != ad7124_regs[reg_nr].value) {
|
||
sprintf(uart_buf, "Register 0x%02X mismatch: wrote 0x%04X, read 0x%04X\r\n",
|
||
reg_nr, ad7124_regs[reg_nr].value, ad7124_regs[reg_nr].value);
|
||
HAL_UART_Transmit(&huart1, (uint8_t*)uart_buf, strlen(uart_buf), 100);
|
||
return COMM_ERR;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 使能同步信号
|
||
HAL_GPIO_WritePin(AD7124_SYNC_GPIO_Port, AD7124_SYNC_Pin, GPIO_PIN_SET);
|
||
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* @brief 通过SPI接口对AD7124进行读写操作
|
||
*
|
||
* 通过SPI接口对AD7124进行读写操作,。
|
||
*
|
||
* @param buff 指向待传输数据的指针
|
||
* @param length 待传输数据的长度
|
||
*
|
||
* @return 传输结果,成功返回0,失败返回负数
|
||
*/
|
||
int32_t ad7124_read_write_spi(uint8_t *buff, uint8_t length)
|
||
{
|
||
int32_t ret;
|
||
|
||
// 确保CS信号在传输前是高的
|
||
board_spi_cs_off(AD7124);
|
||
HAL_Delay(1); // 添加短暂延时
|
||
//board_spi_init(AD7124);
|
||
board_spi_cs_on(AD7124);
|
||
HAL_Delay(1); // 添加短暂延时
|
||
|
||
ret = spi_transmit_receive(&hspi2, buff, length);
|
||
|
||
HAL_Delay(1); // 添加短暂延时
|
||
board_spi_cs_off(AD7124);
|
||
|
||
return ret;
|
||
}
|