freepeople性欧美熟妇, 色戒完整版无删减158分钟hd, 无码精品国产vα在线观看DVD, 丰满少妇伦精品无码专区在线观看,艾栗栗与纹身男宾馆3p50分钟,国产AV片在线观看,黑人与美女高潮,18岁女RAPPERDISSSUBS,国产手机在机看影片

正文內(nèi)容

多串口多線(xiàn)程的數(shù)據(jù)管理系統(tǒng)的設(shè)計(jì)畢業(yè)論文(編輯修改稿)

2025-07-23 11:18 本頁(yè)面
 

【文章內(nèi)容簡(jiǎn)介】 程序中的線(xiàn)程有兩種類(lèi)型。一種是工作線(xiàn)程,它不處理窗口消息,常用于后臺(tái)執(zhí)行任務(wù)。另一種是用戶(hù)接口線(xiàn)程,主要用來(lái)處理用戶(hù)輸入和響應(yīng)由用戶(hù)產(chǎn)生的消息與事件。 本系統(tǒng)編寫(xiě)的工作線(xiàn)程用于后臺(tái)的數(shù)據(jù)采集和通信。微軟基本類(lèi)庫(kù)(MicrosoftFoundation Class-MFC)為多線(xiàn)程提供了三個(gè)全局函數(shù)AfxBeginThread(),AfxEndThread()和 AfxGetThread()對(duì)線(xiàn)程進(jìn)行操作,分別用來(lái)創(chuàng)建工作線(xiàn)程,結(jié)束工作線(xiàn)程,獲得當(dāng)前線(xiàn)程的指針。因?yàn)橥贿M(jìn)程的所有線(xiàn)程共享進(jìn)程的虛擬地址空間,進(jìn)程中的線(xiàn)程是并行執(zhí)行的,每個(gè)線(xiàn)程占用 CPU 的時(shí)間由系統(tǒng)來(lái)劃分。系統(tǒng)為每一個(gè)線(xiàn)程分配一個(gè) CPU 時(shí)間片,某個(gè)線(xiàn)程只有在分配的時(shí)間片內(nèi)才有對(duì) CPU 的控制權(quán)。實(shí)際上,在 PC 機(jī)中,同一時(shí)間只有一個(gè)線(xiàn)程在運(yùn)行,系統(tǒng)不停地在各個(gè)線(xiàn)程之間切換,而且線(xiàn)程是匯編級(jí)中斷,所以有可能實(shí)現(xiàn)多個(gè)線(xiàn)程同時(shí)訪(fǎng)問(wèn)同一個(gè)對(duì)象的情況。這些對(duì)象可以是全局變量,MFC 的對(duì)象,也可以是 MFC的 API 等等。而串口通信對(duì)每個(gè)串口對(duì)象只提供一個(gè)緩沖區(qū),即發(fā)送接收都要用到這一個(gè)緩沖區(qū),如果一個(gè)線(xiàn)程在未完成對(duì)某一大尺寸全局變量的讀操作時(shí),另一個(gè)線(xiàn)程又對(duì)該變量進(jìn)行了寫(xiě)操作,那么第一個(gè)線(xiàn)程讀入的變量值可能是一種修改過(guò)程中的不穩(wěn)定值。所以必須建立同步線(xiàn)程,使得一個(gè)時(shí)刻只能進(jìn)行一種線(xiàn)程操作,一個(gè)線(xiàn)程必須等待另一線(xiàn)程結(jié)束才能開(kāi)始。在處理一個(gè)線(xiàn)程的同時(shí)必須把其余待處理的線(xiàn)程掛起等待,以減少待處理線(xiàn)程對(duì) CPU 的資源占用。正處理的線(xiàn)程一旦處理結(jié)束,則通過(guò)線(xiàn)程間的通信發(fā)出信號(hào)來(lái)?yè)艋畋粧炱鸬木€(xiàn)程中的一個(gè)線(xiàn)程進(jìn)入處理。這樣才能達(dá)到協(xié)調(diào)運(yùn)行多個(gè)線(xiàn)程的目的。VC++提供了多種同步對(duì)象來(lái)協(xié)調(diào)實(shí)現(xiàn)多線(xiàn)程的并行,Csemaphore 信號(hào)燈對(duì)象,Cmutex 互斥量對(duì)象,Cevent 事件對(duì)象,以及CcriticalSection 臨界區(qū)對(duì)象都可以做到這一點(diǎn)。以臨界區(qū)對(duì)象為例,進(jìn)程負(fù)責(zé)為臨界區(qū)對(duì)象分配內(nèi)存空間,臨界區(qū)對(duì)象實(shí)際上是一個(gè) CRITICAL_SECTION 型的變量,它一次只能被一個(gè)線(xiàn)程擁有。在線(xiàn)程使用臨界區(qū)對(duì)象之前,必須調(diào)用 InitializeCriticalSection 函數(shù)將其初始化。如果線(xiàn)程中有一段關(guān)鍵的代碼不希望被別的線(xiàn)程中斷,那么可以調(diào)用 EnterCriticalSection 函數(shù)來(lái)申請(qǐng)關(guān)鍵節(jié)的所有權(quán),在運(yùn)行完關(guān)鍵代碼后再用 LeaveCriticalSection函數(shù)來(lái)釋放所有權(quán)。如果在調(diào)用EnterCriticalSection 時(shí)關(guān)鍵節(jié)對(duì)象已被另一個(gè)線(xiàn)程擁有,那么該函數(shù)將無(wú)限期等待所有權(quán)。具體實(shí)現(xiàn)代碼為:UINT WaitStation1Event(LPVOID lpParameter){ …………… while(1){ if(lpSerialComm1m_bStation1Exit) AfxEndThread(TRUE)。 //接到 1 號(hào)站停止標(biāo)志,停止線(xiàn)程 ReadMask=0。 ReadNum=0。 WaitCommEvent(lpSerialComm1m_hCOM,amp。ReadMask,amp。os)。 //等待串口通信事件的發(fā)生 ,檢測(cè)返回的 dwEvtMask,知道發(fā)生了什么串口事件 Event = WaitForMultipleObjects(2, lpSerialComm1m_hEventArray, FALSE, INFINITE)。 //m_hEventArray[0]為讀事件,m_hEventArray[1]為寫(xiě)事件 switch(Event){ case 0: {//read event if(ReadMask amp。 EV_RXCHAR == EV_RXCHAR){ Sleep(600)。 COMSTAT ComStat。 DWORD dwLength。 DWORD dwErrorFlags。 EnterCriticalSection(amp。lpSerialComm1m_csCommunicationSync)。 ClearCommError(lpSerialComm1m_hCOM,amp。dwErrorFlags, amp。ComStat)。 LeaveCriticalSection(amp。lpSerialComm1m_csCommunicationSync)。 dwLength = 。 //輸入緩沖區(qū)有多少數(shù)據(jù)? if (dwLength 0) { EnterCriticalSection(amp。lpSerialComm1m_csCommunicationSync)。 BOOL fReadStat 。 fReadStat = ReadFile(lpSerialComm1m_hCOM, lpSerialComm1m_COMInput, dwLength, amp。ReadNum, amp。os)。 //讀數(shù)據(jù) if (!fReadStat) {/*查詢(xún)錯(cuò)誤信息*/ } LeaveCriticalSection(amp。lpSerialComm1m_csCommunicationSync)。 if(!lpSerialComm1m_bStation1Exit) { //調(diào)用數(shù)據(jù)處理函數(shù) ::SendMessage(m_hStation1Wnd,WM_COM_EVENT,1,NULL)。 } } } break。 } case 1: {//write eventlpSerialComm1SendOutChar(lpSerialComm1nOutChar,lpSerialComm1m_numbyte)。 break。 } } } return TRUE。 }3.2. 1 上位機(jī)的串口通信該過(guò)程采用 P J Naughter 提供的串口通信類(lèi)實(shí)現(xiàn), 并在其基礎(chǔ)上針對(duì) modem通信擴(kuò)展了撥號(hào)、掛斷等功能。通信協(xié)議參照標(biāo)準(zhǔn)遠(yuǎn)動(dòng)規(guī)約,報(bào)文內(nèi)容以字節(jié)為單位,結(jié)構(gòu)如圖 3所示。其中報(bào)文類(lèi)型用來(lái)說(shuō)明報(bào)文的類(lèi)型和功能, 數(shù)據(jù)長(zhǎng)度用來(lái)說(shuō)明數(shù)據(jù)區(qū)的字節(jié)數(shù),8 位校驗(yàn)碼為累加和校驗(yàn)。用戶(hù)界面對(duì)話(huà)框與命令響應(yīng):進(jìn)行通信和數(shù)據(jù)抄錄的用戶(hù)界面,首先處理界面上用戶(hù)選擇的需要通信和控制的下位機(jī),并用如下指令啟動(dòng)通信主線(xiàn)程: AfxBeginThread(ThreadMainCommunication,GetSafeHwnd())。 報(bào)文格式 圖3報(bào)文格式 如果多個(gè)串口都采用查詢(xún)方式進(jìn)行輸入 ,則可以在一個(gè)通信線(xiàn)程中完成通信任務(wù)。但是 ,如果每個(gè)串口都采用中斷方式進(jìn)行輸入 ,或有的串口采查詢(xún)方式而有的串口采用中斷方式 ,則一個(gè)線(xiàn)程很難滿(mǎn)足通信要求 ,應(yīng)當(dāng)采用多個(gè)通信線(xiàn)程來(lái)滿(mǎn)足各串口的通信要求。因?yàn)槿绻捎猛粋€(gè)線(xiàn)程進(jìn)行多個(gè)串口的通訊 ,則一旦某個(gè)采用中斷方式輸入的串口通信中斷 ,則該通信線(xiàn)程將掛起 ,無(wú)法進(jìn)行其它串口的通信。所以 ,如果某個(gè)串口采用中斷方式進(jìn)行輸入 ,則該串口的通信應(yīng)當(dāng)采用一個(gè)專(zhuān)用線(xiàn)程。理論上 ,每個(gè)串口都有自己的數(shù)據(jù)發(fā)送、 接收緩沖區(qū) ,數(shù)據(jù)的發(fā)送、 接收都是由硬件獨(dú)立自動(dòng)完成的。因此 ,每個(gè)串口都可以利用一個(gè)線(xiàn)程進(jìn)行數(shù)據(jù)的發(fā)送和接收。但是 ,如果線(xiàn)程太多,必然增大線(xiàn)程管理 (包括線(xiàn)程同步 )和共享數(shù)據(jù)互斥訪(fǎng)問(wèn)的難度。所以 ,原則上講 ,能在一個(gè)線(xiàn)程內(nèi)順序執(zhí)行的任務(wù)最好都安排在一個(gè)線(xiàn)程中 ,只有需要進(jìn)行優(yōu)先級(jí)調(diào)度控制或并行執(zhí)行的任務(wù)才采用多個(gè)線(xiàn)程。3.2.2 通信主線(xiàn)程(ThreadMainCommunication)通信主線(xiàn)程的主要功能是對(duì)各個(gè)通信子線(xiàn)程進(jìn)行調(diào)度和管理。在通信主線(xiàn)程中首先根據(jù)可用的串口數(shù)定義一個(gè)信號(hào)量變量。如下所示,其中變量m__usable為可用的串口個(gè)數(shù)。 S_num=CreateSemaphore(NULL,m__usable,m__usable,NULL)。 然后再用下面的語(yǔ)句為每個(gè)可用的串口創(chuàng)建一個(gè)對(duì)應(yīng)的子通信線(xiàn)程,主要代碼如下所示: for(ii=0。ii32。ii++)//最多三十二個(gè)串口 {ThreadID[ii]=ii。 if(m_st[ii]._status==1)///如果該串口的狀態(tài)為可用的 {m_st[ii].()。 hThread[ii]=AfxBeginThread(ThreadRead,amp。amp。ThreadID[ii])。//創(chuàng)建一個(gè)對(duì)應(yīng)的子通信線(xiàn)程 }} 當(dāng)上面的準(zhǔn)備工作完成后,就開(kāi)始檢查是否還有用戶(hù)需要進(jìn)行通信的下位機(jī)。如果有,就分配一個(gè)空閑的串口進(jìn)行通信。如果沒(méi)有空閑的串口就等待。這樣一直到所有用戶(hù)需要進(jìn)行通信的下位機(jī)都處理完,然后再將各個(gè)子通信線(xiàn)程結(jié)束。這部分的主要代碼如下: if(m_set_mm_readstatus==1)/////如果需要進(jìn)行通信 {WaitForSingleObject(S_num,INFINITE)。//等待一個(gè)空閑的可用串口 intcur_=0。 ()。///進(jìn)入互斥操作區(qū) while(cur_32amp。amp。amp。amp。m_st[cur_]._status==0) ///尋找空閑串口 cur_++。 if(cur_32) ////如果找到空閑的串口 {m_st[cur_]._status=0。////狀態(tài)修改為不可用 m_st[cur_].telephone=m_set_mm_tel_number。 ...... E_startdial[cur_].SetEvent()。 //通知對(duì)應(yīng)的子通信線(xiàn)程開(kāi)始連接 } ... ()。 ///離開(kāi)互斥操作區(qū) 3.2.3 子通信線(xiàn)程 每個(gè)子通信線(xiàn)程對(duì)應(yīng)一個(gè)串口,每個(gè)子通信線(xiàn)程負(fù)責(zé)通過(guò)對(duì)應(yīng)的串口進(jìn)行數(shù)據(jù)的讀寫(xiě)。主線(xiàn)程通過(guò)向子線(xiàn)程依次傳遞不同的電話(huà)號(hào)碼從而使一個(gè)串口依次與不同的下位機(jī)進(jìn)行連接。子通信線(xiàn)程中首先對(duì)串口進(jìn)行初始化,然后就進(jìn)入到循環(huán)等待本串口的開(kāi)始連接信號(hào)到來(lái)的狀態(tài)。如果開(kāi)始連接的信號(hào)到來(lái)了,就可以進(jìn)行連接,然后再進(jìn)行數(shù)據(jù)的發(fā)送和接收。接收的 數(shù)據(jù)數(shù)據(jù)發(fā)送和接受處理完成后,就可以關(guān)閉連接,并釋放一個(gè)信號(hào)量。代碼的主要部分如下: CSerialPortm_port。 intthreadid=*ii。//傳進(jìn)來(lái)的參數(shù),用來(lái)區(qū)分讀數(shù)線(xiàn)程(0~31) intm_id=*ii+1。 (m_id)。//打開(kāi)串口,初始化 while(1)//無(wú)限循環(huán),直到主線(xiàn)程通知結(jié)束 {::WaitForSingleObject(E_startdial[threadid].m_hObject,INFINITE)。 if(m_st[threadid].()) {//如果為空,則表示主線(xiàn)程希望子線(xiàn)程結(jié)束 ReleaseSemaphore(S_num,1,NULL)。 break。} ()。 ()。 //清空緩沖區(qū) m_rlt=(m_telnum)。 //與指定的下位機(jī)建立通信連接 if() ////如果撥號(hào)成功,則進(jìn)行數(shù)據(jù)收發(fā) ......////在此加入數(shù)據(jù)發(fā)送和接收的處理程序。 ()。//關(guān)閉連接 Sleep(2000)。 m_st[threadid]._status=1。 ////修改MODEM狀態(tài)為可用 ReleaseSemaphore(S_num,1,NULL)。///釋放一個(gè)信號(hào)量 if(::WaitForSingleObject(E_end[threadid],0)==WAIT_OBJECT_0) break。///如果收到結(jié)束信號(hào),就中止 } 3.3 下位機(jī)通信軟件的實(shí)現(xiàn) 下位機(jī)主要由單片機(jī)構(gòu)成,通過(guò)調(diào)制解調(diào)器和電話(huà)網(wǎng)與上位機(jī)連接。下位機(jī)輪流掃描各個(gè)傳感器并將讀數(shù)保存。當(dāng)上位機(jī)需要進(jìn)行連接時(shí),響應(yīng)上位機(jī)的連接請(qǐng)求,并根據(jù)上位機(jī)的要求將數(shù)據(jù)送出或?qū)Ρ镜卦O(shè)備進(jìn)行控制操作。數(shù)據(jù)包的格式與前面的格式相同。下載下位機(jī)進(jìn)行數(shù)據(jù)采集所需參數(shù),一旦查詢(xún)到下位機(jī)回復(fù)了設(shè)定的信號(hào)則開(kāi)啟對(duì)應(yīng)站號(hào)的線(xiàn)程。實(shí)現(xiàn)函數(shù)為: if(m_nStationNum==1)// m_nStationNum為站點(diǎn)號(hào) { …………… m_hStation1Thread = CreateThread((LPSECURITY_ATTRIBUTES)NULL, 0, (LPTHREAD_START_ROUTINE)WaitStation1Event, // WaitStation1Event 為1號(hào)站輔助線(xiàn)程的處理函數(shù) (LPVOID)this, 0, amp。wStation1ThreadId)。 if (m_hStation1Thread==NULL) { AfxMessageBox(創(chuàng)建線(xiàn)程失敗!)。 return。 } }4 串行通信協(xié)議4. 1 單片機(jī)的參數(shù)設(shè)置要實(shí)現(xiàn)單片機(jī)與PC機(jī)之間的正常通信,必須正確設(shè)定它們兩者之間的通信方式,保證雙方都用相同的波特率、起始位、停止位、奇偶校驗(yàn)位,并且要建立通信的應(yīng)答信號(hào)。單片機(jī)的結(jié)構(gòu)和特殊寄存器,這是你編寫(xiě)軟件的關(guān)鍵。至于串口通信需要用到那些特殊功能寄存器呢,它們是SCON,TCON,TMOD,SCON等,各代表什么含義呢? SBUF 數(shù)據(jù)緩沖寄存器這是一個(gè)可以直接尋址的串行口專(zhuān)用寄存器。有朋友這樣問(wèn)起過(guò)“為何在串行口收發(fā)中,都只是使用到同一個(gè)寄存器SBUF?而不是收發(fā)各用一個(gè)寄存器?!睂?shí)
點(diǎn)擊復(fù)制文檔內(nèi)容
畢業(yè)設(shè)計(jì)相關(guān)推薦
文庫(kù)吧 www.dybbs8.com
備案圖片鄂ICP備17016276號(hào)-1