本應(yīng)用筆記介紹如何使用DS3900 PC串口轉(zhuǎn)3線接口與DS1267、DS1867和DS1868三個(gè)數(shù)字電位器通信,DS3900、DS3223和DS232使用該移位寄存器接口進(jìn)行編程。DS3是一個(gè)模塊,具有MAX3900 RS-<>收發(fā)器和一個(gè)微處理器,微處理器充當(dāng)PC串行端口與被控制的<>線器件之間的接口。收發(fā)器允許模塊的微處理器與PC通信,微處理器通過(guò)其并行端口實(shí)現(xiàn)命令結(jié)構(gòu),以允許PC讀取或?qū)懭肴齻€(gè)數(shù)字電位計(jì)。應(yīng)用筆記描述了DS<>以及如何將其連接到被測(cè)器件。本文中描述的源代碼可在達(dá)拉斯半導(dǎo)體的FTP站點(diǎn)上找到。
介紹
DS1267、DS1867和DS1868均為數(shù)字電位器,采用獨(dú)特的3線協(xié)議,很難與PC接口。本應(yīng)用筆記提供了一個(gè)簡(jiǎn)單的硬件/軟件解決方案,用于生成用于調(diào)整電位器設(shè)置的PC接口,以及用于讀取和寫(xiě)入這些器件的示例C++算法。圖1所示軟件及其源代碼可在ADI網(wǎng)站上找到。
圖1.ADI公司的3線評(píng)估軟件(DS3線.exe)。
硬件
為該應(yīng)用生成的硬件利用DS3900與IC通信。DS3900是具有MAX3223 RS232收發(fā)器和微處理器的模塊。收發(fā)器允許模塊的微處理器與PC通信,微處理器實(shí)現(xiàn)命令結(jié)構(gòu),允許PC讀取或?qū)懭肽K上的任何I / O引腳。除DS3900和3線IC外,還應(yīng)使用去耦電容來(lái)降低V上的噪聲。抄送由DS3900和電位器的數(shù)字接口引起。圖2所示為使用DS3和DS3900Wire應(yīng)用與3線器件通信所需的連接。
圖2.DS3Wire應(yīng)用原理圖
軟件
圖 1 所示的軟件有三個(gè)主要例程;初始化DS3900和對(duì)話(huà)框(OnInitDialog),讀取17位寄存器(OnRead),寫(xiě)入17位寄存器(OnWrite)。這些例程是使用名為“CdsPic”的C++類(lèi)實(shí)現(xiàn)的。CdsPic包含子程序,允許使用預(yù)先編寫(xiě)和測(cè)試的RS232/DS3900代碼來(lái)創(chuàng)建3線算法。DS3Wire應(yīng)用中CdsPic類(lèi)的實(shí)例稱(chēng)為“DS3900”。CdsPic類(lèi)和RS232功能可在ADI網(wǎng)站上找到,任何感興趣的人都可以使用。對(duì)于那些對(duì)DS3900實(shí)現(xiàn)的細(xì)節(jié)不感興趣的人,函數(shù)名稱(chēng)足夠通用,可以被視為偽代碼。表 1 中列出了一些示例函數(shù)名稱(chēng)及其說(shuō)明,以供參考。
例 | 描述 |
DS3900.主板禮物() |
如果在CdsPic類(lèi)初始化代碼期間檢測(cè)到DS3900,則返回TRUE;如果未檢測(cè)到DS3900,則返回FALSE。 |
DS3900.寫(xiě)入 1(真) |
引腳P1設(shè)置為輸出并強(qiáng)制其高電平。如果在通信過(guò)程中未檢測(cè)到錯(cuò)誤,則返回 TRUE。 |
DS3900.寫(xiě)1(假) |
引腳P1設(shè)置為輸出并強(qiáng)制其低電平。如果在通信過(guò)程中未檢測(cè)到錯(cuò)誤,則返回 TRUE。 |
DS3900.讀取 1(狀態(tài)) |
引腳 P1 設(shè)置為輸入、讀取,P1 的輸入電平返回到布爾變量“狀態(tài)”。如果在通信過(guò)程中未檢測(cè)到錯(cuò)誤,則返回 TRUE。 |
DS3900讀取4(狀態(tài)) | 引腳 P4 設(shè)置為輸入、讀取,P4 的輸入電平返回到布爾變量“狀態(tài)”。如果在通信過(guò)程中未檢測(cè)到錯(cuò)誤,則返回 TRUE。 |
3線基礎(chǔ)知識(shí)
如果將這個(gè)特定版本的3線接口視為具有兩個(gè)控制信號(hào)時(shí)鐘(CLK)和移位使能(“/RST”)以及兩個(gè)數(shù)據(jù)信號(hào)(數(shù)據(jù)輸入(DQ)和數(shù)據(jù)輸出(C外).當(dāng)“/RST”為高電平時(shí),接口未復(fù)位;因此,移位寄存器已啟用。當(dāng)“/RST”為高電平時(shí),CLK上收到的任何正邊沿都將導(dǎo)致移位寄存器將所有數(shù)據(jù)移位一個(gè)位置,將DQ的現(xiàn)值移動(dòng)到第一個(gè)位置。這種轉(zhuǎn)變也會(huì)改變C的值外,始終顯示寄存器中第 17 位的當(dāng)前值。一旦所有17位數(shù)據(jù)移入器件,復(fù)位信號(hào)就會(huì)調(diào)低,這將把新設(shè)置傳輸?shù)娇刂齐娢挥?jì)位置并禁用3線接口的寄存器。
該 C外PIN旨在提供在同一條3線總線上將多個(gè)3線器件級(jí)聯(lián)在一起的能力,但它確實(shí)提供了對(duì)移位寄存器的讀取訪問(wèn)。通過(guò)使能接口(將“/RST”設(shè)置為高電平)并將移位寄存器中的17位時(shí)鐘設(shè)置為C來(lái)執(zhí)行讀取外一次可以讀取一位。當(dāng)“/RST”被停用時(shí),移位寄存器中的值將是DQ在讀取周期內(nèi)寫(xiě)入器件的值,因?yàn)閿?shù)據(jù)在移出時(shí)被移入器件。這需要將 DQ 重寫(xiě)為 C 的當(dāng)前值外在每個(gè)時(shí)鐘脈沖啟動(dòng)之前,否則讀取操作將是破壞性的。破壞性讀取操作將導(dǎo)致電位計(jì)在停用“/RST”時(shí)改變位置。
此接口有兩個(gè)主要問(wèn)題需要避免:
部分寫(xiě)入(移位小于 17 位)將產(chǎn)生移位寄存器垃圾,這是先前數(shù)據(jù)和新數(shù)據(jù)的產(chǎn)物。因此,如果不寫(xiě)入所有17位,就不可能改變一個(gè)電阻的值。
讀取功能具有破壞性,除非移出移位寄存器的數(shù)據(jù)輪換回移位寄存器。
第一個(gè)問(wèn)題很容易解決,不要執(zhí)行部分寫(xiě)入。第二個(gè)問(wèn)題可以解決兩個(gè) 不同的方式。數(shù)據(jù)手冊(cè)顯示了使用反饋電阻(10kΩ)自動(dòng)寫(xiě)入C值外到 DQ,除非 DQ 在寫(xiě)入周期內(nèi)由輸出驅(qū)動(dòng)。雖然這可以用DS3900實(shí)現(xiàn),但設(shè)計(jì)是用C語(yǔ)言實(shí)現(xiàn)的。外驅(qū)動(dòng)單獨(dú)的輸入引腳。這演示了在無(wú)法使用反饋電阻時(shí)如何實(shí)現(xiàn)接口。微處理器(在本例中為DS3900)必須在固件/軟件中執(zhí)行反饋電阻的功能。在 C 上讀取值時(shí)外,它將在3線器件時(shí)鐘之前寫(xiě)入DQ。
無(wú)法使用反饋電阻的最常見(jiàn)情況是將3線器件連接至集電極開(kāi)路I/O端口。集電極開(kāi)路I/O引腳將具有一個(gè)上拉電阻,以輸出高電壓電平。該電阻將與反饋電阻爭(zhēng)用。如果反饋電阻小于上拉電阻,則C外將始終寫(xiě)入 DQ,包括在寫(xiě)入周期期間,當(dāng)目的是將新值寫(xiě)入設(shè)備時(shí)。如果反饋電阻大于上拉電阻,則在讀取期間DQ將始終為高電平。
OnInitDialog
OnInitDialog是Windows調(diào)用的用于初始化對(duì)話(huà)框的函數(shù)。如果使用 Microsoft Developer Studio 生成對(duì)話(huà)框,則其中一個(gè)對(duì)話(huà)框構(gòu)造選項(xiàng)會(huì)在代碼中為程序員留下注釋。這將在此函數(shù)的末尾留下一個(gè)“TODO”注釋?zhuān)f(shuō)明在此處放置額外的初始化代碼。
本例中添加了以下代碼,以確保DS3900正確上電,將CLK和“/RST”設(shè)置為低電平,并使用電位器的當(dāng)前位置初始化編輯框。如果未檢測(cè)到DS3900,則會(huì)顯示一條錯(cuò)誤消息通知用戶(hù)。
// 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 函數(shù)添加了額外的初始化代碼
讀取時(shí)
OnRead 函數(shù)讀取 17 位移位寄存器。它在按下讀取按鈕時(shí)和 OnInitDialog 期間執(zhí)行。該算法假設(shè) C外引腳連接到單獨(dú)的DS3900輸入,如圖2所示。這需要軟件寫(xiě)入在 C 上讀取的值外在3線器件時(shí)鐘之前到DQ,或者在讀取操作期間無(wú)意中調(diào)整電位計(jì)。圖 4 顯示了應(yīng)用程序使用的算法。除了讀取 17 位之外,它還將數(shù)據(jù)重建為表示 Pot0、Pot1 和堆棧選擇位的變量,并使用 UpdateData(FALSE) 函數(shù)更新對(duì)話(huà)框。每次從PC到DS3900的傳輸都會(huì)被監(jiān)控錯(cuò)誤,任何對(duì)通信的干擾都將導(dǎo)致交易終止并顯示錯(cuò)誤信息。如果未發(fā)生錯(cuò)誤,則會(huì)向狀態(tài)框?qū)懭搿白x取成功”消息。此功能大約需要 95 毫秒才能執(zhí)行,但結(jié)果可能會(huì)因所用 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.讀取功能
請(qǐng)注意,讀取算法的最后一個(gè) if 語(yǔ)句更新對(duì)話(huà)框的狀態(tài)消息。如果DS3900初始化成功,則在顯示對(duì)話(huà)框之前,將用“成功讀取”覆蓋初始化的“找到DS3900!”消息。
寫(xiě)入時(shí)
OnWrite 函數(shù)讀取用戶(hù)在對(duì)話(huà)框中鍵入的值,并將其寫(xiě)入 3 線器件。若要讀取對(duì)話(huà)框值,將調(diào)用 UpdateData(TRUE) 函數(shù)。除了讀取數(shù)據(jù)外,UpdateData(TRUE) 還將 ASCII 字符串轉(zhuǎn)換為電位計(jì)寄存器的無(wú)符號(hào)字符,以及堆棧選擇位單選按鈕的整數(shù)值。這些值自動(dòng)存儲(chǔ)在m_ucEDIT_Pot0、m_ucEDIT_Pot1和m_RADIO_Stack變量中。讀取新的所需設(shè)置后,寫(xiě)入算法指示DS3900一次發(fā)送一位17位數(shù)據(jù)。
在寫(xiě)入過(guò)程中,與DS3900的通信被監(jiān)測(cè)錯(cuò)誤,“成功”變量保持成功數(shù)據(jù)傳輸次數(shù)的運(yùn)行總數(shù)。如果DS3900的每次讀/寫(xiě)操作都成功,程序?qū)⒏聽(tīng)顟B(tài)框,使其顯示為“寫(xiě)入成功”;否則,它將中止命令并返回錯(cuò)誤消息。該函數(shù)執(zhí)行大約需要 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.寫(xiě)入函數(shù)
結(jié)論
本應(yīng)用筆記提供了一種簡(jiǎn)單的C++算法,用于使用DS3對(duì)包含17位移位寄存器的3900線器件進(jìn)行讀寫(xiě)。寫(xiě)入操作大約需要 70ms,不使用反饋電阻的讀取操作大約需要 95ms 才能執(zhí)行。雖然相對(duì)于3線接口的最大數(shù)據(jù)速率而言,這并不快,但足以評(píng)估電位計(jì)。
審核編輯:郭婷
-
收發(fā)器
+關(guān)注
關(guān)注
10文章
3424瀏覽量
105959 -
寄存器
+關(guān)注
關(guān)注
31文章
5336瀏覽量
120228 -
電位器
+關(guān)注
關(guān)注
14文章
1012瀏覽量
66765
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論