久久久91-久久久91精品国产一区二区-久久久91精品国产一区二区三区-久久久999国产精品-久久久999久久久精品

最新廣告
關(guān)注中國(guó)自動(dòng)化產(chǎn)業(yè)發(fā)展的先行者!
工業(yè)智能邊緣計(jì)算2025年會(huì)
CAIAC 2025
2025工業(yè)安全大會(huì)
OICT公益講堂
當(dāng)前位置:首頁(yè) >> 案例 >> 案例首頁(yè)

案例頻道

Windows CE環(huán)境下與單片機(jī)串行通信的實(shí)現(xiàn)
  • 企業(yè):     領(lǐng)域:電源    
  • 點(diǎn)擊數(shù):2331     發(fā)布時(shí)間:2005-08-23 11:42:01
  • 分享到:
本文介紹了在Windows CE環(huán)境下與單片機(jī)基于多線程的串行通信的實(shí)現(xiàn)問(wèn)題。深入研究了Windows CE中對(duì)基于多線程的串口通信的各項(xiàng)設(shè)置和數(shù)據(jù)接收中一些關(guān)鍵問(wèn)題,并提出了AT89C52單片機(jī)的串口通信中波特率正確設(shè)定的方法,特別適用于傳輸?shù)臄?shù)據(jù)量較大且傳輸速度較高的情況。



1. 引言

    隨著科技的發(fā)展,軟硬件資源的成熟和完善,嵌入式系統(tǒng)在現(xiàn)代工業(yè)控制領(lǐng)域中得到了越來(lái)越廣泛的應(yīng)用,其應(yīng)用領(lǐng)域涉及通信、自動(dòng)化、信息家電、軍事等各個(gè)方面。而嵌入式操作系統(tǒng)的引入大大提高了嵌入式系統(tǒng)的功能,方便了嵌入式應(yīng)用軟件的設(shè)計(jì)。
    Windows CE是微軟公司開發(fā)的一種嵌入式實(shí)時(shí)操作系統(tǒng),它是一種模塊化的、實(shí)時(shí)的、有強(qiáng)大的通信功能的、搶先式、多任務(wù)具有強(qiáng)大通信功能的32位嵌入式操作系統(tǒng)。
    在嵌入式系統(tǒng)的實(shí)現(xiàn)中一般都會(huì)涉及數(shù)據(jù)的采集和處理,因此數(shù)據(jù)的通信成了系統(tǒng)穩(wěn)定可靠運(yùn)行的關(guān)鍵。串行通信是計(jì)算機(jī)與外部設(shè)備交換信息的重要途徑,由于其實(shí)現(xiàn)簡(jiǎn)單,節(jié)省I/O口和線路,傳輸時(shí)序明晰等特點(diǎn),應(yīng)用的非常普遍,同樣在嵌入式系統(tǒng)中它也是一種主要的通信方式。在本文中研究的是基于Windows CE操作系統(tǒng)的掌上電腦和單片機(jī)之間的串行通信問(wèn)題。

