<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 單片機學(xué)習(xí)之十八:串行通訊程序:單片機發(fā)送

          單片機學(xué)習(xí)之十八:串行通訊程序:單片機發(fā)送

          作者: 時間:2016-11-18 來源:網(wǎng)絡(luò) 收藏
          一、實驗現(xiàn)象:

          本文引用地址:http://www.ex-cimer.com/article/201611/315892.htm

          每次按下k0按鍵,由單片機向電腦發(fā)送數(shù)據(jù)62。

          二、實驗?zāi)康?/p>

          掌握單片機串行通訊的概念、特點

          掌握串行通訊波特率的計算方法

          掌握max232接口芯片的連接方法

          掌握方式1串口通訊的簡單程序編寫

          三、實驗任務(wù)分析:

          在這個實驗里面,我們來學(xué)習(xí)編寫一個單片機和PC機之間的通訊程序。首先我們來學(xué)習(xí)一些和串行通訊有關(guān)的理論知識。

          通訊的基本方式分為并行通訊和串行通訊。由于MCS-51系列單片機有一個異步全雙工(全雙工:指的是數(shù)據(jù)可以同時進行雙向的傳送)的串行口,所以我們只研究串行通訊的問題。這里有個新概念-異步,下面我們簡單的給大家解釋一下。

          (一)、異步通訊的概念

          由于單片機自帶的串行口是異步的,所以我們現(xiàn)在只研究異步通訊問題

          在異步傳送中,一幀信息是一位一位進行傳送的。每一個要傳送的字符要用“起始位”和“停止位”作為字符開始和結(jié)束的標(biāo)志,傳送的時候每個字符的的組成格式如下:

          1幀信號=起始位+數(shù)據(jù)位(可以是5、6、7、8位數(shù)據(jù))+停止位,具體格式由通訊雙方約定。

          (二)、關(guān)于異步通訊需要了解的知識

          從異步通訊的特點中我們可以知道,在異步數(shù)據(jù)傳送中,通訊雙方事先必須約好兩項事宜:

          (1)、字符格式:雙方要約定兩者之間以什么樣的格式傳遞信息,比如字符的編碼形式、奇偶校驗形式、以及起始位和停止位的規(guī)定。在單片機中我們是靠選擇串口的工作方式來約定格式的,如何選擇稍后介紹。

          (2)、波特率:在異步數(shù)據(jù)傳送中,通訊雙方傳送數(shù)據(jù)的速率應(yīng)該相同。我們用“波特率”作為衡量數(shù)據(jù)傳送速率的指標(biāo),它定義為“每秒傳送的數(shù)據(jù)位數(shù)”。

          例如:數(shù)據(jù)傳送的速率是120字符/秒,每一個字符假如是10位,則傳送的波特率為:120×10=1200(比特)

          一般的,異步傳送速率在50~9600比特之間。

          可見,在通訊程序中,我們首先應(yīng)該進行初始化工作,約定雙方異步通訊的相關(guān)協(xié)議。

          那么怎樣進行初始化呢?這就涉及到串行接口的控制問題,下面我們來談?wù)勥@個問題。

          (三)、MCS-51的串行通訊接口

          MCS-51單片機內(nèi)部有一個功能很強的異步全雙工串行口,該串行口有四種工作方式,供不同的場合使用(如何選擇后面介紹)。通訊的波特率可以由我們編寫的軟件設(shè)置,由片內(nèi)的定時器/計數(shù)器T1或者T0產(chǎn)生。下面我們就來詳細的介紹一下。

          1、串行口的工作方式

          串行口的四種工作方式中,串行通訊只使用方式1、2、3,方式0主要用于擴展I/O口,這種方式我們不做詳細說明,大家可參考相關(guān)教材。

          方式1:

          這是串口通訊中最常用的方式,為10位異步通訊接口,一幀信息(10位)=起始位(0)+8位數(shù)據(jù)(低位在前)+停止位(1)。

          另外,方式1還有一個特點,波特率可變,我們能夠靈活進行設(shè)置(如何設(shè)置我們稍后介紹),因此這種方式在串行通訊中應(yīng)用的十分廣泛,我們在該試驗中,就選擇這個工作方式。

          方式2和3:

          一般用于主-從式多機通訊的情況下,本試驗采用的是方式1,所以我們暫時也不介紹拉!

          2、串行口工作方式的選擇

          既然決定采用方式1,那么就要對控制寄存器初始化了。串行口的四種通訊方式,使用哪種由特殊功能寄存器SCON決定(也在特殊功能寄存器區(qū),地址是98H,可位尋址,它的各位在單片機復(fù)位的時候被清零)。SCON各位說明如下:圖


          SM0、SM1:串行接口的工作方式選擇:

          00-方式0;01-方式1;10-方式2;11-方式3。由于在該試驗中我們選擇方式1,所以應(yīng)該把SM0和SM1置為01。

          SM2:允許方式2和方式3進行多機通訊的控制位,所以如果我們使用方式2、3進行多機通訊時,將該位置1;但是在本實驗中我們采用方式1,所以SM2置0即可。

          再來看看TI:串行口發(fā)送中斷標(biāo)志。

          當(dāng)一幀信息發(fā)送完成時,發(fā)送中斷標(biāo)志TI置1,向CPU申請中斷。所以在有串口中斷程序的時候,我們初始化的時候應(yīng)該把這一位置0,免得還沒有開始發(fā)送就申請中斷啦?。ㄎ覀兿冗@樣簡單的解釋一下,說多了大家可能會暈哦,如果想了解的更加詳細,自己參考相關(guān)教材吧!^_^)。

          RI:串行口接受中斷標(biāo)志。

          當(dāng)串口接受完一幀信息后,接受中斷標(biāo)志RI置1,向CPU申請中斷,如果CPU允許中斷,就進入串行中斷服務(wù)程序。同樣,在有串口中斷程序的時候,初始化的時候也應(yīng)該把RI清0,免得還沒有開始接受就申請中斷啦!

          但是這里需要說明一點:CPU事先不能分辯是TI還是RI的中斷請求,所以必須在中斷服務(wù)程序中加以判斷,然后在程序中用軟件清零。

          REN:允許串行口接受控制位。當(dāng)REN=1時為允許串行口接受數(shù)據(jù);當(dāng)REN=0時為禁止接受狀態(tài)。在這個實驗里面,由于我們用單片機發(fā)送數(shù)據(jù),所以這一位置0置1均可,我們就把它置0吧。

          TB8:在方式1中該位沒有用,在方式2、3中,是要發(fā)送的第九位數(shù)據(jù)。所以這一位是1和0均可。

          RB8:在方式2、3中,它是接受到的第九位數(shù)據(jù)位。在方式1中,當(dāng)SM2=0,RB8是已經(jīng)接受的停止位。

          綜上所述,我們這個實驗里面,對串口的初始化程序可以是:mov scon,#40h

          3、串口波特率的計算

          當(dāng)串口工作于方式1,波特率是可變的,我們可以靈活的進行設(shè)置,通過給計數(shù)器置入不同的初值,產(chǎn)生不同的波特率。

          計數(shù)初值N和波特率之間的關(guān)系可以用下面的公式描述:

          N=28-(2SMOD×fosc)/(32×12×波特率)

          其中的SMOD是特殊功能寄存器PCON的最高位,叫做波特率選擇位,格式如下,其中和串口有關(guān)的只有D7位,其余的我們就不研究了。

          它的設(shè)置可以通過如下的程序完成:

          mov pcon,#00h ;使smod=0

          mov pcon,#80h ;使smod=1

          下面通過例子說明N的計算方法,例如:

          (1)、系統(tǒng)晶振12MHZ,當(dāng)SMOD=1,欲產(chǎn)生的波特率為2400,時間常數(shù)N的計算如下:

          N=256-(2×12×106)/(32×12×2400)=256-26.04=230=E6H

          (2)、系統(tǒng)晶振12MHZ,當(dāng)SMOD=0,欲產(chǎn)生的波特率為2400,時間常數(shù)N的計算如下:

          N=256-(1×12×106)/(32×12×2400)=256-13.02=243=F3H

          關(guān)于N的計算我們就簡單的說這么多吧,后面的說明里面有一個常用的波特率設(shè)置的表格,在設(shè)置波特率的時候可以進行查閱。

          從上面我們可以看到,SMOD取0或者1都可以產(chǎn)生2400的波特率,那么到底應(yīng)該如何選擇呢?其實,SMOD的選擇影響著波特率的準(zhǔn)確度。關(guān)于這部分內(nèi)容的詳細討論大家可以參考相關(guān)教材,我們就不多說了。

          4、數(shù)據(jù)的發(fā)送過程

          設(shè)置好了串口的工作方式和波特率,我們就可以進行數(shù)據(jù)的發(fā)送拉。發(fā)送的過程如下:CPU執(zhí)行一條將數(shù)據(jù)寫入發(fā)送緩沖區(qū)SBUF的指令即可啟動發(fā)送(如mov sbuf,a),串行數(shù)據(jù)從TXD引腳輸出,發(fā)送完一幀數(shù)據(jù)后,由硬件把TI置位。

          (五)、單片機的串口電平轉(zhuǎn)換電路

          以上我們介紹的是單片機串口的定義和設(shè)定,在實際使用的時候,單片機串口輸出的是TTL電平,傳輸?shù)木嚯x非常有限,不超過1.5m。而電腦的串口輸出的是RS232電平,兩者的電平并不相同,需要外接接口進行電平匹配,這個電平轉(zhuǎn)換芯片采用專用芯片max232來完成。

          在學(xué)習(xí)板的電路上,是采用3線制連接串口,也就是說和電腦的9針串口連接3條線即可,RXD(串行輸入通道)、TXD(串行輸出通道)、GND,對我們來說已經(jīng)夠用了。具體的電路如下圖所示,這是一個典型電路,可以直接使用:

          對這個電路我們簡單解釋一下:

          T1IN、T2IN: 兩路TTL電平輸入引腳,連接單片機的串行輸出TXD腳。

          T1OUT、T2OUT: 兩路RS232電平輸出引腳,連接電腦9針串口的串行輸入RXD。

          R1IN、R2IN: 兩路RS232電平輸入,連接電腦9針串口的串行輸出TXD端。

          R1OUT、R2OUT:兩路TTL電平輸出,連接電腦9針串口的串行輸入RXD端。

          4個外接電容進行電壓匹配和電源去耦。

          通過MAX232的TTL和RS232輸入輸出端口,自動調(diào)節(jié)了單片機串口的TTL電平信號和RS232串行通信信號的電平匹配。

          順便說一句:本實驗是單片機和電腦之間的串行通訊,兩者電平不同,所以需要電平轉(zhuǎn)換芯片,如果是單片機和單片機之間的通訊,兩者都是TTL電平,就不需要進行電平轉(zhuǎn)換,兩個串口可以直接通過導(dǎo)線連接。

          (六)、串口調(diào)試助手

          為了能夠在電腦上看到單片機發(fā)送過來的數(shù)據(jù),我們必須用一個軟件來觀察通訊情況。這里采用“串口調(diào)試助手”軟件,這是一個綠色軟件,無需安裝,可以直接運行。它的設(shè)置方法可見下面的圖解:

          四、實驗程序

          org 0000h

          clr p1.5

          ;以下是串口初始化程序

          mov scon,#40h ;選擇串口工作于方式1

          mov tmod,#20h ;定時器T1設(shè)置為工作方式2,用作波特率發(fā)生器

          mov tl1,#0f3h ;按照波特率為2400計算初值

          mov th1,#0f3h ;把計數(shù)初值送入常數(shù)緩沖器

          mov pcon,#80h ;smod=1,波特率變成4800

          setb tr1 ;啟動定時器T1

          ;以下判斷是否按鍵k0按下

          wait1: jb p1.1,wait1 ;k0沒有按下,等待

          acall del10ms ;延時10ms去抖動

          jb p1.1,wait1 ;再次查詢k0,是抖動返回

          wait2: jnb p1.1,wait2 ;等待按鍵彈起

          mov a,#62h ; 01100010送到a

          mov sbuf,a ;發(fā)送信息,傳送的一幀信息為:0+01100010+1

          ajmp wait1 ;返回繼續(xù)查詢k0是否按下

          del10ms: mov r7,#20 ;延時10ms子程序

          del1: mov r6,#0ffh

          del2: djnz r6,del2

          djnz r7,del1

          ret

          end

          五、幾點說明

          1、該例子中,單片機向電腦發(fā)送的是一個數(shù)據(jù),所以我們我們在串口助手上選擇16進制顯示,就會顯示數(shù)據(jù)62,如果我們不選擇16進制顯示,那么發(fā)送的就是ASCII碼,大家可以試一下,這時顯示的是字符b。

          2、下表是串口常用的波特率設(shè)置,便于大家使用的時候查閱:

          工作

          方式

          波特率

          Fosc=6M

          Fosc=12M

          Fosc=11.0592M

          方式1

          或者

          方式3

          SMOD

          TMOD

          TH1

          SMOD

          TMOD

          TH1

          SMOD

          TMOD

          TH1

          62500

          -

          -

          -

          1

          20

          FFH

          -

          -

          -

          19200

          -

          -

          -

          -

          -

          -

          1

          20

          FDH

          9600

          -

          -

          -

          -

          -

          -

          0

          20

          FDH

          4800

          -

          -

          -

          1

          20

          F3H

          0

          20

          FAH

          2400

          1

          20

          F3H

          0

          20

          F3H

          0

          20

          F4H

          1200

          1

          20

          E6H

          0

          20

          E6H

          0

          20

          E8H

          600

          1

          20

          CCH

          0

          20

          CCH

          0

          20

          D0H



          評論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();