当前位置: 首页 > 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.dtcms.com/a/294347.html

相关文章:

  • GoLang学习笔记
  • Qt 菜单与工具栏设计:提升用户体验
  • stm32使用USB虚拟串口,因电脑缺少官方驱动而识别失败(全系列32单片机可用)
  • Git下载全攻略
  • 状压Dp和记忆化搜索
  • k8s怎么找deploy历史版本?
  • UDP通信是否需要使用bind,connect,send等函数
  • 如何高效合并音视频文件
  • iview+Tree 在数据中添加selected和expand属性默认展开后点不动问题
  • 【数据结构】——时间与空间复杂度深度解析
  • MATLAB近红外光谱分析:MATLAB编程+BP神经网络+SVM+随机森林+遗传算法+变量降维+卷积神经网络等
  • 云蝠智能 Voice Agent:重构企业语音交互,引领 AI 服务新范式
  • 《Spring Bean生命周期全景图解:从实例化到销毁》
  • 增强LLM最后隐藏层的意义与效果
  • 文本溢出时显示省略号,并在鼠标移入文本时显示 tooltip全内容
  • Taint Bug (污点漏洞):
  • 【bug】websocket协议不兼容导致的一个奇怪问题
  • 垃圾回收介绍
  • jenkins 入门指南:从安装到启动的完整教程
  • Selenium是解决了什么问题的技术?
  • web安全 | docker复杂环境下的内网打点
  • Docker 启动 PostgreSQL 主从架构:实现数据同步的高效部署指南
  • VRRP的概念及应用场景
  • 彩色转灰度的核心逻辑:三种经典方法及原理对比
  • 优雅!通过编程方式重启 Spring Boot 应用的 3 种方案
  • Apache PDFBox深入实践
  • python学智能算法(二十九)|SVM-拉格朗日函数求解中-KKT条件
  • PHP语法高级篇(五):回调函数与异常处理
  • Ansible 变量指南:声明、优先级、作用域与最佳实践(一)
  • Jquery、Vue 、Ajax、axios、Fetch区别