2. 系統(tǒng)結(jié)構(gòu)和Windows CE簡(jiǎn)介

    本文介紹的是一種基于掌上電腦的便攜式動(dòng)態(tài)心電信號(hào)采集及處理系統(tǒng),主要討論系統(tǒng)串行通信的設(shè)計(jì)和實(shí)現(xiàn)。整個(gè)系統(tǒng)由檢測(cè)模塊和掌上電腦兩部分組成。其中,檢測(cè)模塊是由AT89C52單片機(jī)控制的智能模塊,負(fù)責(zé)心電信號(hào)的檢測(cè)、放大、濾波與采集;掌上電腦負(fù)責(zé)參數(shù)的設(shè)置,心電波形數(shù)據(jù)存儲(chǔ)、處理、分析以及波形顯示等;掌上電腦基于Windows CE操作系統(tǒng)。圖1為整個(gè)系統(tǒng)的功能框圖,檢測(cè)模塊與掌上電腦之間通過(guò)RS232接口實(shí)現(xiàn)通信,而掌上電腦通過(guò)RS232或USB接口和PC機(jī)進(jìn)行數(shù)據(jù)通信,由PC機(jī)對(duì)數(shù)據(jù)進(jìn)行深入的分析和處理。整個(gè)系統(tǒng)的實(shí)現(xiàn)中,數(shù)據(jù)的串行通信是最基本也是最重要的部分。由于掌上電腦和PC機(jī)之間的通信由商家提供專門的接口線以及驅(qū)程,因此我們?cè)谶@不作具體的研究。
    Windows CE作為一種嵌入式操作系統(tǒng),它的很多特性都是為了適應(yīng)嵌入式系統(tǒng)的特殊要求,它與一般的Windows程序有很多區(qū)別,如API函數(shù),存儲(chǔ)器的限制,電源管理方式,硬件特性等等。但是在通信方面Windows CE基本擁有和Windows同樣的Win32 API,因?yàn)檫\(yùn)行Windows CE的系統(tǒng)或者是移動(dòng)的,或者需要與遠(yuǎn)程服務(wù)器進(jìn)行連接,因此必須具有強(qiáng)大的通信功能。Windows CE下的應(yīng)用程序是通過(guò)文件I/O函數(shù)CreateFile,ReadFile,WriteFile,CloseHandle訪問(wèn)設(shè)備驅(qū)動(dòng)程序的,對(duì)文件進(jìn)行操作時(shí),在Windows CE下的設(shè)備不支持重疊I/O。



圖1  系統(tǒng)整體結(jié)構(gòu)概略圖



3. Windows CE下基于多線程的串行通信實(shí)現(xiàn)

    什么是使用多線程的好時(shí)機(jī)呢?如果你的程序有許多事要忙,但是你還要隨時(shí)保持注意某些外部事件(可能來(lái)自硬件或來(lái)自使用者),這時(shí)就適合使用多線程來(lái)幫忙。以通信程序?yàn)槔憧梢宰屩骶€程負(fù)責(zé)使用者界面,并保持中樞的地位,而以―個(gè)分離的線程處理通信端口,這樣就可以在串口讀寫數(shù)據(jù)的同時(shí)保持使用者界面依然靈活,不受影響。本文就是采用這種多線程的方法來(lái)實(shí)現(xiàn)串行通信的,創(chuàng)建了單獨(dú)的讀和寫線程來(lái)處理串口讀寫數(shù)據(jù)。
    Windows CE下的串行設(shè)備被視為用于打開、關(guān)閉、讀和寫串行端口的常規(guī)、可安裝的流設(shè)備。這里我們構(gòu)造一個(gè)串口類CSerial來(lái)對(duì)Win32 API串口操作函數(shù)CreateFile,ReadFile,WriteFile,CloseHandle等進(jìn)行封裝,并在其中完成對(duì)串口的各項(xiàng)設(shè)置。在本系統(tǒng)中主要時(shí)在Windows CE環(huán)境中接收單片機(jī)上傳的大量數(shù)據(jù),因此我們將對(duì)數(shù)據(jù)的接收作比較詳細(xì)的分析。

