简介这份资源面向使用STM32微控制器驱动AD5755高精度16位DAC的嵌入式开发者提供经过功能验证与调试的驱动程序代码可解决工业控制、测试测量及数据采集系统中精确电压输出的控制问题。压缩包共2个文件包含1个h头文件与1个c源文件整体约3KB头文件提供寄存器映射与命令代码等定义源文件实现初始化、电压输出设置、状态读取及SPI/I2C通信等核心函数便于直接集成到STM32固件工程中。目前已有416人学习下载适合需要快速完成AD5755接口配置与模拟输出调试的开发者参考。通过该驱动读者可掌握接口配置、驱动加载、DAC初始化、电压设定与错误处理等关键环节为电源调节、信号发生或系统校准等场景提供可复用的底层代码基础。1. AD5755 驱动移植从 ad5755_store9a4 看工业 DAC 的落地路径如果你手上有块 AD5755 四通道 16 位电流/电压输出 DAC 板子Linux 下iio子系统能识别但写值不生效或者干脆连设备节点都出不来那这篇就是写给你的。AD5755 这颗芯片在 PLC 模拟量输出、过程控制、HART 变送器里出镜率极高但它的驱动不是简单i2c-dev读寄存器就能跑通的——上电时序、CRC 校验、动态功率、电压/电流模式切换每一步都能让输出卡在 0 mA 或者满量程。标题里的ad5755_store9a4是驱动里负责把用户写入的 raw 值落到 DAC 寄存器的核心函数理解它基本就理解了整条数据通路。这篇面向做嵌入式 Linux 驱动移植、工业板卡调试的工程师从设备树配置一路讲到 store 函数的参数校验和踩坑记录目标是让你能在自己的板子上把四路输出跑起来。2. AD5755 驱动模型拆解IIO 框架下的四通道 DAC 怎么组织2.1 为什么走 IIO 而不是字符设备AD5755 是四通道、16 位、支持电压和电流输出的 DAC还带片内基准和 DC-DC 转换器。这种多通道、带量程切换、需要暴露 raw 值和 scale 的器件用传统misc字符设备写 ioctl 会非常别扭。Linux 的 IIOIndustrial I/O子系统天生就是为这类工业模拟器件设计的每个通道一个iio_chan_specraw 值走iio_dev的读写回调量程通过scale属性暴露给用户态sysfs下自动生成out_voltage0_raw、out_current1_raw这样的节点。常见做法是把 AD5755 注册成iio_dev在probe里分配通道数组每个通道指定typeIIO_VOLTAGE或IIO_CURRENT、channel编号、output标志、info_mask_separate里挂上IIO_CHAN_INFO_RAW和IIO_CHAN_INFO_SCALE。这样用户态echo 32768 out_voltage0_raw就能直接写半量程不用自己算寄存器地址。选 IIO 的另一个理由是它和regmap配合得好。AD5755 走 SPI寄存器是 24 位帧8 位地址 16 位数据还带 CRC。用regmap把 SPI 读写封装起来store函数里只关心逻辑不用每次手拼字节序。2.2 ad5755_store9a4 在数据通路里的位置ad5755_store9a4这个名字拆开看ad5755是器件store是 IIO 的写回调命名习惯9a4大概率是作者或版本标识。它的职责是接收用户态写入的 raw 值做范围检查然后通过regmap写到对应通道的 DAC 数据寄存器。整条通路是这样的用户态 echo - sysfs out_voltage0_raw - iio_dev-info-write_raw (即 ad5755_store9a4) - 校验 val 是否在 0~65535 - 查通道对应的寄存器地址 - regmap_write(ad5755-regmap, reg, val) - SPI 24 位帧 CRC - AD5755 芯片关键点在于AD5755 的 DAC 寄存器不是直接写值就输出它还有一层“输出使能”和“量程寄存器”。如果量程寄存器没配对你写 65535 可能只输出 5V 而不是 10V或者电流通道直接不动作。store函数通常只负责数据寄存器量程和使能要在probe或单独的write_raw分支里处理。2.3 通道与寄存器的映射关系AD5755 四个通道每个通道有独立的 DAC 数据寄存器、量程寄存器、控制寄存器。典型映射如下具体地址以数据手册为准这里给的是常见布局通道DAC 数据寄存器量程寄存器控制寄存器00x000x080x1010x010x090x1120x020x0A0x1230x030x0B0x13在驱动里一般用struct ad5755_state存regmap、spi_device、以及每个通道的当前量程模式。store函数拿到chan-channel后查表得到寄存器地址再写值。提示AD5755 的寄存器地址是 5 位数据 16 位SPI 帧共 24 位。如果regmap配置成 8 位地址 16 位数据要确认reg_bits8、val_bits16、pad_bits0否则帧会错位。3. 从设备树到 store 函数AD5755 驱动移植的完整步骤3.1 设备树节点与 SPI 配置先确认硬件连接AD5755 的SYNC接 SPI 片选SCLK、SDIN、SDO标准四线。复位引脚RESET和报警ALERT可选。设备树里挂到对应 SPI 控制器下spi1 { status okay; ad5755: dac0 { compatible adi,ad5755; reg 0; spi-max-frequency 1000000; spi-cpol; spi-cpha; reset-gpios gpio1 15 GPIO_ACTIVE_LOW; adi,range-select; }; };spi-cpol和spi-cpha必须加AD5755 是模式 2CPOL1, CPHA0或模式 3具体看手册时序图。spi-max-frequency先给 1 MHz跑通后再往上提AD5755 支持到 30 MHz 但长线要降速。reset-gpios用于上电复位没有的话驱动里要发软件复位命令。3.2 regmap 初始化与 CRC 使能AD5755 的 SPI 帧可以带 CRC也可以不带。带 CRC 时每帧多 8 位校验多项式是 0x07。驱动里用regmap的read_flag_mask和write_flag_mask控制读写位CRC 一般自己拼帧或者用regmap的自定义总线。static const struct regmap_config ad5755_regmap_config { .reg_bits 8, .val_bits 16, .read_flag_mask 0x80, .write_flag_mask 0x00, .max_register 0x1F, .cache_type REGCACHE_NONE, }; static int ad5755_probe(struct spi_device *spi) { struct ad5755_state *st; struct regmap *regmap; st devm_kzalloc(spi-dev, sizeof(*st), GFP_KERNEL); if (!st) return -ENOMEM; regmap devm_regmap_init_spi(spi, ad5755_regmap_config); if (IS_ERR(regmap)) return PTR_ERR(regmap); st-regmap regmap; spi_set_drvdata(spi, st); /* 硬件复位 */ if (st-reset_gpio) { gpiod_set_value_cansleep(st-reset_gpio, 1); msleep(1); gpiod_set_value_cansleep(st-reset_gpio, 0); msleep(10); } return 0; }read_flag_mask 0x80是因为 AD5755 读操作时地址最高位置 1。REGCACHE_NONE表示不用缓存每次直接走 SPI避免缓存和芯片实际值不一致。复位后至少等 10 ms 再访问寄存器否则芯片内部基准还没稳。3.3 store 函数的参数校验与写入逻辑ad5755_store9a4的核心逻辑不复杂但边界条件多。下面是一个典型实现static int ad5755_store9a4(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long mask) { struct ad5755_state *st iio_priv(indio_dev); u8 reg; int ret; if (mask ! IIO_CHAN_INFO_RAW) return -EINVAL; /* 16 位 DACraw 值范围 0~65535 */ if (val 0 || val 65535) return -EINVAL; /* 通道号映射到 DAC 数据寄存器 */ switch (chan-channel) { case 0: reg AD5755_DAC_A; break; case 1: reg AD5755_DAC_B; break; case 2: reg AD5755_DAC_C; break; case 3: reg AD5755_DAC_D; break; default: return -EINVAL; } /* 检查通道是否已使能输出 */ if (!(st-chan_enabled BIT(chan-channel))) return -EPERM; ret regmap_write(st-regmap, reg, val); if (ret) dev_err(indio_dev-dev, write dac reg %02x failed: %d\n, reg, ret); return ret; }逻辑说明先校验mask是不是IIO_CHAN_INFO_RAW因为同一个write_raw可能还要处理IIO_CHAN_INFO_SCALE或IIO_CHAN_INFO_CALIBBIAS。然后范围检查AD5755 是 16 位无符号负值直接拒。通道映射用switch而不是数组方便加调试打印。chan_enabled位图记录哪些通道已经配置好量程并使能没使能就返回-EPERM避免用户写了一个通道但输出没反应还找不到原因。参数说明val是用户写入的 raw 值val2在 raw 模式下不用mask区分属性。regmap_write的第三个参数是 16 位值regmap会自动按val_bits16拼帧。3.4 量程与输出使能的配置顺序AD5755 上电后所有通道默认是电压输出、0~5V 量程、输出高阻。要输出电流必须先写量程寄存器再写控制寄存器使能输出最后写 DAC 数据。顺序反了会短暂输出错误值。static int ad5755_set_range(struct ad5755_state *st, int ch, u8 range) { u8 reg AD5755_RANGE_A ch; int ret; ret regmap_write(st-regmap, reg, range); if (ret) return ret; /* 使能输出 */ ret regmap_write(st-regmap, AD5755_CTRL_A ch, AD5755_CTRL_EN); if (ret) return ret; st-chan_enabled | BIT(ch); return 0; }常见量程编码0x00 对应 0~5V0x01 对应 0~10V0x02 对应 0~20mA0x03 对应 4~20mA。具体值查手册。写完量程后至少等 1 ms 再写数据DC-DC 转换器需要建立时间。4. AD5755 驱动调试避坑SPI 无响应、输出漂移、CRC 报错4.1 现象probe 成功但 sysfs 写值无输出原因最常见的是量程寄存器没配或者控制寄存器的输出使能位没置。AD5755 的 DAC 数据寄存器写了值但输出级还处于高阻万用表量不到。另一个可能是regmap的write_flag_mask配错写操作被当成读芯片没收到数据。解决先读回 DAC 数据寄存器确认写入生效。如果读回值对但输出不对检查量程和使能。用示波器抓 SPI 波形确认 24 位帧的地址位和数据位顺序。AD5755 是 MSB first如果 SPI 控制器配成 LSB first地址会完全错位。4.2 现象输出电流在 4~20mA 模式下卡在 0mA原因4~20mA 模式需要外部环路电源AD5755 的AVDD和AVSS要满足手册要求通常AVDD要 15V 以上。如果只给了 5V电流输出级不工作。另外FAULT引脚如果被拉低芯片会关闭输出。解决量AVDD对AGND的电压确认在 12~33V 范围内。检查FAULT引脚状态读状态寄存器看有没有报警。4~20mA 模式下 raw 值 0 对应 4mA65535 对应 20mA如果写 0 输出 0mA说明量程选成了 0~20mA。4.3 现象SPI 读回数据 CRC 错误或全 0xFF原因CRC 使能了但驱动没算 CRC或者 SPI 模式不对。AD5755 的 CRC 是 8 位多项式 0x07初始值 0x00覆盖 24 位数据。如果驱动发帧不带 CRC 但芯片配置成 CRC 使能芯片会忽略所有命令。解决先确认芯片的 CRC 使能位。有些板子通过硬件引脚配置有些通过寄存器。如果不用 CRC在probe里发命令关掉。用逻辑分析仪抓 MISO 线如果一直是高电平说明芯片没驱动 MISO检查SDO是否使能。4.4 现象多通道同时输出时互相干扰原因AD5755 四个通道共用一套 SPI 接口和基准如果regmap没有加锁多线程同时写不同通道会导致帧交错。另外 DC-DC 转换器负载突变时基准会有短暂波动。解决在store函数里加mutex_lock(st-lock)保证 SPI 帧原子性。如果对精度要求高写完一个通道后等 100 us 再写下一个。基准波动可以通过加去耦电容缓解典型值 10 uF 并联 100 nF。4.5 现象上电后第一帧 SPI 无响应原因AD5755 上电需要复位如果RESET引脚悬空或驱动没拉芯片内部状态机可能没初始化。另外 SPI 控制器的片选在probe之前可能已经拉低过导致芯片误判帧边界。解决在probe最开始手动拉低RESET至少 10 ns再拉高等 10 ms。如果没接复位引脚发软件复位命令写 0x1F 寄存器。SPI 控制器的cs-gpios要配成手动模式避免自动片选在数据传输中间翻转。5. 进阶用 IIO 缓冲和触发实现 AD5755 的同步输出5.1 为什么单次写 sysfs 不够单次echo写out_voltage0_raw适合调试但工业场景经常要求四通道同步更新比如三相电流源或者波形发生器。AD5755 支持LDAC引脚同步加载四个通道的数据可以先写到影子寄存器然后一个LDAC脉冲同时更新所有输出。IIO 的缓冲模式配合硬件触发可以做到这一点。5.2 配置 IIO 缓冲与 LDAC 触发在probe里注册一个触发源把LDAC引脚配成 GPIO 输出。用户态通过configfs创建触发然后使能缓冲# 创建触发 mkdir /sys/kernel/config/iio/triggers/hrtimer/ad5755_trig # 绑定到设备 echo ad5755_trig /sys/bus/iio/devices/iio:device0/trigger/current_trigger # 使能通道 0 和 1 的缓冲 echo 1 /sys/bus/iio/devices/iio:device0/scan_elements/out_voltage0_raw_en echo 1 /sys/bus/iio/devices/iio:device0/scan_elements/out_voltage1_raw_en # 设置缓冲长度 echo 4 /sys/bus/iio/devices/iio:device0/buffer/length # 使能缓冲 echo 1 /sys/bus/iio/devices/iio:device0/buffer/enable驱动里在write_raw的缓冲回调中把数据写到影子寄存器然后在触发处理函数里拉LDAC。这样四通道更新延迟在微秒级远好于逐个写 sysfs。5.3 验证同步输出的方法用示波器四通道同时抓四个输出给一个阶跃信号看四个通道的上升沿是否对齐。如果偏差超过 10 us检查LDAC脉冲宽度是否够手册要求最小 20 ns以及 SPI 写入是否在LDAC之前全部完成。另一个方法是读回所有 DAC 寄存器确认影子寄存器的值和预期一致。我自己的习惯是先在单通道模式下把量程、使能、数据写入全部跑通再用iio_generic_buffer工具做缓冲测试。iio_generic_buffer -n ad5755 -t ad5755_trig -g -c 100可以连续发 100 个样本观察输出波形有没有断点。如果中间有跳变多半是regmap没加锁或者触发频率超过了 SPI 带宽。AD5755 在 1 MHz SPI 下写一个通道要 24 us四通道加LDAC至少 120 us触发周期不能低于这个值。希望帮到你。本文还有配套的精品资源点击获取
