本应用笔记介绍如何使用DS3900 PC串口转3线接口与DS1267、DS1867和DS1868三个数字电位器通信,DS3900、DS3223和DS232使用该移位寄存器接口进行编程。DS3是一个模块,具有MAX3900 RS-<>收发器和一个微处理器,微处理器充当PC串行端口与被控制的<>线器件之间的接口。收发器允许模块的微处理器与PC通信,微处理器通过其并行端口实现命令结构,以允许PC读取或写入三个数字电位计。应用笔记描述了DS<>以及如何将其连接到被测器件。本文中描述的源代码可在达拉斯半导体的FTP站点上找到。
介绍
DS1267、DS1867和DS1868均为数字电位器,采用独特的3线协议,很难与PC接口。本应用笔记提供了一个简单的硬件/软件解决方案,用于生成用于调整电位器设置的PC接口,以及用于读取和写入这些器件的示例C++算法。图1所示软件及其源代码可在ADI网站上找到。
图1.ADI公司的3线评估软件(DS3线.exe)。
硬件
为该应用生成的硬件利用DS3900与IC通信。DS3900是具有MAX3223 RS232收发器和微处理器的模块。收发器允许模块的微处理器与PC通信,微处理器实现命令结构,允许PC读取或写入模块上的任何I / O引脚。除DS3900和3线IC外,还应使用去耦电容来降低V上的噪声。抄送由DS3900和电位器的数字接口引起。图2所示为使用DS3和DS3900Wire应用与3线器件通信所需的连接。
图2.DS3Wire应用原理图
软件
图 1 所示的软件有三个主要例程;初始化DS3900和对话框(OnInitDialog),读取17位寄存器(OnRead),写入17位寄存器(OnWrite)。这些例程是使用名为“CdsPic”的C++类实现的。CdsPic包含子程序,允许使用预先编写和测试的RS232/DS3900代码来创建3线算法。DS3Wire应用中CdsPic类的实例称为“DS3900”。CdsPic类和RS232功能可在ADI网站上找到,任何感兴趣的人都可以使用。对于那些对DS3900实现的细节不感兴趣的人,函数名称足够通用,可以被视为伪代码。表 1 中列出了一些示例函数名称及其说明,以供参考。
例 | 描述 |
DS3900.主板礼物() |
如果在CdsPic类初始化代码期间检测到DS3900,则返回TRUE;如果未检测到DS3900,则返回FALSE。 |
DS3900.写入 1(真) |
引脚P1设置为输出并强制其高电平。如果在通信过程中未检测到错误,则返回 TRUE。 |
DS3900.写1(假) |
引脚P1设置为输出并强制其低电平。如果在通信过程中未检测到错误,则返回 TRUE。 |
DS3900.读取 1(状态) |
引脚 P1 设置为输入、读取,P1 的输入电平返回到布尔变量“状态”。如果在通信过程中未检测到错误,则返回 TRUE。 |
DS3900读取4(状态) | 引脚 P4 设置为输入、读取,P4 的输入电平返回到布尔变量“状态”。如果在通信过程中未检测到错误,则返回 TRUE。 |
3线基础知识
如果将这个特定版本的3线接口视为具有两个控制信号时钟(CLK)和移位使能(“/RST”)以及两个数据信号(数据输入(DQ)和数据输出(C外).当“/RST”为高电平时,接口未复位;因此,移位寄存器已启用。当“/RST”为高电平时,CLK上收到的任何正边沿都将导致移位寄存器将所有数据移位一个位置,将DQ的现值移动到第一个位置。这种转变也会改变C的值外,始终显示寄存器中第 17 位的当前值。一旦所有17位数据移入器件,复位信号就会调低,这将把新设置传输到控制电位计位置并禁用3线接口的寄存器。
该 C外PIN旨在提供在同一条3线总线上将多个3线器件级联在一起的能力,但它确实提供了对移位寄存器的读取访问。通过使能接口(将“/RST”设置为高电平)并将移位寄存器中的17位时钟设置为C来执行读取外一次可以读取一位。当“/RST”被停用时,移位寄存器中的值将是DQ在读取周期内写入器件的值,因为数据在移出时被移入器件。这需要将 DQ 重写为 C 的当前值外在每个时钟脉冲启动之前,否则读取操作将是破坏性的。破坏性读取操作将导致电位计在停用“/RST”时改变位置。
此接口有两个主要问题需要避免:
部分写入(移位小于 17 位)将产生移位寄存器垃圾,这是先前数据和新数据的产物。因此,如果不写入所有17位,就不可能改变一个电阻的值。
读取功能具有破坏性,除非移出移位寄存器的数据轮换回移位寄存器。
第一个问题很容易解决,不要执行部分写入。第二个问题可以解决两个 不同的方式。数据手册显示了使用反馈电阻(10kΩ)自动写入C值外到 DQ,除非 DQ 在写入周期内由输出驱动。虽然这可以用DS3900实现,但设计是用C语言实现的。外驱动单独的输入引脚。这演示了在无法使用反馈电阻时如何实现接口。微处理器(在本例中为DS3900)必须在固件/软件中执行反馈电阻的功能。在 C 上读取值时外,它将在3线器件时钟之前写入DQ。
无法使用反馈电阻的最常见情况是将3线器件连接至集电极开路I/O端口。集电极开路I/O引脚将具有一个上拉电阻,以输出高电压电平。该电阻将与反馈电阻争用。如果反馈电阻小于上拉电阻,则C外将始终写入 DQ,包括在写入周期期间,当目的是将新值写入设备时。如果反馈电阻大于上拉电阻,则在读取期间DQ将始终为高电平。
OnInitDialog
OnInitDialog是Windows调用的用于初始化对话框的函数。如果使用 Microsoft Developer Studio 生成对话框,则其中一个对话框构造选项会在代码中为程序员留下注释。这将在此函数的末尾留下一个“TODO”注释,说明在此处放置额外的初始化代码。
本例中添加了以下代码,以确保DS3900正确上电,将CLK和“/RST”设置为低电平,并使用电位器的当前位置初始化编辑框。如果未检测到DS3900,则会显示一条错误消息通知用户。
// TODO: Add extra initialization here <-Developer Studio Comments if(DS3900.BoardPresent()) // <- BoardPresent() checks for DS3900 { // <-If found path m_sEDIT_Status= "DS3900 Found!"; // new status message, all systems go DS3900.Write1(false); // initialize clock DS3900.Write2(false); // initialize reset OnRead(); // read pots and update edit boxes } else { // <-If not found path m_sEDIT_Status = "DS3900 not found!@#$"; // new status message, error detect UpdateData(FALSE); // Update Dialog Values MessageBox("DS3900 Not Found Check Power and Serial Cable Restart Applicaion","DS3900 Error"); }
图3.向 OnInitDialog 函数添加了额外的初始化代码
读取时
OnRead 函数读取 17 位移位寄存器。它在按下读取按钮时和 OnInitDialog 期间执行。该算法假设 C外引脚连接到单独的DS3900输入,如图2所示。这需要软件写入在 C 上读取的值外在3线器件时钟之前到DQ,或者在读取操作期间无意中调整电位计。图 4 显示了应用程序使用的算法。除了读取 17 位之外,它还将数据重建为表示 Pot0、Pot1 和堆栈选择位的变量,并使用 UpdateData(FALSE) 函数更新对话框。每次从PC到DS3900的传输都会被监控错误,任何对通信的干扰都将导致交易终止并显示错误信息。如果未发生错误,则会向状态框写入“读取成功”消息。此功能大约需要 95 毫秒才能执行,但结果可能会因所用 PC 的速度而异。
void OnRead() { //Variables used by subroutine int success; bool bit; unsigned char mask=0x80; unsigned char pot0=0; unsigned char pot1=0; if(DS3900.BoardPresent()) // Only Read if DS3900 found { success = DS3900.Write2(true); // Pull reset high if(success) // Abort Read if comm fail. { success += DS3900.Read5(bit); // Read Cout (stack bit first) success += DS3900.Write4(bit); // Copy Read Contents to DQ success += DS3900.Write1(true); // Clock bit success += DS3900.Write1(false); // Clock bit m_RADIO_Stack = bit; // <-Update Dialog Box Variable if(success == 5) // Abort Read if comm fail. { for(int x = 0; x <8 ; x++) // Pot 1 Read Loop { success += DS3900.Read5(bit); // Read Cout (stack bit first) success += DS3900.Write4(bit); // Copy Read Contents to DQ success += DS3900.Write1(true); // Clock bit success += DS3900.Write1(false); // Clock bit if(bit) // If bit set, set bit in Pot variable pot1 |= mask; mask = mask >> 1; // Adjust Mask for next pass } m_ucEDIT_Pot1 = pot1; // <-Update Dialog Box Variable mask=0x80; // Reset Mask for(int y = 0; y <8 ; y++) // Pot 0 Read Loop { success += DS3900.Read5(bit); // Read Cout (stack bit first) success += DS3900.Write4(bit); // Copy Read Contents to DQ success += DS3900.Write1(true); // Clock bit success += DS3900.Write1(false); // Clock bit if(bit) // If bit set, set bit in Pot variable pot0 |= mask; mask = mask >> 1; // Adjust Mask for next pass } m_ucEDIT_Pot0 = pot0; // <-Update Dialog Box Variable } } success += DS3900.Write2(false); // Pull reset low if(success == 70) // Determine if comm has failed m_sEDIT_Status = "Successful Read"; // Success Message else m_sEDIT_Status = "Read Failed"; // Fail Message } UpdateData(FALSE); // <-Triggers Dialog Box Update }
图4.读取功能
请注意,读取算法的最后一个 if 语句更新对话框的状态消息。如果DS3900初始化成功,则在显示对话框之前,将用“成功读取”覆盖初始化的“找到DS3900!”消息。
写入时
OnWrite 函数读取用户在对话框中键入的值,并将其写入 3 线器件。若要读取对话框值,将调用 UpdateData(TRUE) 函数。除了读取数据外,UpdateData(TRUE) 还将 ASCII 字符串转换为电位计寄存器的无符号字符,以及堆栈选择位单选按钮的整数值。这些值自动存储在m_ucEDIT_Pot0、m_ucEDIT_Pot1和m_RADIO_Stack变量中。读取新的所需设置后,写入算法指示DS3900一次发送一位17位数据。
在写入过程中,与DS3900的通信被监测错误,“成功”变量保持成功数据传输次数的运行总数。如果DS3900的每次读/写操作都成功,程序将更新状态框,使其显示为“写入成功”;否则,它将中止命令并返回错误消息。该函数执行大约需要 70 毫秒,如图 5 所示。
void OnWrite() { UpdateData(TRUE); //Read values of Dialog Box //variables used by subroutine int success; unsigned char mask = 0x80; unsigned char pot0 = m_ucEDIT_Pot0; unsigned char pot1 = m_ucEDIT_Pot1; bool bit = false; if(m_RADIO_Stack) // place stack select bit into "bit" variable. bit = true; if(DS3900.BoardPresent()) // Only Write if DS3900 Found { success = DS3900.Write2(true); // Pull reset high if(success) // Write abortion if comm. fail { success += DS3900.Write4(bit); // write stack select bit success += DS3900.Write1(true); // Clock bit success += DS3900.Write1(false); // Clock bit if(success == 4) // Write abortion if comm. fail { for(int x = 0; x <8 ; x++) // Loop for 8 bits of pot 1 { if(pot1 & mask) // Read next DQ value with mask success += DS3900.Write4(true); else success += DS3900.Write4(false); success += DS3900.Write1(true); // Clock bit success += DS3900.Write1(false); // Clock bit mask = mask >> 1; // Adjust mask to next position } mask = 0x80; // Reset mask for(int y = 0; y <8 ; y++) // Loop for 8 bits of pot 0 { if(pot0 & mask) // Read next DQ value with mask success += DS3900.Write4(true); else success += DS3900.Write4(false); success += DS3900.Write1(true); // Clock bit success += DS3900.Write1(false); // Clock bit mask = mask >> 1; // Adjust mask to next position. } } } success += DS3900.Write2(false); // Pull reset low } if(success == 53) // Comm. Pass/Fail notification. m_sEDIT_Status = "Successful Write"; // Pass Message else m_sEDIT_Status = "Write Failed"; // Fail Message UpdateData(FALSE); // <-Trigger Dialog Update }
图5.写入函数
结论
本应用笔记提供了一种简单的C++算法,用于使用DS3对包含17位移位寄存器的3900线器件进行读写。写入操作大约需要 70ms,不使用反馈电阻的读取操作大约需要 95ms 才能执行。虽然相对于3线接口的最大数据速率而言,这并不快,但足以评估电位计。
审核编辑:郭婷
全部0条评论
快来发表一下你的评论吧 !