STM32 DAC8734 4路16位DA驱动程序

一、DAC8734 芯片概述

DAC8734 是 TI 推出的 4通道、16位、电压输出 DAC ,采用 SPI 接口,特别适合 数字电源基准、偏置电压、校准系统。

参数 规格
分辨率 16位
通道数 4路(A/B/C/D)
接口 SPI(最高 50MHz)
输出电压 ±10V、±5V、0-10V、0-5V
参考电压 内部 2.5V / 外部
封装 TSSOP-38

二、硬件连接(STM32 ↔ DAC8734)

推荐连接方式

复制代码
STM32           DAC8734
────────────────────────
SPIx_SCK   ───► SCLK
SPIx_MOSI  ───► SDIN
SPIx_MISO  ◄─── SDOUT
GPIOx_PIN  ───► SYNC (CS)
GPIOx_PIN  ───► LDAC
GPIOx_PIN  ◄─── RDY
GPIOx_PIN  ───► RST

电压配置跳线

PIN 配置
RNG0 / RNG1 输出电压范围
REFSEL 参考电压选择

三、DAC8734 寄存器定义

寄存器地址

c 复制代码
/* DAC8734 寄存器地址 */
#define DAC_REG_A        0x00
#define DAC_REG_B        0x01
#define DAC_REG_C        0x02
#define DAC_REG_D        0x03
#define DAC_REG_ALL      0x04

#define DAC_GAIN_REG     0x08
#define DAC_OFFSET_REG   0x09
#define DAC_CONFIG_REG   0x0A
#define DAC_STATUS_REG   0x0B

命令帧格式(24位)

复制代码
23:20 - 命令位
19:16 - 地址位
15:0  - 数据位

四、STM32 SPI 底层驱动

1、SPI 初始化(CubeMX 配置)

c 复制代码
/* SPI 配置参数 */
/*
Mode: Full-Duplex Master
Hardware NSS: Disable
Data Size: 8 bits
Prescaler: 8~32 (≥10MHz)
CPOL: Low
CPHA: 1 Edge
First Bit: MSB
*/

2、SPI 读写函数

c 复制代码
#include "spi.h"

static uint8_t SPI_TransferByte(SPI_HandleTypeDef *hspi, uint8_t data)
{
    uint8_t rxdata;
    HAL_SPI_TransmitReceive(hspi, &data, &rxdata, 1, 100);
    return rxdata;
}

static void SPI_Write24Bits(SPI_HandleTypeDef *hspi, uint32_t data)
{
    SPI_TransferByte(hspi, (data >> 16) & 0xFF);
    SPI_TransferByte(hspi, (data >> 8)  & 0xFF);
    SPI_TransferByte(hspi, data & 0xFF);
}

五、DAC8734 驱动核心代码

dac8734.h

c 复制代码
#ifndef __DAC8734_H
#define __DAC8734_H

#include "stm32f4xx_hal.h"

/* 输出范围 */
typedef enum {
    DAC_RANGE_0_5V   = 0x00,
    DAC_RANGE_0_10V  = 0x01,
    DAC_RANGE_5V     = 0x02,
    DAC_RANGE_10V    = 0x03,
    DAC_RANGE_5V_NEG = 0x04,
    DAC_RANGE_10V_NEG= 0x05
} DAC_Range_t;

/* 通道定义 */
typedef enum {
    DAC_CH_A = 0,
    DAC_CH_B = 1,
    DAC_CH_C = 2,
    DAC_CH_D = 3,
    DAC_CH_ALL = 4
} DAC_Channel_t;

/* 设备句柄 */
typedef struct {
    SPI_HandleTypeDef *hspi;
    GPIO_TypeDef *cs_port;
    uint16_t cs_pin;
    GPIO_TypeDef *ldac_port;
    uint16_t ldac_pin;
    GPIO_TypeDef *rst_port;
    uint16_t rst_pin;
} DAC8734_Handle_t;

/* API */
HAL_StatusTypeDef DAC8734_Init(DAC8734_Handle_t *hdac);
HAL_StatusTypeDef DAC8734_SetVoltage(DAC8734_Handle_t *hdac,
                                     DAC_Channel_t ch,
                                     float voltage);
HAL_StatusTypeDef DAC8734_SetRange(DAC8734_Handle_t *hdac,
                                   DAC_Channel_t ch,
                                   DAC_Range_t range);
HAL_StatusTypeDef DAC8734_SoftwareUpdate(DAC8734_Handle_t *hdac);

#endif

dac8734.c

c 复制代码
#include "dac8734.h"
#include <math.h>

#define DAC8734_CS_LOW(h)   HAL_GPIO_WritePin((h)->cs_port, (h)->cs_pin, GPIO_PIN_RESET)
#define DAC8734_CS_HIGH(h)  HAL_GPIO_WritePin((h)->cs_port, (h)->cs_pin, GPIO_PIN_SET)
#define DAC8734_LDAC_LOW(h) HAL_GPIO_WritePin((h)->ldac_port,(h)->ldac_pin,GPIO_PIN_RESET)
#define DAC8734_LDAC_HIGH(h)HAL_GPIO_WritePin((h)->ldac_port,(h)->ldac_pin,GPIO_PIN_SET)

/* 内部写函数 */
static void DAC8734_WriteReg(DAC8734_Handle_t *hdac, uint8_t addr, uint16_t data)
{
    uint32_t frame = ((uint32_t)addr << 16) | data;

    DAC8734_CS_LOW(hdac);
    SPI_Write24Bits(hdac->hspi, frame);
    DAC8734_CS_HIGH(hdac);
}

