外设驱动库开发笔记2:AD8400系列数字电位器驱动

一些时候我们需要在系统使用过程中改变某些电路电阻值以达到改变设定的目的,这时候我们就会使用电位器。在我们使用数字控制电路时多选择数字电位器。在这一篇我们就来设计AD8400系列数字电位器驱动

1、功能概述

AD8400/AD8402/AD8403分别是单通道/双通道/四通道、256位、数字控制可变电阻(VR)器件,可实现与机械电位计或可变电阻相同的电子调整功能。AD8400内置一个可变电阻,采用紧凑的SOIC-8封装。AD8402内置两个独立的可变电阻,采用节省空间的SOIC-14表面贴装封装。AD8403内置四个独立的可变电阻,提供24引脚PDIP、SOIC和TSSOP三种封装。各器件均内置一个带游标触点的固定电阻,该游标触点在载入控制串行输入寄存器的数字码所确定的数字码分接该固定电阻值。游标与固定电阻任一端点之间的电阻值,随传输至VR锁存器中的数字码呈线性变化。在A端与游标或B端与游标之间,各可变电阻提供一个完全可编程电阻值。A至B固定端接电阻(1 kΩ、10 kΩ、50 kΩ或100 kΩ)的通道间匹配容差为±1%,标称温度系数为500 ppm/°C。借助独特的开关电路,可将传统开关电阻设计中固有的高脉冲干扰降至最低,从而避免任何先合后开或先开后合操作。

 

每个VR均有各自的VR锁存器,用来保存其编程电阻值。这些VR锁存器由一个SPI兼容型串行至并行移位寄存器更新,该移位寄存器从一个标准三线式串行输入数字接口加载数据。由10个数据位构成的数据字传输至串行输入寄存器。

 

该数据字经过解码,前2位确定需要载入的VR锁存器地址,后8位是数据。利用串行寄存器相对端的串行数据输出引脚,就可以简单的菊花链形式将多个VR连接,而无需额外的外部解码逻辑。

复位(RS)引脚通过将80H载入VR锁存器来迫使游标移到中间电平。SHDN引脚则迫使A端的电阻变为端到端开路状态,并使游标与B端短路,从而实现毫瓦级功耗的关断状态。当SHDN回到逻辑高电平时,先前的锁存器设置将使游标处于关断前的电阻值设置。数字接口在关断期间仍有效,以便更改代码,当器件脱离关断状态时,游标将处于新的位置。

2、驱动设计与实现

我们已经了解了AD840x系列数字电位器的基本情况,接下来我们将基于此实现AD840x系列数字电位器的驱动。

2.1、对象定义

我们的的驱动设计都是基于对象的操作,所以我们先要抽象出AD840x系列数字电位器的对象类型。这是一个系列对象所以有不同的类型,每种类型又有不同的标称电阻值。这些都可以区别不同的对象,我们将其抽象为AD840x对象的属性。而对于操作则相对简单,我们只需要向AD840x对象写数据,所以将写数据作为它的操作。具体定义如下:

/* 定义AD840x类型枚举 */
typedef enum AD840x{
AD8400,
AD8402,
AD8403
}AD840xType;

/* 定义AD840x通道选择枚举 */
typedef enum AD840xLdac{
AD840x_VR1=0x00,
AD840x_VR2=0x01,
AD840x_VR3=0x02,
AD840x_VR4=0x03
}AD840xLdacType;

/* 定义AD840x标称电阻枚举 */
typedef enum AD840xNR{
AD840x_NR1k, //标称电阻为1K
AD840x_NR10k, //标称电阻为10K
AD840x_NR50k, //标称电阻为50K
AD840x_NR100k //标称电阻为100K
}AD840xNRType;

/* 定义AD840x对象类型 */
typedef struct AD840xObject{
AD840xType type; //AD840x对象类型
float nominalValue; //标称电阻值
void (*Write)(uint8_t rdac); //写数据操作函数指针
}AD840xObjectType;

有操作对象后,还需要对该对象变量作初始化才可使用,所以我们还需要定义一个初始化函数用于对象的初始化。AD840x对象的初始化函数如下:

/* 初始化AD840x对象 */
void AD840xInitialization(AD840xObjectType *vr,AD840xType type,AD840xWriteByte write,AD840xNRType nr)
{
float nValue[4]={1000,10000,50000,100000};

if((vr==NULL)||(write==NULL))
{
return;
}

vr->type=type;

vr->Write=write;

vr->nominalValue=nValue[nr];
}

2.2、对象操作

