<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 測試測量 > 設計應用 > 單片機監控程序的實(shí)現

單片機監控程序的實(shí)現

——
作者:柯 鋒 周永鵬 黃錦恩 時(shí)間:2006-07-22 來(lái)源: 收藏
  

摘 要 首先分析了(80C196為例)監控程序的實(shí)現;介紹了在Win98平臺使用實(shí)現,以及如何利用將匯編后的二進(jìn)制用戶(hù)程序發(fā)送至執行。 
關(guān)鍵詞     
1 引 言
  在調試單片機應用系統時(shí),需要反復地修改用戶(hù)程序,為了避免頻繁地使用編程器寫(xiě)存儲芯片,可以編制單片機監控程序,單片機的監控程序接收來(lái)自PC機的用戶(hù)程序,PC機向單片機發(fā)送用戶(hù)程序。
2 用戶(hù)程序格式
  用戶(hù)將單片機源程序(.a(chǎn)sm文件)匯編后形成.hex格式的文件,該文件即為發(fā)送至單片機的十六進(jìn)制可執行文件。該文件的結構是:由多行構成,行頭為起始符(:),然后是該行有效數據字節數(滿(mǎn)行時(shí)該數為10,即十進(jìn)數16),接下來(lái)為兩字節地址及00,接著(zhù)是有效數據,行尾是校驗碼及換行符。為了簡(jiǎn)化單片機監控程序,僅向單片機發(fā)送行字節數和有效數據,可用下面的簡(jiǎn)單C語(yǔ)句從.hex文件中提取字節數和有效數據:
  fscanf(fp,":%2x%4x00",&TranBytes,&Address);
  fscanf(fp,"%2x",&TranChar);
3 單片機監控程序的實(shí)現
  單片機監控程序實(shí)現的功能為:接收來(lái)自PC機的用戶(hù)程序,將用戶(hù)程序放置在用戶(hù)程序段,當用戶(hù)程序接收完畢后,跳轉至用戶(hù)程序段首地址以執行用戶(hù)程序。接收采用單字節方式,即每次只接收一個(gè)字節。
    為了保證單片機接收用戶(hù)程序的準確性,在接收用戶(hù)程序之前需要進(jìn)行握手。筆者所用的握手協(xié)議為:PC機發(fā)0x55,單片機收0x55后發(fā)回0x55給PC機,上位PC機收0x55后再發(fā)0xaa,單片機收0xaa后發(fā)回,PC機收0xaa后握手成功,轉為發(fā)用戶(hù)程序,單片機轉為接收用戶(hù)程序。
  為了防止單片機監控程序被破壞,需將其固化在EPROM里。筆者所用的80C196系統,將地址2000H-7FFFFH固化,監控程序從2080開(kāi)始。這樣一來(lái)又涉及到如何使用中斷向量的問(wèn)題??梢赃@樣解決:在中斷向量地址中放入8000之后的地址,舉例說(shuō)明,在串行中斷向量地址放入8030H,當要使用串行中斷時(shí),在8030中PUSHF和LJMP指令,在8032中放入跳轉字節數。
  利用串行中斷,單片機接收用戶(hù)程序為逐行接收(見(jiàn)前敘.hex文件的結構)。先接收本行要接收的字節個(gè)數,然后才將接受的有效數據寫(xiě)入用戶(hù)程序段,當接受的有效數據數等于該行要接收的字節個(gè)數時(shí),準備接收下一行,如此反復,如果某行要接收的字節數為0,則表明用戶(hù)程序已經(jīng)傳完,將用戶(hù)程序段首址壓入堆棧再彈出(改變中斷返回地址技術(shù)),以執行用戶(hù)程序,如圖1所示。