1) 串口的打開和配置
    在類CSerial中用BOOL Open( int nPort, int nBaud)來(lái)完成串口的打開和初始化工作。先調(diào)用CreateFile打開指定的串口,然后通過(guò)GetCommState和SetCommState函數(shù)來(lái)配置串口,最后設(shè)置串口讀寫數(shù)據(jù)的超時(shí)值。
    配置串口時(shí)一般先調(diào)用GetCommState得到默認(rèn)的DCB結(jié)構(gòu),然后根據(jù)自己的需要來(lái)對(duì)它作必要的修改,再用SetCommState來(lái)重新配置串口。DCB結(jié)構(gòu)包括波特率、流控制、傳輸模式、起始位、停止位、校驗(yàn)等設(shè)置。需要注意的是Win32操作系統(tǒng)一般只支持二進(jìn)制的傳輸模式,因此fBinary字段應(yīng)設(shè)為TRUE,另外接收緩沖器應(yīng)該盡量設(shè)的大一些。
    下面具體研究一下讀寫數(shù)據(jù)的超時(shí)值,通過(guò)GetCommTimeouts和SetCommTimeouts對(duì)COMMTIMEOUTS結(jié)構(gòu)的5個(gè)字段進(jìn)行設(shè)置。通常在實(shí)現(xiàn)串口通信時(shí)往往不重視甚至忽略對(duì)讀寫數(shù)據(jù)超時(shí)值的設(shè)置,這樣可能就會(huì)造成串口數(shù)據(jù)讀寫的不可靠性,特別是在接收大量數(shù)據(jù)時(shí),如果超時(shí)值的設(shè)置不合適將會(huì)使數(shù)據(jù)不能完全接收過(guò)來(lái)而導(dǎo)致通信出錯(cuò)。在本系統(tǒng)中如下設(shè)置串口超時(shí)值。
    COMMTIMEOUTS CommTimeOuts;
CommTimeOuts.ReadIntervalTimeout =10; 
    CommTimeOuts.ReadTotalTimeoutMultiplier =10; 
    CommTimeOuts.ReadTotalTimeoutConstant = 10;   
    CommTimeOuts.WriteTotalTimeoutMultiplier = 5; 
    CommTimeOuts.WriteTotalTimeoutConstant = 5; 
    其中ReadIntervalTimeout設(shè)置串口相鄰字節(jié)接收間隔時(shí)間的最大值,單位為毫秒。如果前后兩個(gè)字節(jié)之間的間隔時(shí)間超過(guò)該設(shè)定值,ReadFile就返回,終止接收。ReadTotalTimeoutMultiplier用來(lái)計(jì)算 ReadFile函數(shù)的總超時(shí),單位為毫秒。每次讀取串口操作,將其與要接收字節(jié)數(shù)相乘再與ReadTotalTimeoutConstant相加來(lái)計(jì)算 ReadFile函數(shù)的總超時(shí)時(shí)間。寫操作兩個(gè)字段的設(shè)置與讀操作類似。
    當(dāng)波特率較高時(shí),ReadIntervalTimeout不能設(shè)的太大,否則兩次接收將會(huì)當(dāng)作一次處理,通信將出現(xiàn)錯(cuò)誤。而對(duì)于后兩者,由于 ReadFile當(dāng)總超時(shí)時(shí)間到時(shí)要立刻返回,因此要綜合考慮波特率、應(yīng)接收字節(jié)數(shù)等因素,以期串口的正確運(yùn)行。很多人在實(shí)現(xiàn)串行通信時(shí)簡(jiǎn)單的將ReadIntervalTimeout設(shè)置為MAXDWORD, ReadTotalTimeoutMultiplier和ReadTotalTimeoutConstant設(shè)為0,這種做法在進(jìn)行大量數(shù)據(jù)傳輸中并不適用,可能會(huì)導(dǎo)致數(shù)據(jù)的丟失。也不能在設(shè)置了適當(dāng)?shù)淖止?jié)間超時(shí)后就簡(jiǎn)單的把總超時(shí)設(shè)為0以期待直到所有數(shù)據(jù)讀完后ReadFile才返回,這樣可能會(huì)使ReadFile一直處于等待狀態(tài),不能正常返回。

2) 數(shù)據(jù)的接收

