当前位置: 首页 > news >正文

MCU驱动AD5231BRUZ_10K

芯片:AD5231 10k的量程

mcu: 普冉的F002B

通信协议:SPI

关于AD5231的数据手册可以到立创商城里面下载。

直接贴驱动代码

SPI配置

#include "py_spi.h"
#include <py32f002b_hal_rcc.h>
#include "am_gpio_config.h"SPI_HandleTypeDef Spi1Handle;PyGpioStructDef ad5231_cs_gpio={AD5321_SPI_CS_GPIOx,AD5321_SPI_CS_GPIOx_PINx};static void py_spi_gpio_config(void)
{GPIO_InitTypeDef  GPIO_InitStruct;__HAL_RCC_GPIOB_CLK_ENABLE();                   __HAL_RCC_GPIOA_CLK_ENABLE();  /*PB0   ------> SCKPA1   ------> MISOPA0   ------> MOSIPA6   ------> NSS*//*SCK*/GPIO_InitStruct.Pin       = SPI_CLK_GPIOx_PINx;GPIO_InitStruct.Pull = GPIO_PULLDOWN;GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_HIGH;GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;HAL_GPIO_Init(SPI_CLK_GPIOx, &GPIO_InitStruct);/* SPI NSS*/GPIO_InitStruct.Pin = AD5321_SPI_CS_GPIOx_PINx;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;HAL_GPIO_Init(AD5321_SPI_CS_GPIOx, &GPIO_InitStruct);/* MOSI*/GPIO_InitStruct.Pin       = SPI_MOSI_GPIOx_PINx ;GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_HIGH;GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;HAL_GPIO_Init(SPI_MOSI_GPIOx, &GPIO_InitStruct);/* MISO*/GPIO_InitStruct.Pin       = SPI_MISO_GPIOx_PINx ;GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_HIGH;GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;HAL_GPIO_Init(SPI_MISO_GPIOx, &GPIO_InitStruct);HAL_GPIO_WritePin(AD5321_SPI_CS_GPIOx, AD5321_SPI_CS_GPIOx_PINx, GPIO_PIN_SET);}/*** @brief  SPI_FLASH初始化 cs软件控制* @param  无* @note  	无* @retval 无*/void py_spi_init(SPI_HandleTypeDef *spi_handle){__HAL_RCC_SPI1_CLK_ENABLE(); py_spi_gpio_config();/* 初始化SPI配置 *//* SPI1 */spi_handle->Instance               = SPI1;     /* 4 分频 */spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;  /* 全双工 */spi_handle->Init.Direction         = SPI_DIRECTION_2LINES;   /* 时钟极性低 */    spi_handle->Init.CLKPolarity       = SPI_POLARITY_LOW;   /* 数据采样从第一个时钟边开始 */spi_handle->Init.CLKPhase          = SPI_PHASE_1EDGE ;  /* SPI数据长度为8位 */    spi_handle->Init.DataSize          = SPI_DATASIZE_8BIT;  /* MSB 模式 */    spi_handle->Init.FirstBit          = SPI_FIRSTBIT_MSB; /* NSS硬件模式 */    spi_handle->Init.NSS               = SPI_NSS_SOFT;  //软件CS/* 主模式 */spi_handle->Init.Mode = SPI_MODE_MASTER;                         /* SPI初始化 */HAL_SPI_Init(spi_handle);}//cs控制
void py_spi_cs_writepin(PyGpioStructDef cs_gpio,uint8_t x)
{HAL_GPIO_WritePin(cs_gpio.GPIOx,cs_gpio.GPIO_Pin,x);
}//SPI阻塞模式下发送和接收数据/// @brief SPI发送一个字节
/// @param data     数据
/// @param Timeout  超时时间
/// @return 0发送成功
uint8_t py_spi_send_u8(uint8_t data , uint32_t Timeout)
{   return (uint8_t)HAL_SPI_Transmit(&Spi1Handle, &data, 1, Timeout);
}/// @brief py_spi_send_u16 发送U16数据
/// @param data 数据
/// @param Timeout 超时时间
/// @return  0发送成功
uint8_t py_spi_send_u16(uint16_t data , uint32_t Timeout)
{   return (uint8_t)HAL_SPI_Transmit(&Spi1Handle, &data, 2, Timeout);
}/// @brief py_spi_send_Buff 发送数据包
/// @param databuf 数据地址
/// @param len  长度
/// @param Timeout 超时
/// @return 0发送成功
uint8_t py_spi_send_Buff(uint8_t *databuf ,uint16_t len, uint32_t Timeout)
{   return (uint8_t)HAL_SPI_Transmit(&Spi1Handle, databuf, len, Timeout);
}/// @brief SPI读取一个字节
/// @param data     数据
/// @param Timeout  超时时间
/// @return 0发送成功
uint8_t py_spi_read_u8(uint8_t *data , uint32_t Timeout)
{   return (uint8_t)HAL_SPI_Receive(&Spi1Handle, data, 1, Timeout);
}/// @brief py_spi_send_u16 读取U16数据
/// @param data 数据
/// @param Timeout 超时时间
/// @return  0发送成功
uint8_t py_spi_read_u16(uint16_t *data , uint32_t Timeout)
{   return (uint8_t)HAL_SPI_Receive(&Spi1Handle, data, 2, Timeout);
}/// @brief py_spi_send_Buff 读取数据包
/// @param databuf 数据地址
/// @param len  长度
/// @param Timeout 超时
/// @return 0发送成功
uint8_t py_spi_read_Buff(uint8_t *databuf ,uint16_t len, uint32_t Timeout)
{   return (uint8_t)HAL_SPI_Receive(&Spi1Handle, databuf, len, Timeout);
}/// @brief spi阻塞模式下,发送和接收
/// @param pTxData 发送地址
/// @param pRxData 接收地址
/// @param len     个数
/// @param Timeout 超时时间
/// @return 0发送成功
uint8_t py_spi_send_and_read(uint8_t *pTxData, uint8_t *pRxData, uint16_t len,uint32_t Timeout)
{   return (uint8_t)HAL_SPI_TransmitReceive(&Spi1Handle, pTxData, pRxData, len, Timeout);
}
#ifndef __PY_SPI_H
#define __PY_SPI_H#include "py32f0xx_hal.h"
#include <py32f002bx5.h>
#include "./py_gpio/py_gpio.h"//硬件SPIextern SPI_HandleTypeDef Spi1Handle;
extern PyGpioStructDef ad5231_cs_gpio;void py_spi_init(SPI_HandleTypeDef *spi_handle);void py_spi_cs_writepin(PyGpioStructDef cs_gpio,uint8_t x);uint8_t py_spi_send_u8(uint8_t data , uint32_t Timeout);
uint8_t py_spi_send_u16(uint16_t data , uint32_t Timeout);
uint8_t py_spi_send_Buff(uint8_t *databuf ,uint16_t len, uint32_t Timeout);uint8_t py_spi_read_u8(uint8_t *data , uint32_t Timeout);
uint8_t py_spi_read_u16(uint16_t *data , uint32_t Timeout);
uint8_t py_spi_read_Buff(uint8_t *databuf ,uint16_t len, uint32_t Timeout);uint8_t py_spi_send_and_read(uint8_t *pTxData, uint8_t *pRxData, uint16_t len,uint32_t Timeout);

上面的SPI代码,和STM32的HAL库基本差不多。

下面是AD5231的驱动代码,驱动AD5231主要就是修改他的寄存器,正常使用到的命令就几个就够了,先简单的了解一下AD5231的命令吧

1.写入RDAC

2.读RDAC

3.将RDAC写入EEMEM

4.将EEMEM的数据恢复到REAC寄存器,基本就这几条,具体的参数命令可以看数据手册

 AD5231的数据协议是3个字节,一共24bit.

下面直接贴驱动代码,只需要把SPI修改成你自己的驱动,基本就没问题。

#include "ad5231.h"#include "./delay/delay.h"#define ad5231_delat_us(x) Delay_us(x)static uint8_t ad5231_cs_set(uint8_t x)
{py_spi_cs_writepin(ad5231_cs_gpio,x);
}/// @brief spi发送数据并读取数据
/// @param data 数据地址
/// @return 1成功 ,0失败
static uint8_t ad5231_spi_send_data(uint8_t *txdata,uint8_t *rxdata)
{uint8_t ret =0;ad5231_cs_set(0);ret = py_spi_send_and_read(txdata,rxdata,3,1000);ad5231_cs_set(1);if(ret == 0){return 1;}else{return 0;}
}static uint8_t ad5231_write_cmd(uint8_t cmd,uint8_t addr,uint16_t data,uint8_t *rxdata)
{uint8_t txdata[3]={0};//uint8_t rxdata[3]={0};txdata[0] = ((cmd << 4) | addr);txdata[1] = (uint8_t)(data >> 8);txdata[2] = (uint8_t)(data & 0x00ff);return ad5231_spi_send_data(txdata,rxdata);
}/// @brief 写入RDAC
/// @param data 0-2013
/// @return 1写入完成
uint8_t ad5231_write_rdac(uint16_t rdac)
{uint8_t rxdata[3]={0};if(rdac > AD5231_SizeRDAC){rdac = AD5231_SizeRDAC;}   return ad5231_write_cmd(AD5231_CMD_WRITE_RDAC,0x0,rdac,rxdata);
}/// @brief 读取RDAC
/// @param data 0-2013
/// @return 1完成
uint8_t ad5231_read_rdac(uint16_t *rdac)
{uint8_t rxdata[3]={0};uint16_t data=0;if(ad5231_write_cmd(AD5231_CMD_READ_RDAC,0x0,0x0,rxdata)){ad5231_delat_us(200);ad5231_write_cmd(0x0,0x0,0x0,rxdata);data = rxdata[1] ;*rdac = ((data<<8) | rxdata[2]);return 1;}else{return 0;}
}uint8_t ad5231_rdac_write_eemem(uint16_t rdac)
{uint8_t rxdata[3]={0};if(rdac > AD5231_SizeRDAC){rdac = AD5231_SizeRDAC;}  if(ad5231_write_cmd(AD5231_CMD_WRITE_RDAC,0x0,rdac,rxdata)){ad5231_delat_us(200);return ad5231_write_cmd(AD5231_CMD_WRITE_EEMEM,0x0,0x0,rxdata);}else{return 0;}}uint8_t ad5231_restores_eemem_to_rdac(void)
{uint8_t rxdata[3]={0};if(ad5231_write_cmd(AD5231_CMD_RESTORES_EEMEM_RDAC,0x0,0x0,rxdata)){ad5231_delat_us(300);return ad5231_write_cmd(AD5231_CMD_NOP,0x0,0x0,rxdata);//恢复编程}else{return 0;}}void ad5231_init(void)
{py_spi_init(&Spi1Handle);}//软件校准
static uint16_t ad5231_software_calibration_rdac(uint32_t r)
{double temp;temp = (double)r;if(r < AD5231_RWB_MIN){return 0;}else if(r > AD5231_RWB_MAX){return AD5231_SizeRDAC;}temp = ((temp -  88.193) / 8.6876);return (uint16_t)(temp+0.5);}uint8_t ad5231_set_RwB(uint32_t r)
{uint16_t rdac=0;if(r > AD5231_SizeR){r = AD5231_SizeR;}rdac = ad5231_software_calibration_rdac(r);return  ad5231_write_rdac(rdac);
}uint8_t ad5231_set_RwA(uint32_t r)
{uint16_t rdac=0;rdac = ad5231_software_calibration_rdac((AD5231_SizeR -r));return   ad5231_write_rdac(rdac);
}
#ifndef __AD5231_H
#define __AD5231_H#include "./py_gpio/py_gpio.h"
#include "./py_spi/py_spi.h"//AD5272命令#define AD5231_CMD_NOP          0x0         // NOP:无操作。
#define AD5231_CMD_RESTORES_EEMEM_RDAC  0X1  //EEMEMS软件复位到RDAC
#define AD5231_CMD_WRITE_EEMEM  0X2           //RDAC写入EEMEM
#define AD5231_CMD_WRITE_RDAC   0xB         // 写入RDAC。
#define AD5231_CMD_READ_RDAC    0xA        // 读取RDAC#define AD5231_SizeR   9000//Ω  总电阻
#define AD5231_SizeRDAC   1024-1 //触点,抽头
#define AD5231_RW     55//
#define AD5231_RWB_MIN 90
#define AD5231_RWB_MAX 8970void ad5231_init(void);
uint8_t ad5231_write_rdac(uint16_t rdac);//写RDAC
uint8_t ad5231_read_rdac(uint16_t *rdac);//读RDACuint8_t ad5231_rdac_write_eemem(uint16_t rdac);//把RDAC写入EEMEM
uint8_t ad5231_restores_eemem_to_rdac(void);//把EEMEM恢复到RDACuint8_t ad5231_set_RwB(uint32_t r);//设置WB端电阻
uint8_t ad5231_set_RwA(uint32_t r);//设置WA端电阻#endif

这就是基本的驱动代码。

关于AD5231的一些问题点总结。

1.AD5231的总量程A-B端只有9kΩ,差了1k的阻值,有一点夸张。

我测得的0=88 Ω,1023时是8970 Ω。

2.SPI的速度降低一点,刚开始速度太快,读取RDAC时 返回数据错误。

3.需要连续命令时,中间需要一个延迟。

4.因为电阻值只有9k和数据测试差太多,所以就没使用数据手册的电阻和抽头的公式,需要自己写一个软件校准代码。可以使用wps做一个线性拟合。

//软件校准
static uint16_t ad5231_software_calibration_rdac(uint32_t r)
{double temp;temp = (double)r;if(r < AD5231_RWB_MIN){return 0;}else if(r > AD5231_RWB_MAX){return AD5231_SizeRDAC;}temp = ((temp -  88.193) / 8.6876);return (uint16_t)(temp+0.5);}uint8_t ad5231_set_RwB(uint32_t r)
{uint16_t rdac=0;if(r > AD5231_SizeR){r = AD5231_SizeR;}rdac = ad5231_software_calibration_rdac(r);return  ad5231_write_rdac(rdac);
}uint8_t ad5231_set_RwA(uint32_t r)
{uint16_t rdac=0;rdac = ad5231_software_calibration_rdac((AD5231_SizeR -r));return   ad5231_write_rdac(rdac);
}

这经过校准的代码。

通过按键设置输出1000,2000,3000电阻,经过电阻测量,还是挺准的。

硬件电路图

 

http://www.lryc.cn/news/597450.html

相关文章:

  • 【Elasticsearch】跨集群检索(Cross-Cluster Search)
  • 83、设置有人DTU设备USR-M100采集传感器数据,然后上传阿里云服务
  • now能减少mysql的压力吗
  • 旅游管理虚拟仿真实训室:重构实践教学新生态
  • 【数据库】国产数据库的新机遇:电科金仓以融合技术同步全球竞争
  • 云蝠智能 Voice Agent:重构企业语音交互,引领 AI 服务新范式
  • QGraphicsScene导出为PDF
  • SQL Server 数据类型的含义、特点及常见使用场景的详细说明
  • 【轨物洞见】光伏逆变器数据:分布式电站价值回归的“第一块多米诺骨牌”
  • Pycharm2025 安装教程 免费分享 没任何套路
  • PyCharm高效进阶指南:掌握专业开发技巧与最佳实践
  • Spring DeferredResult 实现长轮询
  • [HarmonyOS] HarmonyOS LiteOS-A 设备开发全流程指南
  • 清华大学层次化空间记忆助力具身导航!Mem4Nav:基于层次化空间认知长短期记忆系统的城市环境视觉语言导航
  • 本地部署 Stable Diffusion:零基础搭建 AI文生图模型
  • 仓颉兴趣组优秀项目-Ginger
  • CPU,减少晶体管翻转次数的编码
  • opencv学习(视频读取)
  • 策略模式(Strategy Pattern)+ 模板方法模式(Template Method Pattern)的组合使用
  • AR维修辅助系统UI设计:虚实融合界面中的故障标注与操作引导
  • 设计模式(单例)
  • ar景区导航导览开发方案:核心技术架构与功能设计
  • HarmonyOS学习记录5
  • 第三章.Redis渐进式遍历
  • 计算机毕设分享-基于SpringBoot的房屋租赁系统(开题报告+源码+Lun文+开发文档+数据库设计文档)
  • 神经架构搜索革命:从动态搜索到高性能LLM的蜕变之路
  • Spark实现WorldCount执行流程图
  • 05-ES6
  • Unity UI的未来之路:从UGUI到UI Toolkit的架构演进与特性剖析(2)
  • UE5多人MOBA+GAS 29、创建一个等级UI