新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > PIC16系列單片機與PC機串行通信的軟硬件實現

        PIC16系列單片機與PC機串行通信的軟硬件實現

        作者: 時間:2011-02-24 來源:網絡 收藏
        摘 要介紹一種運用PIC16F84實現與PC機串行通信的方法,并給出其硬件接口電路及通信源程序。

        1 前言

        美國Microchip公司的PIC16系列是一種新型的CMOS工藝的8位。其中,PIC16FXX單片機的程序存儲器為電可擦除閃速存儲器(flash),可多次修改程序,甚至可以在線編程。PIC16F83和PIC16F84片內數據存儲器除RAM外,還有64字節的EEPROM,可以當作一般的或非易失性的數據存儲器使用,簡單方便。它還具有片內上電復位、延時電路、看門狗電路等。另外,PIC16系列單片機功耗極低,因而是一種非常適合在各種便攜式設備中使用的高性價比的單片機,并已經得到了越來越廣泛的應用。
        但是在許多需要大量計算的運用中,還必須借助微機的強大數據處理能力。這樣必須通過通信電路實現與微機間的可靠數據傳輸。有的PIC16單片機內并沒有提供串行口,所以串行通信必須通過自己設計的硬件電路和通信軟件來實現。
        下面介紹用查詢法實現異步串行通訊的方法。同時給出了用PIC16F84單片機的兩個I/O口模擬2線串行口的硬件接口電路、程序流程框圖、單片機內通信程序以及微機內的通信程序等。

        2 硬件實現方法與電路

        PIC16F84單片機的程序存儲器由1K×14的閃速(flash)存儲器構成,它只有13條I/O口,1個定時器,為了盡量節省單片機的軟硬件資源,采用下述異步串行通信的實現方法。
        如圖1所示,PIC16F84在4MHz時鐘下,采用半雙工方式,可實現9600波特率的異步串行數據通信,1位停止位,8位數據位,無校驗位。接收和發送以低位在先(一般模式),采用軟件延時。為節省篇幅,單片機內的通信程序中未提供任何握手協議,用戶可根據自己的需要在軟件中加入握手方式。

        由于PIC16F84單片機本身沒有專門的串行口,這里用其I/O口來模擬串行口的功能。
        PC機的串行接口是符合EIA RS-232C規范的外部總線標準接口。RS-232C采用的是負邏輯,即邏輯“1”:-5V至-15V;邏輯“0”:+5V至+15V。而CMOS電平為:邏輯“1”:4.99V,邏輯“0”:0.01V;TTL電平的邏輯“1”和“0”則分別為2.4V和0.4V。因此在用RS-232C總線進行串行通信時需外接電路實現電平轉換。在發送端用驅動器將TTL或CMOS電平轉換為RS-232C電平,在接收端用接收器將RS—232C電平再轉換為TTL或CMOS電平。
        這里選用了MAXIM公司的MAX202E來作電平轉換。MAX202E屬于MAXIM公司的通用串行接收/發送驅動器芯片。其外圍電路簡單,只需外接四個0.1μF的電容即可,如圖1所示。



        圖1 接口原理圖

        3 PIC16F84單片機內通信程序的設計

         


        圖2 接收子程序框圖 圖3發送子程序框圖


        圖2和圖3分別是串行發送和接收的子程序流程框圖。發送時,通過使數據發送端DX為低電平并保持B秒(9600波特率時為104μs)來發送起始位。隨后每B秒鐘通過置位或清零DX端把數據發送出去。這里的B是指一位所持續的時間(B=1/波特率)。接收時,數據接收端DR大約要每B/2秒(9600波特率時為52μs)查詢一次以檢測起始位,如果檢測到起始位,則在大約1.5B秒(9600波特率時為156μs)后檢測第一位數據位,隨后每B秒鐘檢測一次其它的數據位。
        相應的源程序如下:

        ;接收子程序
        Rcvr
        clrwdt
        ;清片內看門狗
        ;定時器
        btfsc
        RA,DR ;檢測起始位
        goto
        Rcvr ;未檢測到起始位
        movlw
        8 ;檢測到起始位
        movwf
        R_CNT ;8位數據位
        Rnext
        call
        Delay ;延時B/2秒
        bcf
        STATUS,C ;清進位標志
        rrf
        RevReg ;LSB在先
        btfsc
        RA,DR ;該位為0
         
        ;還是為1
        bsf
        RcvReg,MSB ;為1
        call
        Delay ;延時B/2秒
        decfsz
        R_CNT
        goto
        Rnext
        retlw0
        ;返回
        ;發送子程序
        Xmtr
        clrwdt
        ;清片內看門狗
        ;定時器
        movlw
        8 ;發送位數為8
        movwf
        X_CNT
        bcf
        RA,DX ;發送起始位
        Xnext
        call
        Delay ;延時B/2秒
        call
        Delay ;延時B/2秒
        rrf
        XmtReg ;LSB在先
        btfsc
        STATUS,C ;檢測將要發送
         
        ;的數據位
        bsf
        RA,DX ;數據位為1
        btfss
        STATUS,C
        bcf
        RA,DX ;數據位為0
        decfsz
        X_CNT ;位計數為0則
        ;發停止位
        goto
        Xnext ;位計數不為0
        ;則發下一位數據位
        Xstop
        call
        Delay ;延時B/2秒
        call
        Delay ;延時B/2秒
        Bsf
        RA,DX ;發送停止位
        Retlw
        0 ;返回
        ;延時子程序
        Delay
        movlw
        12 ;52μS延時
        movwf
        DCNT ;
        Dnext
        decfsz
        DCNT
        goto
        Dnext ;
        retlw 0


        4 Win95的串行通信機制及串口查詢法的原理

        常用的DOS系統主要是工作在響應中斷方式。PC機串行通信程序大多利用其BIOS塊的INT14H中斷,以查詢串口的方式完成異步串行通信。
        Windows系統函數即包含了通信支持中斷功能。Win95系統為每個通信設備開辟了用戶定義的輸入輸出緩沖區(即讀/寫緩沖區),數據進出通信口均由系統后臺來完成。應用程序只需完成對輸入輸出緩沖區操作就可以了。實際過程是每接收一個字符就產生一個低級硬件中斷,Win95系統中的串行驅動程序就取得了控制權,并將接收到的字符放入輸入數據緩沖區。然后將控制權返還正在運行的應用程序。如果輸入緩沖區數據已滿,串行驅動程序用當前定義的流控制機制通知發送方停止發送數據。隊列中的數據按“先進先出”的次序處理。
        (1) 按協議的設置初始化并打開串口,這樣做就是通知Windows本應用程序需要這個串口,并封鎖其他應用程序使它們不能使用此串口。
        (2) 配置這個串口。
        (3) 在串口上往返地傳輸數據,并在傳輸過程中進行校驗。
        (4) 不需要此串口時,關閉串口。即釋放串口以供其它應用程序使用。
        在這四個步驟中,主要的程序代碼集中在第(3)步。
        串口查詢法是一種主要工作在查詢方式下的實現方法。當通信程序工作在“查詢”方式時,可以不考慮Win95的進程和線程的問題。僅在串口有數據時,去讀串口緩沖區就可以了,如圖4所示。這種方法下確定串口讀取的時機、握手協議及軟件糾錯的實現是程序員應考慮的主要問題。

         

        圖4 讀取接收緩沖區數據流程圖

         


        圖5 串口初始化流程


        由于這種方法主要工作在查詢方式。程序員必須完成相當一部分通信狀態的檢測工作,許多細節(甚至包括通信過程中的字符屬性的轉換)也必須通過程序代碼完成。這種查詢方法對通信雙方協議的依賴性尤其大。雙方通信協議的約定對程序實現的難易程度影響很大。
        串口查詢法中,一般串口初始化的流程如圖5。
        值得注意的一點是,此方法下協議的約定必須滿足以下條件:即甲方發送時,乙方必須在甲方發送動作之前進入循環接收狀態,直到接收到字符后通過對串口讀取函數ReadFile返回值的判斷跳出循環狀態。
        同時,一般為了不使系統因循環等待接收而進入“死循環”狀態,可以人為設置讀取串口的循環次數,一般1000~10000次即可。
        本程序的實現平臺是VB4,這是一種極為靈活的高級語言,它可以方便地引入匯編語言的思維,利用其GoTo轉向語句方便地控制程序的流程,靈活方便。

        5 PC機內通信程序的實例

        現約定甲方是PC機,乙方是單片機系統(如讀卡器)。通信格式設置為2400波特率,8位數據位,1位停止位,無奇偶校驗。
        下面是一個約定好通訊協議的程序實例,協議流程如圖6所示。
        以下是甲方(PC機)的幾個子函數的程序實例。



        圖6 通信協議流程


        Private Function OpenThePort(cPort as String,cBaud as String,cParity

        as String,cData as String,tStops asString)As Boolean ’ 打開串口的子過程

        Dim lResult as Long

        Dim lHandle as Long

        Dim DCB_COMM as DCB

        Dim cDCBConfig as String

        lHandle = CreateFile(cPort,GENERIC_READ Or GENERIC_WRITE,

        0,0,OPEN_EXISTING,0,0)

        If lHandle = -1 Then ’打開串口失敗

        OpenThePort = False

        MsgBox “串口可能正被其他應用程序占用!”

        lResult = CloseHandle(lHandle) ’先關閉串口后再打開

        If lResult = 0 Then

        OpenThePort

        Exit Function

        End If

        End If

        cDCBConfig.band = 2400 ’設置DCB

        cDCBConfig.parity = None

        cDCBConfig.data = 8

        cDCBConfig.stop = 1

        lResult = BuildCommDCB(cDCBConfig,DCB_COMM) ’按用戶設定配置一個DCB結構

        If lResult = 0 Then

        OpenThePort = False

        MsgBox “無法建立DCB設備控制塊”

        Exit Function

        End If

        lResult = SetCommState(lHandle,DCB_Comm) ’實際設置一個串口的DCB

        If lResult = 0 Then

        OpenThePort = False

        MsgBox “無法建立DCB設備控制塊”

        Exit Function

        End If

        OpenThePort = True

        End Function

        Private Sub SendHand ( ) ’發送握手信號的子過程

        Dim Nchars As Long

        Static Readbuff As String * 1

        Static Writebuff As String * 1

        Dim lpDCB As DCB

        Dim lRet As Long

        Dim lHandle As Long

        Dim lpOverlapped As OVERLAPPED

        Dim RNum As Integer

        MsgBox “請把讀卡器插在串口2上!”,

        48,“提示窗口”

        lHandle = OpenThePort(COMM1,2400,None,8,1)

        lRet = PurgeComm( lHandle,1 ) ’清輸出緩沖區

        lRet = PurgeComm( lHandle,0 ) ’清輸入緩沖區

        lRet = GetCommState ( lHandle,lpDCB ) ’獲得通訊口的狀態

        Shand:

        Writebuff$= Chr$(H8F)

        lRet = WriteFile (lHandle,Writebuff$,1,Nchars,lpOverlapped )

        ’送握手信號入串口緩沖區

        If lRet = 0 Then

        MsgBox “發送操作出錯,卡握手信號未發送成功”, 16

        GoTo Shand ’不成功則重發

        Else

        GoTo Qtest

        End If

        GoTo Shand

        Qtest:

        Readbuff$ =“ ” ’清除緩沖區為空

        Do While lHandle ’循環查詢串口

        RNum = 0 ’設置讀串口次數的指針為0

        ReadAgain:

        lRet = ReadFile( lHandle, Readbuff$,1,Nchars,lpOverlapped )

        If lRet 0 Then

        MsgBox “讀取應答信號時出錯”, 16

        End If

        If lRet = 0 Then

        If RNum > 1000 Then ’只讀1000次串口,以免陷入死循環

        MsgBox

        "卡沒有插接好或卡沒有接在串口上!"

        GoTo CloseP

        End If

        RNum = RNum + 1

        GoTo ReadAgain

        End If

        If Hex$(Asc(Readbuff)) > Hex$(HFF) Then GoTo Shand

        ’回送碼不正確則返回繼續發送握手信號

        Else

        Label1.Caption = “握手信號是:”

        +Hex$(Asc(Readbuff$))

        Msgbox “握手信號正確,已正確聯機”

        GoTo CloseP

        End If

        Loop

        CloseP:lRet = CloseHandle( lHandle )

        If lRet = 0 Then

        MsgBox “串行通訊口關閉成功”,

        48,“提示窗口”

        End If

        End Sub

        這里要注意的是:當PC機與單片機系統通信時,單片機數據存儲區( RAM )內的數據是十六進制,在信號線上傳輸的是十六進制數的ASCII碼的二進制形式;而Windows系統下使用的是ANSI碼,ANSI碼僅在前126個與ASCII碼相同。即在Win95下接收到的是十六進制數的ASCII碼的字符串,可先轉換為ANSI碼后再在Win95下還原為十六進制數。
        具體為:Code$=Hex$(Asc ( Readbuff$ ) )
        另外,由于32位API函數參數的數據類型的變化,所有整形參數都被換為長整型(Long)以支持32位的處理,這一點在設置返回值時尤其如此。

        6 結束語

        以上的軟硬件在我們的實踐中達到了較為理想的效果。通過軟件節省了硬件的開銷,并通過在PIC16F84單片機系統和PC機雙方的通信軟件內增加握手信號,達到了軟件數據校驗的目的,獲得了較高的通信可靠性。

        參 考 文 獻

        1 MICROCHIP CO. PIC16/17 MICROCO-NTROLLER DATA BOOK. 1995/1996
        2 李東星等. PIC16CXX系列單片機應用設計. 高奇電子科技公司,1996.10
        3 美 Darwin Boyle等. Visual Basic 4 Developer’s Guide. 北京:機械工
        業出版社,1997.

        51單片機相關文章:51單片機教程


        數字通信相關文章:數字通信原理


        通信相關文章:通信原理


        存儲器相關文章:存儲器原理




        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 竹溪县| 平昌县| 千阳县| 阳城县| 调兵山市| 马尔康县| 临汾市| 长宁区| 思南县| 当雄县| 昌吉市| 关岭| 延庆县| 成安县| 阿拉善盟| 东台市| 阿荣旗| 永清县| 峨山| 灵台县| 小金县| 苏州市| 辽阳市| 马关县| 睢宁县| 呼图壁县| 韶关市| 浠水县| 阜平县| 米林县| 巴林右旗| 文昌市| 台东市| 武义县| 哈巴河县| 本溪市| 开化县| 永福县| 边坝县| 澳门| 花莲县|