254 lines
8.8 KiB
C
254 lines
8.8 KiB
C
#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-20mA(XFR寄存器)
|
||
// dac161s997_write_reg(dac_type, DAC161S997_XFR_REG, 0x0A);
|
||
// HAL_Delay(2);
|
||
|
||
// // 验证XFR寄存器
|
||
// if(dac161s997_read_reg(dac_type, DAC161S997_XFR_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, ®_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, ®_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, ®_value) == SUCCESS) {
|
||
dac161s997_config_reg = reg_value; // 存储到调试变量
|
||
}
|
||
|
||
// 读取NOP寄存器(输出使能)
|
||
if(dac161s997_read_reg(dac_type, DAC161S997_NOP_REG, ®_value) == SUCCESS) {
|
||
dac161s997_status_reg = reg_value; // 存储到调试变量
|
||
}
|
||
|
||
// 读取ERR_CONFIG寄存器
|
||
if(dac161s997_read_reg(dac_type, DAC161S997_ERR_CONFIG_REG, ®_value) == SUCCESS) {
|
||
// 可以存储到其他调试变量
|
||
}
|
||
|
||
// 读取DACCODE寄存器(当前DAC值)
|
||
if(dac161s997_read_reg(dac_type, DAC161S997_DACCODE_REG, ®_value) == SUCCESS) {
|
||
dac161s997_data_reg = reg_value; // 存储到调试变量
|
||
}
|
||
|
||
// 读取STATUS寄存器(设备状态)
|
||
if(dac161s997_read_reg(dac_type, 0x00, ®_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
|