AD8400/AD8402/AD8403分别是单通道/双通道/四通道、256位、数字控制可变电阻(VR)器件。更改VR编程设置是通过将10位串行数据字送入SDI引脚来实现。此数据字由2个地址位(MSB优先)和8个数据位(也是MSB优先)组成。串行寄存器数据字格式如下:

AD840x的地址分配,由ADDR解码器解码,确定接收位B7至B0中的串行寄存器数据的VR锁存器的位置。位置的计算公式如下:

 

VR#=A1*2+A0+1

单通道AD8400要求A1 = A0 = 0。双通道AD8402要求A1 = 0。A1、A0的取值方式如下:

 

关于

AD840x对象设置游标的位置与电阻的关系:

 

根据上述两个公式,当我们需要某一阻值的电阻时,只需要设置响应的D值就看可以了。具体的操作函数如下:

/*设置AD8400游标的位置*/
void SetAD8400ResistorValue(AD840xObjectType *vr,uint16_t resistorValue,AD840xLdacType ldac)
{
  float mValue=0.0;
  uint16_t sendValue=0;
  uint8_t txData[2];
  
  if((resistorValue<50)||(resistorValue>vr->nominalValue))
  {
    return;
  }

  if((vr->type==AD8400)&&(ldac!=AD840x_VR1))
  {
    return;
  }

  if((vr->type==AD8402)&&(ldac>AD840x_VR2))
  {
    return;
  }

  mValue=((float)resistorValue-(float)RESISTANCEINITIAL)/(float)vr->nominalValue;
  sendValue=(uint8_t)(mValue*RESISTANCEINDEX);

  sendValue=sendValue||(ldac<<8);
  
  txData[0]=(sendValue>>2);
  txData[1]=(sendValue<<6);
  vr->Write(txData[0]);
  vr->Write(txData[1]);
}

第三个参数通道选择,如前面所述由A1、A0决定。对于AD8400是单通道,直接指定第一通道即可。而AD8402对应第一、第二通道。

3、驱动的使用

我们实现了AD840x系列数字电位器的驱动,接下来我们需要来讨论一下它的应用,及如何使用我们开发的驱动实现我们的应用。

3.1、声明并初始化对象

首先我们依然是需要声明AD840x对象变量。我们在驱动设计时已经定义了AD840xObjectType对象类型,所以我们就是用这个对象类型声明AD840x对象变量。具体操作如下:

AD840xObjectType ad840x;

对于定义的这一对象变量尚不能直接使用,必须先对其初始化。我们在驱动中也设计了初始化函数:void AD840xInitialization(AD840xObjectType *vr,AD840xType type,AD840xWriteByte write,AD840xNRType nr)。它的四个参数分别是:AD840x对象指针、AD840x的类型、写AD840x对象函数指针、AD840x的标称电阻值。

AD840x对象指针指向的就是我们所要初始化的对象变量。AD840x的类型就是源自AD840xType枚举。AD840x的标称电阻值则源自AD840xNRType枚举。关于写AD840x对象函数指针则是与具体硬件平台和接口相关的数据发送函数。在这里就是指SPI对口的数据发送函数。具体类型如下:

typedef void (*AD840xWriteByte)(uint8_t rdac);

如我们可声明为:void WriteAD8400bySPI(uint8_t rdac);

有了这些参数我们就可以使用初始化函数来初始化我们前面声明的对象变量了。具体形式如下:

AD840xInitialization(&ad840x, AD8400, WriteAD8400bySPI, AD840x_NR10k);

我们就将对象变量ad840x初始化为AD8400类型的标称电阻为10K的可变电阻对象,且向对象写数据的函数为WriteAD8400bySPI。

3.2、基于对象进行操作

我们声明并初始化完成对象变量后。就可以调用操作函数来实现我们想要对AD840x对象进行的操作了。使用电阻设置函数即可:

void SetAD8400ResistorValue(AD840xObjectType *vr,uint16_t resistorValue,AD840xLdacType ldac)

其3个参数,第一个是我们要操作的对象的指针;第二个是我们想要设置的电阻值;第三个参数是通道选择。

4、应用总结

我们已经实现了AD840x的驱动及应用。AD840x的应用并不复杂,我们只需要设定我们想要的电阻就可以了。在我们的应用中得到的结果与我们预期的完全一致。

在使用驱动时我们应该注意。AD8402与AD8403均为多通道的可变电阻。在使用时需要注意通道选择。通道选择由下发数据的A1、A0位决定。驱动中已定义为枚举,选择即可。

源码公布到GitHUB:https://github.com/foxclever/ExPeriphDriver

欢迎关注:

发布了79 篇原创文章 · 获赞 289 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/foxclever/article/details/104721129