使用装有DS3900的PC与DS1267、DS1867和DS1868通信

描述

本应用笔记介绍如何使用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线接口的最大数据速率而言,这并不快,但足以评估电位计。

审核编辑:郭婷

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分