关键词数字电位器 I2C总线 单片机 程序模块
1引言
随着I2C总线应用的日益广泛,兼容I2C总线的接口芯片及存储器的品种也越来越多,其中数字电位器以其调节方便、使用寿命长、受物理环境的影响小、性能稳定等特点,已被广大电子工程技术人员所认识;尤其是在音频产品、控制领域等的应用越来越受到人们的重视。I2C总线数字电位器是美国Xicor公司推出的X9×××系列数字电位器中较有代表性的一种。它是把几个E2POT非易失性数字电位器集成在一起的单片CMOS微电路,具有二线串行I2C总线接口,易于软件控制,可直接读出、写入滑动端位置,可级联使用等先进特性。本文以X9241为例说明。
2结构原理 X9241内部包括一个I2C接口和四个数字电位器。每个数字电位器由电阻阵列及与之对应的滑动端计数寄存器WCR、四个8位数据寄存器R0~R3等部分构成。其引脚配置如图1所示。 2.1电阻阵列 每个电阻阵列由63个串联连接的分立的电阻段组成。每个电阻阵列的物理终端等效于机械电位器的固定端(VH和VL输入端)。每个阵列的VH和VL以及每个电阻段之间的接点(即抽头)通过FET开关连接滑动输出端VW;而滑动端VW在电阻阵列中的位置由WCR控制。 | 图1X9241引脚配置图 | 其中VW0、VW1、VW2及VW3分别为四个电位器的滑动端;VL0、VL1、VL2及VL3分别为四个电位器的低端;VH0、VH1、VH2及VH3分别为四个电位器的高端;A0、A1、A2及A3为地址线(用来设置从属地址低4位);SDA及SCL分别为串行数据和串行时钟;VCC及VSS分别为电源和地 |
如果将四个电阻阵列中的两个、三个或四个串联起来可构成127、190或253个抽头的数字电位器。
X9241电位器电阻阵列的阻值种类根据后缀的不同而不同。当分别为Y、W、U时,则电阻阵列分别为四个2kΩ、四个10kΩ、四个50kΩ的数字电位器;而当为M时,其内部四个数字电位器阻值分别为2kΩ、10kΩ、10kΩ、50kΩ。
2.2滑动端计数寄存器WCR
滑动端计数寄存器WCR实际上是一个6位带有译码输出的计数器,用来实现选择六十四选一的FET开关的位置,即控制滑动端在电阻阵列中的位置。WCR是一种易失性存贮器,其内容可通过指令改写,上电时装入数据寄存器R0的内容(注意:此值可能与断电时的值不同)。
2.3数据寄存器
数据寄存器的内容可由用户读出或写入,其内容可传输到滑动计数寄存器WCR以设置滑动端的位置。每个数字电位器有四个8位非易失性数据寄存器R0~R3。
2.4串行接口
X9241支持I2C串行双向总线的定向规约:实际应用时X9241为从器件,由主机启动数据的传输,并为发送和接收操作提供时钟。数据线SDA和时钟线SCL的信号间关系(起始条件、终止条件及应答条件)见图2。
3器件寻址及指令结构
3.1器件寻址
在起始后,主器件输出它所要访问的从器件地址,该地址的格式如下:
0 | 1 | 0 | 1 | A3 | A2 | A1 | A0 |
对于X9241来说,这个地址的高4位固定为:0101,低4位由物理的器件地址A0~A3输入端状态决定。这样,X9241把串行数据流与地址输入端的状态进行比较,若所有位都比较成功,则该器件在总线上作出一个应答响应。
3.2指令结构
主器件在发送完起始条件及器件地址,且从器件作出应答之后,送到X9241的下一个字节包括指令及寄存器指针的信息。其格式如下:
I3 | I2 | I1 | I0 | P1 | P0 | R1 | R0 |
其中低4位中前两位(R0和R1)指出四个寄存器中的一个,后两位(P0和P1)选择四个电位器中的哪一个;高4位决定指令,X9241共有9条指令见表1。
表1X9241指令
指令 | I3 | I2 | I1 | I0 | P1 | P0 | R1 | R0 | 功能说明 |
Read WCR | 1 | 0 | 0 | 1 | 1/0 | 1/0 | × | × | 读P1、P0指定的滑动端计数寄存器内容 |
Write WCR | 1 | 0 | 1 | 0 | 1/0 | 1/0 | × | × | 写新值到P1、P0指定的滑动端计数寄存器中 |
Read Data Register | 1 | 0 | 1 | 1 | 1/0 | 1/0 | 1/0 | 1/0 | 读P1、P0和R1、R0指定的寄存器内容 |
Write Data Register | 1 | 1 | 0 | 0 | 1/0 | 1/0 | 1/0 | 1/0 | 写新值到P1、P0和R1、R0指定的寄存器中 |
XFT Data Register to WCR | 1 | 1 | 0 | 1 | 1/0 | 1/0 | 1/0 | 1/0 | 传输由P1、P0和R1、R0指定的寄存器内容到与它相关的WCR中 |
XFT WCRto Data Register | 1 | 1 | 1 | 0 | 1/0 | 1/0 | 1/0 | 1/0 | 传输由P1、P0指定的WCR的内容到R1、R0指定的寄存器中 |
Global XFT Data Register to WCR | 0 | 0 | 0 | 1 | × | × | 1/0 | 1/0 | 传输由R1、R0指定的所有四个数据寄存器的内容到与它们相应的WCR中 |
Global XFT WCRto Data Register | 1 | 0 | 0 | 0 | × | × | 1/0 | 1/0 | 传输所有WCR中的内容到与它们相应的由R1、R0指定的数据寄存器中 |
Increment /Decrement Wiper | 0 | 0 | 1 | 0 | 1/0 | 1/0 | × | × | 使能增加/减少由P1、P0指定的滑动端计数寄存器(WCR)的内容 |
9条指令中包括四条两字节指令,四条三字节指令和一条增加/减少指令。
(1)两字节指令:这四条两字节指令用作在WCR与数据寄存器中的一个之间交换数据;这种传输可以发生在四个电位器之一与它们的一个辅助寄存器之间,或全局性地发生在所有四个电位器与它们的一个辅助寄存器之间;操作时序见图2(a)。
(2)三字节指令:这四条指令是在主机和X9241之间传输数据,无论是主机与一个数据寄存器或是主机直接与WCR间都可以;这些指令是读、写WCR(即读出、写入选定电位器的当前滑动端的位置)或读、写数据寄存器(即读出、写入选定的非易失性寄存器的内容);操作时序见图2(b)。
(3)增加/减少指令:这条指令与其它的指令不同,一旦这条指令发出且X9241已用一个应答来响应后,主机才能够以时钟来触发选定的滑动端升或降一个电阻段;这个操作的命令时序见图2(c)。
4电位器的串联方式及控制
X9241提供一个把阵列串联起来的机构,可以把一个阵列的六十三个电阻元件与一个相邻阵列的电阻元件串联起来,其控制位在三字节的指令中。对于三字节的指令,其数据字节包括用来定义滑动端位置的6位(LSB)加上高2位:CM(串联方式Caseade Mode)和DW(禁止滑动端Disable Wipe)。CM位的状态用来使能或禁止串联方式;当WCR的CM位被置为“0”时,则电位器是正常工作方式;当CM位置“1”,则与它相邻的高序号的电位器串联连接。例如电位器WCR1的位7被置为“1”,则POT1与POT2被串联使用。DW位的状态用于使能或禁止滑动端,当WCR的DW位被置为“0”(或“1”)时,则滑动端被使能(或被禁止),禁止时该滑动端是电气上隔离并且是浮空的,当工作于串联方式时,被串联阵列的VH、VL及滑动端VW这三个输出端必须在电气上与外部连接,除了一个滑动端被使能以外,其余的滑动端必须被禁止。用户可以通过改变WCR的内容来改变滑动端的位置。
5与GMS90/97系列单片机的接口 图3是X9241与GMS90/97系列单片微机之间的一种有代表性的连接,笔者曾将该连接方法成功地用于音频系统和智能仪表中,作为增益反馈电阻,这样可在宽范围内由软件编程来调整放大器的增益。在实际应用系统设计中,采用I2C总线数字电位器可以收到降低成本、简化电路的效果;然而在数字电位器带来硬件设计简化的同时,却增加了软件的工作量,原因是对其访问需要一套严格而复杂的操作;假如有了接口程序模块,使用I2C总线数字电位器就很方便了。为此,本文给出笔者已成功应用的I2C总线数字电位器与GMS90/97系列单片机的接口程序模块,读者几乎不需改动就可采用;该程序模块略加修改还可用于串行E2PROM的读写。 | 图3GMS90/97系列单片机与X9241的典型连接 |
E2POT驱动程序模块
RW9241: | SCL | BIT | P1.4 |
SDA | BIT | P1.5 | |
INCDEC | BIT | 02H | |
;滑动端的增减位 | |||
DEVICE | DATA | 50H |
;器件地址 |
COMMAND | EQU | 30H | |
;命令字节 | |||
RD_DATA | EQU | 31H | |
;读出的数据 |
WR_DATA | EQU | 32H | |
;写入的数据 | |||
ACALL | START_IC | ||
;置开始 |
MOV | A,#DEVICE | ||
ACALL | WR_BYTE | ||
;写器件地址 | |||
MOV | A,COMMAND |
;根据命令及识别字散转 | |||
SWAP | A | ||
ANL | A,#0FH | ||
CJNE | A,#09H,XRW1 |
;指令的高4位为09H表示R_WCR |
AJMP | R_WCR | ||||
XRW1: | CJNE | A,#0AH,XRW2 | |||
;指令的高4位为0AH表示W_WCR | |||||
AJMP | W_WCR | ||||
XRW2: | CJNE | A,#0BH,XRW3 | |||
;指令的高4位为0BH表示R_ROM(读寄存器) | |||||
AJMP | R_ROM | ||||
XRW3: | CJNE | A,#0CH,XRW4 | |||
;指令的高4位为0CH表示W_ROM(写寄存器) | |||||
AJMP | W_ROM | ||||
XRW4: | CJNE | A,#0DH,XRW5 | |||
;指令的高4位为0DH表示将寄存器中的值传送到WCR | |||||
AJMP | ROM_WCR | ||||
XRW5: | CJNE | A,#0EH,XRW6 |
;指令的高4位为0EH表示将WCR中的值传送到寄存器 | |||||
AJMP | WCR_ROM | ||||
XRW6: | CJNE | A,#01H,XRW7 | |||
;指令的高4位为01H表示全局寄存器中值传送到WCR | |||||
AJMP | A_ROM_WCR | ||||
XRW7: | CJNE | A,#08H,XRW8 | |||
;指令的高4位为08H表示全局WCR中值传送到寄存器 | |||||
AJMP | A_WCR_ROM | ||||
XRW8: | CJNE | A,#02H,XRW9 | |||
;指令的高4位为02H表示指定的WCR增/减 | |||||
AJMP | INC_DEC | ||||
XRW9: | ACALL | STOP_IC |
;命令执行完毕,STOP并返回 |
RETI | ||||
R_WCR: | MOV | A,COMMAND |
;读WCR子程序 | |||
ACALL | WR_BYTE | ||
ACALL | RD_BYTE | ||
MOV | RD_DATA,A | ||
ACALL | ACK_IC |
AJMP | XRW9 | ||
W_WCR: | MOV | A,COMMAND |
;写WCR子程序 | |||||
ACALL | WR_BYTE | ||||
MOV | A,WR_DATA | ||||
ACALL | WR_BYTE | ||||
AJMP | XRW9 | ||||
R_ROM: | MOV | A,COMMAND |
;读寄存器子程序 | |||||
ACALL | WR_BYTE | ||||
ACALL | RD_BYTE | ||||
MOV | RD_DATA,A | ||||
ACALL | ACK_IC | ||||
AJMP | XRW9 | ||||
W_ROM: | MOV | A,COMMAND | |||
;写寄存器子程序 | |||||
ACALL | WR_BYTE | ||||
MOV | A,WR_DATA | ||||
ACALL | WR_BYTE | ||||
AJMP | XRW9 | ||||
ROM_WCR: | MOV | A,COMMAND | |||
;寄存器中数据送WCR子程序 | |||||
ACALL | WR_BYTE | ||||
AJMP | XRW9 | ||||
WCR_ROM: | MOV | A,COMMAND | |||
;WCR中数据送寄存器子程序 | |||||
CALL | WR_BYTE | ||||
AJMP | XRW9 | ||||
A_ROM_WCR: | MOV | A,COMMAND | |||
;全局寄存器中数据送WCR子程序 | |||||
ACALL | WR_BYTE | ||||
AJMP | XRW9 | ||||
A_WCR_ROM: | MOV | A,COMMAND | |||
;全局WCR中数据送寄存器子程序 | |||||
ACALL | WR_BYTE | ||||
AJMP | XRW9 | ||||
INC_DEC: | MOV | R7,#63 | |||
MOV | A,COMMAND | ||||
;指定的WCR增/减子程序 | |||||
ACALL | WR_BYTE | ||||
JB | INCDEC,WCRINC | ||||
CLR | SDA | ||||
SETB | SCL | ||||
JMP | IDC | ||||
WCRINC: | CLR | SCL | |||
SETB | SDA | ||||
IDC: | CLR | SCL | |||
SETB | SCL | ||||
DJNZ | R7,IDC | ||||
AJMP | XRW9 | ||||
START_IC:SETB | SDA | ||||
;开始子程序 | |||||
SETB | SCL | ||||
CLR | SDA | ||||
CLR | SCL | ||||
RET | |||||
WR_BYTE:MOV | B,#08 | ||||
;写字节子程序,共写8位 | |||||
WR_BYTE1:CLR | SCL | ||||
RLC | A | ||||
;向左移位至CY | |||||
MOV | SDA,C | ||||
;数据输出 | |||||
SETB | SCL | ||||
DJNZ | B,WR_BYTE1 | ||||
CLR | SCL | ||||
SETB | SDA | ||||
SETB | SCL | ||||
JB | SDA,$ | ||||
;检测X9241E的应答 | |||||
CLR | SCL | ||||
RET | |||||
RD_BYTE: | MOV | B,#08 | |||
;读字节子程序,共读8位 | |||||
RD_BYTE1: | SETB | SCL | |||
MOV | C,SDA | ||||
RLC | A | ||||
CLR | SCL | ||||
DJNZ | B,RD_BYTE1 | ||||
RET | |||||
STOP_IC: | CLR | SDA | |||
;停止子程序 | |||||
SETB | SCL | ||||
SETB | SDA | ||||
CLR | SCL | ||||
CLR | SDA | ||||
RET | |||||
ACK_IC: | CLR | SDA | |||
;应答子程序 | |||||
SETB | SCL | ||||
CLR | SCL | ||||
RET |