/* 初始化 */
HAL_StatusTypeDef DAC8734_Init(DAC8734_Handle_t *hdac)
{
    /* 复位 */
    if (hdac->rst_port) {
        HAL_GPIO_WritePin(hdac->rst_port, hdac->rst_pin, GPIO_PIN_RESET);
        HAL_Delay(10);
        HAL_GPIO_WritePin(hdac->rst_port, hdac->rst_pin, GPIO_PIN_SET);
    }

    /* 配置默认输出范围 */
    for (int i = 0; i < 4; i++) {
        DAC8734_SetRange(hdac, i, DAC_RANGE_0_10V);
    }

    return HAL_OK;
}

/* 设置电压 */
HAL_StatusTypeDef DAC8734_SetVoltage(DAC8734_Handle_t *hdac,
                                      DAC_Channel_t ch,
                                      float voltage)
{
    uint16_t code;

    /* ±10V 范围示例 */
    if (voltage > 10.0f) voltage = 10.0f;
    if (voltage < 0.0f)  voltage = 0.0f;

    code = (uint16_t)((voltage / 10.0f) * 65535.0f);

    DAC8734_WriteReg(hdac, ch, code);

    /* 软件触发更新 */
    DAC8734_SoftwareUpdate(hdac);

    return HAL_OK;
}

/* 设置输出范围 */
HAL_StatusTypeDef DAC8734_SetRange(DAC8734_Handle_t *hdac,
                                   DAC_Channel_t ch,
                                   DAC_Range_t range)
{
    uint16_t gain_code = 0;

    switch (range) {
        case DAC_RANGE_0_5V:   gain_code = 0x0000; break;
        case DAC_RANGE_0_10V:  gain_code = 0x0001; break;
        case DAC_RANGE_5V:     gain_code = 0x0002; break;
        case DAC_RANGE_10V:    gain_code = 0x0003; break;
        default: return HAL_ERROR;
    }

    DAC8734_WriteReg(hdac, DAC_GAIN_REG + ch, gain_code);
    return HAL_OK;
}

/* 软件 LDAC 更新 */
HAL_StatusTypeDef DAC8734_SoftwareUpdate(DAC8734_Handle_t *hdac)
{
    DAC8734_LDAC_LOW(hdac);
    __NOP(); __NOP(); __NOP();
    DAC8734_LDAC_HIGH(hdac);
    return HAL_OK;
}

六、使用示例(数字电源场景)

c 复制代码
DAC8734_Handle_t dac8734 = {
    .hspi = &hspi1,
    .cs_port = GPIOA,
    .cs_pin = GPIO_PIN_4,
    .ldac_port = GPIOA,
    .ldac_pin = GPIO_PIN_5,
};

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_SPI1_Init();

    DAC8734_Init(&dac8734);

    /* 设置 4 路基准电压 */
    DAC8734_SetVoltage(&dac8734, DAC_CH_A, 3.3f);  // 参考电压
    DAC8734_SetVoltage(&dac8734, DAC_CH_B, 5.0f);  // 偏置
    DAC8734_SetVoltage(&dac8734, DAC_CH_C, 1.8f);  // 软启动斜率
    DAC8734_SetVoltage(&dac8734, DAC_CH_D, 0.5f);  // 保护阈值

    while (1) {
        /* 动态调整 */
        DAC8734_SetVoltage(&dac8734, DAC_CH_A, 3.0f);
        HAL_Delay(1000);
    }
}

参考代码 STM32 DAC8734 4路16位DA驱动程序 www.youwenfan.com/contentcsv/72602.html

七、校准功能

c 复制代码
/* 两点校准 */
void DAC8734_Calibrate(DAC8734_Handle_t *hdac,
                        DAC_Channel_t ch,
                        float real_v1, float set_v1,
                        float real_v2, float set_v2)
{
    float gain = (real_v2 - real_v1) / (set_v2 - set_v1);
    float offset = real_v1 - gain * set_v1;

    /* 写入 OFFSET / GAIN 寄存器 */
}

八、常见问题排查

现象 原因 解决
无输出 CS 时序错误 检查 SYNC 低电平宽度
输出不准 参考电压漂移 使用外部 2.5V 基准
噪声大 SPI 串扰 缩短走线,加 RC
多路耦合 LDAC 未同步 统一 LDAC 触发
相关推荐
无敌贵点大王1 小时前
从寄存器层面重学STM32(7)——定时器
stm32·单片机·嵌入式硬件
碧海银沙音频科技研究院2 小时前
粉色笔记本电脑每次要等把电池电耗尽才能开机问题解决方法
嵌入式硬件
wuyk55516 小时前
Keil工具链-第05讲-启动文件与__main到底做了什么
c语言·stm32·单片机·嵌入式硬件·物联网
shijuejianceliu1 天前
传统规则视觉与嵌入式AI智能相机的技术差异
人工智能·嵌入式硬件·视觉检测·相机
Zw-awa1 天前
OLED为什么能显示字:软件I2C换成硬件I2C
stm32
不脱发的程序猿1 天前
GD32串口数据收进内存之后DMA如何处理?
单片机·嵌入式硬件·dma·嵌入式·串口通信·gd32
FPGA小迷弟1 天前
FPGA 与千兆以太网校验和:从原理到 Verilog 实现
嵌入式硬件·fpga开发·无人机·ai编程·fpga
Zw-awa2 天前
协议是人为约定:同一个字节能有三种意思
stm32
国科安芯2 天前
83 倍:ASC0108S 在推挽和开漏之间,差的不是速度,是回程
单片机·嵌入式硬件·架构·电平转换·抗辐射
国科安芯2 天前
从遥控到自治:ASP4644S2B支撑星载电源健康管理与容错配电
网络·单片机·嵌入式硬件·安全·dcdc·低轨卫星·商业航天