數(shù)據(jù)的接收我們用DWORD ReadData(char *data,CString FileName)函數(shù)來(lái)完成,如下所示。
DWORD CSerial::ReadData( char *data,CString FileName)
{
 char Byte[1000];
    DWORD dwComStatus,dwBytesTransferred;
    DWORD len=0;
    CFile ECGFile;
 ECGFile.Open(FileName,CFile::modeCreate|CFile::modeWrite);
 SetCommMask (m_hComID, EV_RXCHAR | EV_CTS | EV_DSR);
 if (m_hComID!= INVALID_HANDLE_VALUE)
 {
  WaitCommEvent (m_hComID, &dwComStatus, 0);
     if (dwComStatus & EV_RXCHAR)
  {
   do
   {
    ReadFile (m_hComID,
     &Byte,
       1000,
     &dwBytesTransferred,
     0
     );
    if (dwBytesTransferred)
    {
//     strncat(data,Byte,dwBytesTransferred); //接收數(shù)據(jù)較少時(shí)
strncpy(data,Byte,dwBytesTransferred); //接收數(shù)據(jù)較多時(shí)
     len+=dwBytesTransferred;
     g_nCount=len;
  ECGFile.Write(Byte,dwBytesTransferred);
                    ECGFile.Flush();                  
    }
   }
   while (dwBytesTransferred);
  }  
 }
 ECGFile.Close();  
 return len;
}
    該函數(shù)的調(diào)用是在一個(gè)單獨(dú)的線程函數(shù)ReadThread中,我們創(chuàng)建一個(gè)單獨(dú)的線程來(lái)讀串口數(shù)據(jù),用如下的語(yǔ)句來(lái)創(chuàng)建該讀線程。
    hReadThread = CreateThread (NULL,0,(LPTHREAD_START_ROUTINE)ReadThread, this, 0, &dwThreadID))
    在ReadData函數(shù)中先使用SetCommMask設(shè)置事件掩碼,然后WaitCommEvent就阻塞線程,直到“串口接收到一個(gè)字符”的預(yù)定事件發(fā)生線程才繼續(xù)執(zhí)行。

在用ReadFile函數(shù)讀數(shù)據(jù)是要注意以下3點(diǎn):
    a) 接收緩沖區(qū)Byte的大小最好和ReadFile中第3個(gè)參數(shù)(即要讀取的字節(jié)數(shù))一致。
    b) 緩沖區(qū)Byte的大小要根據(jù)實(shí)際情況來(lái)設(shè)置,當(dāng)要接收的數(shù)據(jù)比較多,波特率又設(shè)的較高時(shí)應(yīng)盡量將緩沖區(qū)設(shè)的大些,否則可能會(huì)使數(shù)據(jù)丟失。
    c) ReadFile中的第四個(gè)參數(shù)是實(shí)際接收到的字節(jié)數(shù),由于通信中常常不可預(yù)料的會(huì)發(fā)生各種異常情況,每次實(shí)際接收到的字節(jié)數(shù)未必和你希望接收的數(shù)量一致,所以當(dāng)每次從接收緩沖區(qū)中取數(shù)據(jù)時(shí)應(yīng)以dwBytesTransferred的值為準(zhǔn),這樣可以避免將不是串口得到的數(shù)據(jù)也錯(cuò)誤的取進(jìn)來(lái)。
    當(dāng)接收的數(shù)據(jù)量大時(shí)我們不得不考慮到Windows CE系統(tǒng)的內(nèi)存限制問(wèn)題,那么有限的內(nèi)存根本無(wú)法將那么多的數(shù)據(jù)同時(shí)放在內(nèi)存中。實(shí)際情況確實(shí)也是這樣的,在實(shí)驗(yàn)中每次當(dāng)串口接收的數(shù)據(jù)多達(dá)幾十K時(shí),往往會(huì)發(fā)生堆棧溢出等異常。于是我們考慮將每次ReadFile接收到的數(shù)據(jù)讀進(jìn)內(nèi)存后就將它永久存儲(chǔ)到對(duì)象存儲(chǔ)器中,當(dāng)然也可以是自備的存儲(chǔ)卡,就像上面給出的程序,我們用MFC中的CFile類來(lái)完成文件的存儲(chǔ)功能。ReadData函數(shù)的第2個(gè)參數(shù)傳入的就是存儲(chǔ)文件的路徑和名字。這樣每次只要消耗固定量的內(nèi)存,解決了內(nèi)存的問(wèn)題。當(dāng)然,如果在實(shí)際中需要從串口接收的數(shù)據(jù)不是很多時(shí),為了方便數(shù)據(jù)的處理,我們通常還是把它們都放在內(nèi)存中。

