controller-pcba/User/driver/dac161s997.c

254 lines
8.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "dac161s997.h"
#include "stm32f4xx_hal.h" // 添加HAL库头文件
#include "spi.h" // 添加SPI头文件
#define _DAC_CHIP_RESET_CODE 0xC33C
#define _ERR_CONFIG_SPI_TIMOUT_400MS (7 << 1)
// 定义调试变量
volatile uint8_t dac161s997_init_status = 0xFF; // 初始化状态 (0=成功, 0xFF=未初始化)
volatile uint8_t dac161s997_error_count = 0; // 错误计数
volatile uint8_t dac161s997_test_step = 0; // 当前测试步骤
volatile uint8_t dac161s997_operation_status = 0; // 操作状态 (0=正常, 1=错误)
volatile uint16_t dac161s997_config_reg = 0; // 配置寄存器值
volatile uint16_t dac161s997_status_reg = 0; // 状态寄存器值
volatile uint16_t dac161s997_data_reg = 0; // 数据寄存器值
volatile float dac161s997_current_value = 0.0f; // 当前输出电流值
volatile uint8_t dac161s997_direction = 0; // 电流变化方向 (0=递减, 1=递增)
volatile float dac161s997_target_current = 0.0f; // 目标电流值
volatile uint16_t dac161s997_dac_code = 0; // DAC代码值
volatile uint8_t dac161s997_cmd_status = 0; // 命令执行状态
volatile uint8_t dac161s997_spi_phase = 0; // SPI通信阶段
volatile uint8_t dac161s997_last_error = 0; // 最后一次错误代码
volatile uint8_t dac161s997_retry_count = 0; // 重试计数
volatile uint8_t dac161s997_verify_status = 0; // 验证状态
// 添加SPI通信调试变量定义
volatile uint8_t dac161s997_spi_state = SPI_STATE_IDLE;
volatile uint8_t dac161s997_spi_error = SPI_ERR_NONE;
volatile uint32_t dac161s997_spi_timeout = 0;
volatile uint8_t dac161s997_spi_buffer[4] = {0};
volatile uint8_t dac161s997_spi_bytes = 0;
volatile uint8_t dac161s997_cs_state = 0;
volatile uint32_t dac161s997_last_spi_time = 0;
volatile uint32_t dac161s997_spi_retry_count = 0;
// 添加SPI通信辅助函数
static int32_t dac161s997_spi_transaction(uint8_t *data, uint8_t bytes, uint32_t timeout)
{
uint8_t rx_data[4] = {0}; // Add receive buffer
// 拉低CS
HAL_GPIO_WritePin(DAC1_CS_GPIO_Port, DAC1_CS_Pin, GPIO_PIN_RESET);
osDelay(5);
// SPI传输
int32_t status = spi_transmit_receive(&hspi1, data, rx_data, bytes);
// 拉高CS
HAL_GPIO_WritePin(DAC1_CS_GPIO_Port, DAC1_CS_Pin, GPIO_PIN_SET);
osDelay(5);
return status;
}
/**
* @brief 向DAC161S997芯片写入寄存器值
*
* @param dac_type DAC芯片类型
* @param reg 要写入的寄存器地址
* @param data 要写入的数据16位
*/
void dac161s997_write_reg(dac_type_t dac_type, uint8_t reg, uint16_t data)
{
uint8_t data_buffer[3] = {0, 0, 0};
data_buffer[0] = reg;
data_buffer[1] = data >> 8;
data_buffer[2] = data;
// 使用新的SPI事务函数
if(dac161s997_spi_transaction(data_buffer, 3, 1000) != SUCCESS) {
dac161s997_error_count++;
dac161s997_last_error = dac161s997_spi_error;
}
// 添加短暂延时确保数据稳定
HAL_Delay(1);
}
/**
* @brief 从DAC161S997芯片读取寄存器值
*
* @param dac_type DAC芯片类型
* @param reg 要读取的寄存器地址
* @param data 存储读取的数据的指针
* @return int32_t 0表示成功非0表示失败
*/
int32_t dac161s997_read_reg(dac_type_t dac_type, uint8_t reg, uint16_t *data)
{
uint8_t data_buffer[3] = {0, 0, 0};
data_buffer[0] = reg | 0x80; // 设置读位
dac161s997_spi_state = SPI_STATE_READ_START;
// 使用新的SPI事务函数
if(dac161s997_spi_transaction(data_buffer, 3, 1000) != SUCCESS) {
dac161s997_error_count++;
dac161s997_last_error = dac161s997_spi_error;
dac161s997_spi_state = SPI_STATE_ERROR;
return FAILURE;
}
*data = (data_buffer[1] << 8) | data_buffer[2];
dac161s997_spi_state = SPI_STATE_READ_END;
// 添加短暂延时确保数据稳定
HAL_Delay(1);
return SUCCESS;
}
/**
* @brief 初始化DAC161S997 DAC设备
*/
int dac161s997_init(dac_type_t dac_type, float current)
{
dac161s997_write_reg(dac_type, DAC161S997_RESET_REG, _DAC_CHIP_RESET_CODE);
//王绪洁版本初始化代码
dac161s997_write_reg(dac_type, DAC161S997_ERR_LOW_REG, 0xFFFF);
dac161s997_write_reg(dac_type, DAC161S997_ERR_CONFIG_REG, 0x070E);
// uint16_t reg_value = 0;
// dac161s997_write_reg(dac_type, DAC161S997_RESET_REG, _DAC_CHIP_RESET_CODE);
// // 1. 写保护寄存器(解锁)
// dac161s997_write_reg(dac_type, DAC161S997_PROTECT_REG_WR_REG, 0x00);
// HAL_Delay(2);
// // 2. 设置输出范围为4-20mAXFR寄存器
// dac161s997_write_reg(dac_type, DAC161S997_XFR_REG, 0x0A);
// HAL_Delay(2);
// // 验证XFR寄存器
// if(dac161s997_read_reg(dac_type, DAC161S997_XFR_REG, &reg_value) == SUCCESS) {
// if(reg_value != 0x0A) {
// // XFR寄存器写入失败
// dac161s997_error_count++;
// return -1; // 初始化失败
// }
// }
// // 3. 使能输出NOP寄存器
// dac161s997_write_reg(dac_type, DAC161S997_NOP_REG, 0x01);
// HAL_Delay(2);
// // 验证NOP寄存器
// if(dac161s997_read_reg(dac_type, DAC161S997_NOP_REG, &reg_value) == SUCCESS) {
// if(reg_value != 0x01) {
// // NOP寄存器写入失败
// dac161s997_error_count++;
// return -2; // 初始化失败
// }
// }
// // 4. 写错误配置寄存器
// dac161s997_write_reg(dac_type, DAC161S997_ERR_CONFIG_REG, 0x070E);
// HAL_Delay(2);
// // 验证ERR_CONFIG寄存器
// if(dac161s997_read_reg(dac_type, DAC161S997_ERR_CONFIG_REG, &reg_value) == SUCCESS) {
// if(reg_value != 0x070E) {
// // ERR_CONFIG寄存器写入失败
// dac161s997_error_count++;
// return -3; // 初始化失败
// }
// }
// // 5. 写低报警寄存器
// dac161s997_write_reg(dac_type, DAC161S997_ERR_LOW_REG, 0xFFFF);
// HAL_Delay(2);
// // 6. 写高报警寄存器(可选)
// dac161s997_write_reg(dac_type, DAC161S997_ERR_HIGH_REG, 0x0000);
// HAL_Delay(2);
// // 初始化成功
// dac161s997_init_status = 0; // 标记初始化成功
// return 0;
}
/**
* @brief DAC161S997芯片输出函数
*
* @param dac_type DAC芯片类型
* @param current 需要设置的电流值,单位:毫安
*/
void dac161s997_output(dac_type_t dac_type, float current)
{
// // 限制电流范围在4-20mA之间
// if (current < 4.0f) current = 4.0f;
// if (current > 20.0f) current = 20.0f;
// uint32_t dac_code = (uint32_t)(((current - 4.0f) * 65535.0f) / 16.0f);
// uint8_t data_buffer[3] = {DAC161S997_DACCODE_REG, dac_code >> 8, dac_code};
// HAL_GPIO_WritePin(DAC1_CS_GPIO_Port, DAC1_CS_Pin, GPIO_PIN_RESET);
// spi_transmit_receive(&hspi1, data_buffer, 3);
// HAL_GPIO_WritePin(DAC1_CS_GPIO_Port, DAC1_CS_Pin, GPIO_PIN_SET);
//uint32_t dac_code = (uint32_t)((current * 65535.0f) / 24.0f);
uint32_t dac_code = (uint32_t)(5461.0f);
uint8_t data_buffer[3] = {0, 0, 0};
data_buffer[0] = DAC161S997_DACCODE_REG;
data_buffer[1] = dac_code >> 8;
data_buffer[2] = dac_code;
dac161s997_init(dac_type, current);
HAL_GPIO_WritePin(DAC1_CS_GPIO_Port, DAC1_CS_Pin, GPIO_PIN_RESET);
spi_transmit_receive(&hspi1, data_buffer, data_buffer, 3);
HAL_GPIO_WritePin(DAC1_CS_GPIO_Port, DAC1_CS_Pin, GPIO_PIN_SET);
}
/**
* @brief DAC161S997诊断函数
*
* 读取并存储所有关键寄存器的值,用于调试
*
* @param dac_type DAC芯片类型
* @return int 0表示成功非0表示失败
*/
int dac161s997_diagnose(dac_type_t dac_type)
{
uint16_t reg_value = 0;
// 读取XFR寄存器输出范围
if(dac161s997_read_reg(dac_type, DAC161S997_XFR_REG, &reg_value) == SUCCESS) {
dac161s997_config_reg = reg_value; // 存储到调试变量
}
// 读取NOP寄存器输出使能
if(dac161s997_read_reg(dac_type, DAC161S997_NOP_REG, &reg_value) == SUCCESS) {
dac161s997_status_reg = reg_value; // 存储到调试变量
}
// 读取ERR_CONFIG寄存器
if(dac161s997_read_reg(dac_type, DAC161S997_ERR_CONFIG_REG, &reg_value) == SUCCESS) {
// 可以存储到其他调试变量
}
// 读取DACCODE寄存器当前DAC值
if(dac161s997_read_reg(dac_type, DAC161S997_DACCODE_REG, &reg_value) == SUCCESS) {
dac161s997_data_reg = reg_value; // 存储到调试变量
}
// 读取STATUS寄存器设备状态
if(dac161s997_read_reg(dac_type, 0x00, &reg_value) == SUCCESS) {
// STATUS寄存器地址通常是0x00
}
return 0;
}
// #ifndef DAC161S997_RANGE_REG
// #define DAC161S997_RANGE_REG 0x01
// #endif
// #ifndef DAC161S997_OUTPUT_ENABLE_REG
// #define DAC161S997_OUTPUT_ENABLE_REG 0x02
// #endif