ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

DS2431驱动开发实战:从1-Wire时序到可移植C代码

DS2431驱动开发实战:从1-Wire时序到可移植C代码 简介DS2431完整驱动是一套基于单总线协议的轻量级驱动代码面向嵌入式开发者和物联网硬件工程师旨在快速集成DS2431芯片的存储读写与初始化操作。该驱动将底层时序控制、命令发送与数据校验封装在简洁的API中用户只需将DS2431.c和DS2431.h两个源文件添加至工程并指定连接端口即可完成调用无需关心复杂的总线协议细节大幅缩短开发调试周期同时提供独立的读写接口便于按需读取或修改芯片内部数据。压缩包内文件总数仅为2个包含一个C源文件与一个对应的头文件整体大小约6KB代码结构紧凑可在Keil、IAR等常见MCU开发环境中直接编译使用。驱动还提供了对芯片非易失性存储区域的访问支持适用于设备标识、校准参数等需掉电保留的数据管理场景在智能终端、工业控制与物联网节点中均有实用价值。截至目前该资源已有2644人学习下载适合具备一定单片机基础、正在评估或使用DS2431器件的工程师参考借鉴。 做过产品序列号管理、设备身份识别或者需要在断电后保存校准参数的嵌入式朋友对 DS2431 这颗芯片应该不陌生。它是 ADI原 Maxim出品的一款 1-Wire 单总线 EEPROM容量 1Kbit封装小、成本低只靠一根数据线和地线就能完成通信非常适合用在设备身份识别、校准数据存储、耗材防伪这类场景。这篇文章不打算复述芯片手册而是把我从零写的一套 DS2431 完整驱动摊开讲清楚包含 1-Wire 协议时序、可移植的 C 代码、写 EEPROM 时容易翻车的细节以及实际调试中踩过的坑。无论你用 STM32、GD32 还是其它 MCU只要弄懂了这套设计思路基本可以无缝抄作业。先说清楚一件事这里的“驱动”不是电脑上那种 CH340、CP2102 串口驱动而是 MCU 里的底层外设驱动。很多人搜 DS2431 驱动搜到的是串口安装包那是两码事。下面进入正题。1. 为什么选 DS2431一颗 1-Wire EEPROM 能解决什么问题1.1 DS2431 的核心参数与硬件特点DS2431 的存储空间是 1024 bit也就是 128 字节被分成 4 页每页 32 字节。它最大的特点是所有通信只走一根数据线 DQ加上地线 VSS 就够用了而且这颗芯片既支持外部供电2.8V~5.25V也支持寄生供电——直接从数据线上“偷电”工作。典型待机电流只有 1uA 左右对于电池供电的设备来说非常友好。每一颗 DS2431 出厂时都刻录了一个 64 位的唯一 ROM ID其中包含 8 位家族码、48 位序列号和 8 位 CRC 校验码。这意味着每颗芯片都有全球唯一的身份标识不需要外部单片机也能做设备认证。另外它的每一页还带独立的写保护位 WP 和 EPROM 仿真模式位 EP可以用来做一次性写入或者防篡改处理。1.2 典型应用场景从防伪到校准存储我在实际项目里见过并且自己用过几种典型玩法第一类是设备身份认证。比如仪器仪表在出厂前把序列号、型号、生产日期写进 DS2431之后上位机通过 1-Wire 转 USB 工具读取这颗芯片的 ID 和数据就能快速识别设备身份防止第三方假货混入。第二类是校准参数存储。传感器设备在产线校准时会把校准系数、温漂补偿值写进去设备每次上电时读取这些参数。因为 DS2431 是 EEPROM断电不丢数据也比外挂 SPI Flash 省 GPIO。第三类是耗材防伪。打印机墨盒、医疗耗材、电池组里面焊一颗 DS2431设备通过读取芯片里的加密信息和 ID 来判断耗材是否原装、剩余寿命多少。这颗芯片的容量不大但胜在接口极简、稳定性好、驱动逻辑一旦吃透就很可控。相比用现成的 OneWire 库自己写驱动的好处是代码量小、便于裁剪还能在关键节点做定制化处理。2. 1-Wire 协议机制驱动必须吃透的底层时序2.1 硬件连接与上拉电阻1-Wire 总线本质上是一条开漏信号线所有设备共用一个 DQ 节点不通信时总线处于高电平。MCU 的 GPIO 必须配置成开漏输出模式并在 DQ 线上接一个上拉电阻。电阻值的选择很关键标准速率下典型值是 4.7kΩ如果总线较长或者挂载设备较多可以降到 2.2kΩ但不要用 10kΩ 以上的电阻否则上升沿太慢时隙容易出错。如果使用寄生供电模式要注意 DS2431 在 EEPROM 写操作期间需要较大的电流总线必须有足够的上拉能力否则写入会失败。我的建议是只要条件允许尽量用外部供电省掉一堆麻烦。后面我会专门讲寄生供电踩坑的事。2.2 五种时隙复位、写 0、写 1、读、等待应答1-Wire 协议没有独立的时钟线所有时序都是通过 GPIO 拉低、释放的宽度来定义的。主机和从机之间通信的最小单位是“时隙”每个时隙大约 60us~120us。时序参数不算复杂但必须精确尤其是复位和读时隙。时序类型参数要求说明复位脉冲主机拉低 480us~960us 后释放用于初始化总线应答脉冲从机拉低 60us~240us从机存在信号主机释放后约 60us 采样写 1 时隙拉低 1us~15us然后释放剩余时间保持高电平写 0 时隙拉低 60us~120us 整个时隙期间不允许释放总线读时隙拉低 1us~6us 后释放主机需在释放后 15us 内完成采样这里有一个很多新手容易搞错的地方读时隙和写 1 时隙的起始动作看起来很像都是主机拉低一小段时间然后释放。但区别在于读时隙中主机会在释放后主动去采样总线电平而写 1 时隙中主机并不关心总线状态。所以代码里读时序一定要在拉低释放后的极短窗口内读 GPIO不能等到时隙快结束了才读。2.3 ROM 命令与存储命令完整读写流程1-Wire 总线可以挂多个 DS2431靠 64 位 ROM ID 区分设备。访问设备时主机先发送复位脉冲然后发送 ROM 命令。最常用的有Read ROM0x33读取总线上唯一设备的 ROM IDSkip ROM0xCC不匹配地址直接访问总线上的设备适用于单设备场景Match ROM0x55后跟 64 位 ROM ID精确匹配指定设备Search ROM0xF0搜索总线上所有设备多设备场景用ROM 命令之后进入存储命令阶段。DS2431 的命令字节如下命令字节码作用Write Scratchpad0x0F向暂存器写入目标地址和数据Read Scratchpad0xAA回读暂存器验证写入内容Copy Scratchpad0x48把暂存器内容复制到 EEPROMRead Memory0xF0从 EEPROM 指定地址连续读取写 EEPROM 的标准流程是先复位再 Skip ROM接着发 0x0F 写暂存器把目标地址和要写入的数据发过去然后再次复位发 0x48 复制暂存器附带目标地址和校验字节 ES最后等待 tPROG 编程时间典型值 10ms再回读验证。这个过程如果省略任何一步都可能出现写入不稳定或者丢数据的情况。3. 完整驱动实现从时隙函数到应用 API3.1 平台适配层四行宏搞定移植我在写这个驱动时把硬件相关的操作封装成了 4 个宏加一个延时函数。这样移植到不同 MCU 时只需要修改这一小段协议层代码完全不用动。/* ds2431.h */ #ifndef __DS2431_H #define __DS2431_H #include stdint.h /* 移植时只需修改以下宏和延时函数 */ #define DS2431_DQ_OUT() HAL_GPIO_WritePin(DS2431_PORT, DS2431_PIN, GPIO_PIN_RESET) // 占位示例 #define DS2431_DQ_IN() // 切换为输入模式或释放总线 #define DS2431_DQ_LOW() // DQ 拉低 #define DS2431_DQ_HIGH() // DQ 拉高开漏模式下释放 #define DS2431_DQ_READ() // 读取 DQ 电平返回 0 或 1 void DS2431_DelayUs(uint32_t us); void DS2431_DelayMs(uint32_t ms); #endif这里有个细节1-Wire 总线是开漏结构所以“释放总线”等价于把 GPIO 配置为输入模式或者开漏输出时输出高电平。我在 STM32 上习惯把 DQ 引脚初始化为开漏输出然后需要读的时候切换成输入模式写完再切回开漏输出。只有输入模式才能避免 MCU 内部上拉或下拉影响采样结果。3.2 底层时序复位、写位、读位时序层是整个驱动的根基必须保证微秒级延时准确。我建议在 STM32 上用 DWT 实现延时后面第 4 章会给出具体代码。先把时序函数写出来/* ds2431.c时序部分 */ uint8_t DS2431_Reset(void) { uint8_t presence 0; DS2431_DQ_OUT(); DS2431_DQ_LOW(); DS2431_DelayUs(520); /* 复位脉冲拉低 520us */ DS2431_DQ_IN(); /* 释放总线 */ DS2431_DelayUs(70); /* 等待从机应答窗口 */ presence DS2431_DQ_READ(); /* 有应答时总线被从机拉低读到 0 */ DS2431_DelayUs(200); /* 等待应答结束释放总线 */ return presence; /* 返回 0 表示检测到设备 */ } void DS2431_WriteBit(uint8_t bit) { DS2431_DQ_OUT(); DS2431_DQ_LOW(); if (bit) { DS2431_DelayUs(3); /* 写 1低脉冲 3us 后释放 */ DS2431_DQ_HIGH(); DS2431_DelayUs(57); /* 补满整个时隙 */ } else { DS2431_DelayUs(60); /* 写 0保持低电平整个时隙 */ DS2431_DQ_HIGH(); DS2431_DelayUs(3); } } uint8_t DS2431_ReadBit(void) { uint8_t dat 0; DS2431_DQ_OUT(); DS2431_DQ_LOW(); DS2431_DelayUs(3); /* 读时隙起始脉冲 */ DS2431_DQ_IN(); /* 释放总线 */ DS2431_DelayUs(8); /* 在 15us 窗口内采样 */ dat DS2431_DQ_READ(); DS2431_DelayUs(50); /* 补满时隙 */ return dat; } void DS2431_WriteByte(uint8_t dat) { for (uint8_t i 0; i 8; i) { DS2431_WriteBit(dat 0x01); dat 1; /* LSB first先发低位 */ } } uint8_t DS2431_ReadByte(void) { uint8_t dat 0; for (uint8_t i 0; i 8; i) { dat 1; if (DS2431_ReadBit()) { dat | 0x80; /* LSB first低位先读 */ } } return dat; }注意复位函数的返回值逻辑我返回的是 DQ 引脚的电平如果读到的电平是 0说明从机有应答设备存在。很多人在这一步会写反建议在代码里用宏或者注释明确区分“检测到设备”和“返回值 0”。3.3 命令层Skip ROM、Read ROM 与 CRC8时序函数就位之后命令层就简单了。多设备模式和单设备模式的差别主要在 ROM 命令上我先把最常用的 Skip ROM 和 Read ROM 封装好。/* ds2431.c命令层 */ void DS2431_SkipROM(void) { DS2431_WriteByte(0xCC); } uint8_t DS2431_ReadROM(uint8_t *rom) { uint8_t crc 0; if (DS2431_Reset() ! 0) return 0xFE; /* 无设备应答 */ DS2431_WriteByte(0x33); /* Read ROM 命令 */ for (uint8_t i 0; i 7; i) { rom[i] DS2431_ReadByte(); crc DS2431_CRC8(crc, rom[i]); } rom[7] DS2431_ReadByte(); /* 第 8 字节是 CRC */ if (crc ! rom[7]) return 0xFC; /* CRC 校验失败 */ return 0; } uint8_t DS2431_CRC8(uint8_t crc, uint8_t data) { uint8_t i; crc ^ data; for (i 0; i 8; i) { if (crc 0x01) crc (crc 1) ^ 0x8C; /* 反向多项式 */ else crc 1; } return crc; }这里的 CRC8 是 Dallas/Maxim 1-Wire 系列通用的校验算法反向多项式是 0x8C。它主要用于校验 64 位 ROM ID确保读到的序列号没有受到干扰。如果你不需要做多设备匹配只做单设备访问Skip ROM 就够用了Read ROM 可以作为产线身份识别时的辅助手段。3.4 存储 APIReadMemory 与 WriteMemory 的完整实现存储层的核心是 Read Memory 和 Write Memory。Read Memory 相对简单Write Memory 要注意写暂存器、复制暂存器、等待编程完成、回读校验这四个环节缺一不可。/* ds2431.c存储 API */ uint8_t DS2431_ReadMemory(uint16_t addr, uint8_t *buf, uint16_t len) { if (buf NULL || len 0) return 0xFF; if (addr len 128) return 0xFD; /* 地址越界 */ if (DS2431_Reset() ! 0) return 0xFE; DS2431_SkipROM(); DS2431_WriteByte(0xF0); /* Read Memory */ DS2431_WriteByte p a hrefhttps://download.csdn.net/download/qq_20967663/9666949 stylecolor:#ec7500;font-size:14px; 本文还有配套的精品资源点击获取 /a img altmenu-r.4af5f7ec.gif srchttps://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif stylewidth:16px;margin-left:4px;vertical-align:text-bottom;cursor:text; /p
返回列表