3) 數(shù)據(jù)的發(fā)送
    主要是在函數(shù)SendData中調(diào)用了API函數(shù)WriteFile,本系統(tǒng)中只需向單片機(jī)發(fā)送一些參數(shù)的設(shè)置和簡(jiǎn)單的控制指令,應(yīng)用相對(duì)比較簡(jiǎn)單。我們也創(chuàng)建一個(gè)單獨(dú)的線程來(lái)寫數(shù)據(jù)到串口,對(duì)SendData函數(shù)的調(diào)用在線程函數(shù)SendThread中,創(chuàng)建寫線程的方法和讀線程類似。

4) 串口的關(guān)閉
    串口的關(guān)閉是最簡(jiǎn)單的,只需使用CloseHandle函數(shù)就可以了。

4. AT89C52單片機(jī)的串行通信

    智能采集部分我們采用的是AT89C52單片機(jī),采用中斷的方式來(lái)與掌上電腦進(jìn)行數(shù)據(jù)通信。我們?cè)O(shè)定單片機(jī)的串口控制寄存器SCON=0x50 ,使串口工作在方式1(即10位異步收發(fā)方式),在這種方式下,串行口的波特率是可編程的,由所使用的定時(shí)器的溢出率決定。AT89C52除了有定時(shí)器0和1外,還增加了定時(shí)器2,定時(shí)器2是一個(gè)16位定時(shí)/計(jì)數(shù)器,其控制和狀態(tài)位位于T2CON和T2MOD,寄存器對(duì)RCAP2H,RCAP2L是定時(shí)器2在16位自動(dòng)重裝載方式下的自動(dòng)重裝載寄存器。
    在單片機(jī)的串行通信中波特率的設(shè)定是最關(guān)鍵的工作,它決定了通信的速度和成敗。波特率最終是由單片機(jī)的主機(jī)頻率和定時(shí)器的工作方式?jīng)Q定的。通常情況下,單片機(jī)的晶振頻率一般選用12M或24M等整數(shù),采用定時(shí)器1來(lái)作為波特率發(fā)生器,因?yàn)?1系列的單片機(jī)沒有定時(shí)器2。這樣就會(huì)出現(xiàn)問(wèn)題,大家經(jīng)常會(huì)發(fā)現(xiàn)當(dāng)設(shè)置波特率較高時(shí)串口接收的數(shù)據(jù)就會(huì)發(fā)生錯(cuò)誤。經(jīng)過(guò)了一段時(shí)間的研究,我們找到了原因,當(dāng)采用T1作為自動(dòng)重裝初值的8位計(jì)數(shù)器來(lái)產(chǎn)生波特率時(shí),由于單片機(jī)晶振是12M或24M,T1的計(jì)數(shù)頻率是1/12的單片機(jī)主頻,根據(jù)T1的溢出率計(jì)算得出的定時(shí)器初值不夠精確,會(huì)產(chǎn)生一定的誤差,而且誤差隨著所設(shè)波特率的提高而增加。這時(shí)的波特率計(jì)算公式如下:

波特率=