4 Win98平臺串行通信的實(shí)現
  現在PC機的應用程序絕大多數都是基于Win98,在進(jìn)行串行通信時(shí)可以通過(guò)調用來(lái)實(shí)現。提供了對串口的各種操作。串口通信時(shí)通過(guò)CreateFile,GetCommState,SetCommState,WriteFile,ReadFile,CloseHandle以及超時(shí)函數GetCommTimeouts,SetCommTimeouts來(lái)實(shí)現。利用CreateFile函數打開(kāi)串口,獲取串口句柄,CloseHandle關(guān)閉串口句柄,利用GetComm-State和SetCommState對通信參數進(jìn)行設置,WriteFile及ReadFile可對串口進(jìn)行讀寫(xiě)。在TC環(huán)境下,對串口的操作方式有兩種:查詢(xún)方式和中斷方式。在VC環(huán)境下,對串口的操作方式可有多種:查詢(xún)方式,同步I/O方式,異步I/O方式,以及事件驅動(dòng)I/O方式。筆者采用的是異步I/O方式,它可以讓串口操作在后臺執行。讓讀寫(xiě)串口操作有足夠的時(shí)間在后臺執行。使用異步I/O方式時(shí),采用如下方式打開(kāi)串口:
  HANDLE m_hCom=CreateFile("COM2",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
  FILE_FLAG_OVERLAPPED指明串口為異步方式打開(kāi)。此時(shí)可以分別在WriteFile和ReadFile的最后一個(gè)參數中指定一個(gè)OVERLAPPED結構,如下所示:
    OVERLAPPED m_OverlappedWrite,     
  m_OverLappedRead;
  m_OverlappedWrite.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
  m_OverlappedRead.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
    CreateEvent函數創(chuàng )建一個(gè)有名或無(wú)名的事件對象,第一個(gè)參數為保密屬性,設為NULL,第二個(gè)參數為T(mén)RUE,指明要用ResetEvent函數將事件設為無(wú)信號,若為FALSE,則在一個(gè)等待該事件的線(xiàn)程被釋放后系統自動(dòng)將其設置為無(wú)信號,第三個(gè)參數設事件初始為無(wú)信號,第四個(gè)參數設事件名為NULL。在讀寫(xiě)操作中使用事件:
  WriteFile(m_hCom,&WriteBuffer,nByteToWrite,&nByteWritten,&m_OverlappedWrite)

  ReadFile(m_hCom,&ReadBuffer,nByteToRead,&nByteRead,&m_OverlappedRead) 
  當WriteFile接手控制時(shí)m_OverlappedWrite.hEvent為無(wú)信號,讀操作完成后,m_OverlappedWrite.hEvent變?yōu)榘l(fā)信號狀態(tài),寫(xiě)操作完成類(lèi)似。在使用ReadFile和WriteFile對串口進(jìn)行讀寫(xiě)時(shí)需要注意的是,這兩個(gè)函數均為立即返回型函數,亦即,可能在實(shí)際的讀寫(xiě)操作還沒(méi)有完成時(shí)函數就返回,操作轉入后臺,但這并不表明實(shí)際的操作失敗。如果返回錯誤代碼為ERROR_IO_PENDING(通過(guò)調用GetLastError獲?。?,說(shuō)明讀寫(xiě)操作仍在進(jìn)行,這時(shí)事件仍然為無(wú)信號,為了顯式地限定前臺等待操作的時(shí)間,可以進(jìn)行延時(shí)處理,調用GetTickCount,GetTickCount()函數獲取系統當前時(shí)間,類(lèi)似于C中的biostime()函數??梢酝ㄟ^(guò)調用GetOverlappedResult獲取后臺的操作情況,該函數報告最近一次OVERLAPPED操作的結果,函數原型如下: 
    BOOLGetOverlappedResult(
    HANDLEhFile,     //文件句柄 

    LPOVERLAPPEDlpOverlapped,
                   //OVERLAPPED結構指針

    LPDWORD lpNumberOfBytesTransferred, 

                  ?。瘜?shí)際完成的字節數

    BOOLbWait

                   //等待標志?。?;
    在進(jìn)行串口讀寫(xiě)時(shí),hFile為串口句柄,lpOverlapped是該函數等待的事件,lpNumberOfBytesTransferrd為實(shí)際讀寫(xiě)完成的字節數,當bWait為T(mén)RUE時(shí),該函數等待讀寫(xiě)操作完成后返回,bWait為FALSE時(shí)函數立即返回。關(guān)于以上兩個(gè)函數的使用,參看如下程序代碼:
if(!WriteFile(m_hCom,&WriteBuffer,nByteToWrite,&nByteWritten,&m_OverlappedWrite)){

if(GetLastError()==ERROR_IO_PENDING) 


    endtime=GetTickCount()+1000;?。訒r(shí)1000 ms  
    while(!GetOverlappedResult(m_hCom,&m_OverlappedWrite&nByteWritten,FALSE)) 

{ 

   if(GetTickCount()>endtime) break;

  }

 } 
if(nByteWritten)    
    ?。幚硭x的字節

 }
  函數ReadFile的調用可以類(lèi)似地處理,進(jìn)行延時(shí)處理后,就可以等到讀寫(xiě)操作完成之后再執行后續程序。為了應用的方便,可以通過(guò)調用API函數,編寫(xiě)自己的串口操作類(lèi)庫來(lái)完成實(shí)際的需要。
5 結 語(yǔ)


  本文介紹的單片機監控程序及串行通信方法簡(jiǎn)單,易于實(shí)現,程序運行穩定。


參 考 文 獻


1 汪建,孫開(kāi)放,章述漢.MCS-96系列單片機原理及應用技術(shù).武昌:華中理工大學(xué)出版社,1999
2 Peter Norton,Rob McGregor.MFC開(kāi)發(fā)Windows95/NT4應用程序.北京:清華大學(xué)出版社,1998
3 譚浩強.C程序設計.北京:清華大學(xué)出版社,1998 

 


評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>