其中fosc是單片機(jī)主頻,當(dāng)SMOD=1時(shí),波特率加倍。
有如下2個(gè)方法可以解決這個(gè)問(wèn)題:
    1) 調(diào)整單片機(jī)的主頻,可以選用11.0592M,22.1184M等來(lái)消除波特率設(shè)置的誤差。
    2) 采用具有16位定時(shí)/計(jì)數(shù)器T2的單片機(jī),如AT89C52。這時(shí)使用T2的16位自動(dòng)重裝初      值的工作方式來(lái)產(chǎn)生波特率,在串口工作在工作方式1時(shí),波特率的計(jì)算公式如下:
      波特率=        
    由于T2的初值是16位的,且這種工作方式下T2的計(jì)數(shù)頻率是1/2的單片機(jī)主頻,按照上述公式計(jì)算得到的定時(shí)器初值的精度足以實(shí)現(xiàn)我們所需的波特率。
    根據(jù)上面的分析,我們采用第2個(gè)方案,設(shè)置T2CON=0x34,使T2工作于波特率發(fā)生器方式,通過(guò)TH2,TL2設(shè)置定時(shí)器初值,在該方式下寄存器RCAP2H和RCAP2L中的值應(yīng)與TH2和TL2中相同,以便在T2溢出時(shí),將RCAP2H和RCAP2L中的初值自動(dòng)重裝到TH2和TL2中。
具體的單片機(jī)串口設(shè)置如下:
  SCON=0x50;              //串口工作在方式1
         TH2=0xff;              
         TL2=0xd9;               //設(shè)置波特率為19200
         RCAP2H=0xff;   
         RCAP2L=0xd9;
         T2MOD=0x00;
         T2CON=0x34;             //T2工作工作于波特率發(fā)生器方式
         IE=0x90;                //開串口中斷

5  總結(jié)

    本文介紹了在Windows CE環(huán)境下與單片機(jī)的基于多線程的串行通信的實(shí)現(xiàn)問(wèn)題。深入研究了Windows CE中對(duì)基于多線程的串口通信的各項(xiàng)設(shè)置和數(shù)據(jù)接收中應(yīng)注意的地方,并提出了AT89C52單片機(jī)的串口通信中波特率正確設(shè)定的方法,特別適用于傳輸?shù)臄?shù)據(jù)量較大且波特率較高的情況。在實(shí)際工作中,我們利用基于Windows CE的系統(tǒng),通過(guò)RS-232C標(biāo)準(zhǔn)接口,與使用單片機(jī)的采集模塊進(jìn)行大量數(shù)據(jù)通信,采用文中介紹的方法,實(shí)現(xiàn)了準(zhǔn)確、可靠的數(shù)據(jù)傳輸。

熱點(diǎn)新聞

推薦產(chǎn)品

x
  • 在線反饋
1.我有以下需求:



2.詳細(xì)的需求:
姓名:
單位:
電話:
郵件:
主站蜘蛛池模板: 欧美三级黄色| 精品视频在线看| 麻豆国产96在线 | 日韩| 国产精品亚洲第一区二区三区| 久久天天综合| 污91视频| 国产成人精品美女在线| 国产日韩在线视频| 狠狠色丁香久久综合五月| 欧美aaaa在线观看视频免费| 亚洲黄色在线看| 亚洲国产精品专区| 91福利国产在线观看| 91啦中文成人| 久久国产精品自在自线| 国精品一区二区三区| 护士一级aaaaaa毛片| 人交性视频大全| www视频在线免费观看| 嫩草视频在线观看视频播放| 黄色网址在线免费播放| 免费观看欧美性一级| 三个黑人强一个女人视频| 欧美一区二区久久精品| 美国黄色网| 亚洲欧美日韩中文高清ww| 亚洲美女爱做色禁图无遮| 国产色啪午夜免费视频| 国产一级特黄aa级特黄裸毛片| 成人深夜福利在线播放不卡| 手机视频在线观看| 天天草综合网| 特级aa一级欧美毛片| 亚洲在线久久| 日韩国产第一页| 国产高清色播视频免费看| 毛片日韩| 女女互添下身免费视频| 国产欧美日韩另类一区乌克兰 | 性网站视频| 日韩福利在线视频|