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

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 中斷方式下進(jìn)行串口通訊的正確方法

          中斷方式下進(jìn)行串口通訊的正確方法

          作者: 時(shí)間:2016-11-30 來(lái)源:網(wǎng)絡(luò) 收藏
          一般普遍的把串口通訊分為查詢(xún)方式和中斷方式。查詢(xún)方式比較容易理解,各種書(shū)籍上都介紹的比較清楚。但中斷方式,沒(méi)有幾本書(shū)講得好的,甚至有些例程根本無(wú)法實(shí)際應(yīng)用。
          問(wèn)題有:
          1,半中斷法。只使用接收中斷,不使用發(fā)送中斷,發(fā)送時(shí)還是依靠查詢(xún)中斷標(biāo)志的辦法;如下:
          ES = 0;//若是接收使用中斷方式,某些單片機(jī)需要關(guān)中斷。但C51不一定需要。這里只是示例。
          SBUF = needsendchar;
          While (!TI);
          TI = 0;
          ES = 1;
          這里的問(wèn)題是:發(fā)送數(shù)據(jù)時(shí)需要等待數(shù)據(jù)發(fā)完才能繼續(xù)其他工作,程序效率降低;發(fā)送時(shí)需要關(guān)中斷,影響數(shù)據(jù)接收。
          2,接收中斷的處理方法錯(cuò)誤。如下:
          中斷程序:
          void ser() interrupt 4 {
          RI = 0;
          temp = SBUF; //讀走數(shù)據(jù),放入緩存(全局的)變量
          rx_flag = 1; //設(shè)置接收標(biāo)志
          }
          主程序:
          void main(){
          …;//初始化
          While (1) {
          If (rx_flag ==1){//查詢(xún)接收標(biāo)志
          rx_flag = 0; //清楚接收標(biāo)志
          x = temp; //從暫存變量讀取數(shù)據(jù)
          …;//接收處理
          }
          …; //其它操作
          }
          }
          這里的問(wèn)題是:如果串口接收數(shù)據(jù)的間隔時(shí)間小于“接收處理”和“其它操作”所用的時(shí)間時(shí),接收數(shù)據(jù)會(huì)丟失一部分。
          正確使用中斷方式處理串口收發(fā)應(yīng)達(dá)到以下目的:
          1,完全使用中斷控制接收和發(fā)送,以達(dá)到最快的收發(fā)速度。
          2,接收和發(fā)送互不影響,達(dá)到全雙工通訊效果。
          3,應(yīng)用程序不發(fā)生等待,以達(dá)到最高運(yùn)行效率。
          正確的中斷發(fā)送方法如下:
          1,建立一個(gè)足夠大小的環(huán)形發(fā)送緩沖區(qū),建立一個(gè)信號(hào)量(用于指示發(fā)送的數(shù)據(jù)量),建立一個(gè)發(fā)送標(biāo)志位(用于指示發(fā)送狀態(tài))。
          2,應(yīng)用程序?qū)?shù)據(jù)寫(xiě)入環(huán)形發(fā)送緩沖區(qū),查詢(xún)發(fā)送接收標(biāo)志,若不在發(fā)送狀態(tài),手動(dòng)觸發(fā)中斷。
          3,產(chǎn)生發(fā)送中斷時(shí),查詢(xún)信號(hào)量,以判別發(fā)送緩沖區(qū)內(nèi)是否有數(shù)據(jù);若有,置發(fā)送標(biāo)志位,從緩沖區(qū)讀取數(shù)據(jù)發(fā)送,累減信號(hào)量;若無(wú),清除發(fā)送標(biāo)志位。
          C51的例程如下:
          //變量定義
          #define BUF_SIZE 0x10//環(huán)形收發(fā)緩沖區(qū)長(zhǎng)度
          //發(fā)送參數(shù)
          char tx_circbuf[BUF_SIZE];//環(huán)形發(fā)送緩沖區(qū)
          uint8 tx_sem;//信號(hào)量
          bool tx_run;//發(fā)送標(biāo)志位
          uint8 tx_circin;//進(jìn)環(huán)形緩沖區(qū)的位置指示
          uint8 tx_circout;//出環(huán)形緩沖區(qū)的位置指示
          //發(fā)送初始化程序
          void tx_init(void){
          //硬件初始化 略
          //發(fā)送參數(shù)初始化
          tx_sem = 0;
          tx_run = False;
          tx_circin = 0;
          tx_circout = 0;
          }
          //中斷程序
          void tx_int(void) interrupt 4 {
          if (TI){
          TI = 0;
          if (tx_sem){
          SBUF = tx_circbuf [tx_circout]; // 發(fā)送緩沖區(qū)中的字符
          if (++tx_circout >= BUF_SIZE) tx_circout = 0;
          tx_sem--;//累減信號(hào)量
          tx_run = True;//置發(fā)送標(biāo)志位
          }
          else tx_run = False;//清除發(fā)送標(biāo)志位
          }
          }
          //發(fā)送處理程序,由應(yīng)用程序調(diào)用
          //輸入:發(fā)送數(shù)據(jù)指針,發(fā)送數(shù)據(jù)長(zhǎng)度
          void tx_data(char * txbuf,uint8 len){
          while (len){
          tx_circbuf [tx_circin] = *txbuf++;// 存入數(shù)據(jù)到發(fā)送緩沖區(qū)
          if (++tx_circin >= BUF_SIZE) tx_circin = 0;
          tx_sem++;//累減信號(hào)量
          len--;
          if (tx_run == False)TI=1;//查詢(xún)發(fā)送狀態(tài)標(biāo)志。若發(fā)送空閑,觸發(fā)中斷,發(fā)送數(shù)據(jù)的工作由中斷程序自動(dòng)完成。
          }
          }
          正確的中斷接收方法如下:
          1,建立一個(gè)足夠大小的環(huán)形接收緩沖區(qū),建立一個(gè)信號(hào)量(用于指示接收的數(shù)據(jù)量)。
          2,發(fā)生接收中斷時(shí),讀出字節(jié)放入接收緩沖區(qū),并累加信號(hào)量。
          3,應(yīng)用程序查詢(xún)接收標(biāo)志,如信號(hào)量不為0,則從接收緩沖區(qū)讀取數(shù)據(jù)進(jìn)行處理,累減信號(hào)量。
          C51的例程如下:
          //變量定義
          #define BUF_SIZE 0x10//環(huán)形收發(fā)緩沖區(qū)長(zhǎng)度
          //接收參數(shù)
          char rx_circbuf[BUF_SIZE];// 環(huán)形接收緩沖區(qū)
          uint8 rx_sem;// 信號(hào)量
          uint8 rx_circin;//進(jìn)環(huán)形緩沖區(qū)的位置指示
          uint8 rx_circout;//出環(huán)形緩沖區(qū)的位置指示
          //接收初始化程序
          void rx_init(void){
          //硬件初始化 略
          //接收參數(shù)初始化
          rx_sem = 0;
          rx_circin = 0;
          rx_circout = 0;
          }
          //中斷程序
          void rx_int(void) interrupt 4 {
          if (RI){
          RI = 0;
          rx_circbuf [rx_circin] = SBUF;// 讀出字節(jié)放入接收緩沖區(qū)
          if (++rx_circin >= BUF_SIZE) rx_circin = 0;
          rx_sem++;//累加信號(hào)量
          }
          }
          //接收處理程序,由應(yīng)用程序調(diào)用
          //輸出:讀出數(shù)據(jù)指針;返回:接收到的數(shù)據(jù)長(zhǎng)度
          uint8 rx_data(char * rxbuf){
          uint8 i;
          i = 0;
          while (rx_sem){
          *rxbuf++ = rx_circbuf [rx_circout];// 從接收緩沖區(qū)讀取數(shù)據(jù)
          if (++rx_circout >= BUF_SIZE) rx_circout = 0;
          rx_sem--;//累減信號(hào)量
          i++;
          }
          return i;
          }
          上述的收發(fā)中斷程序在應(yīng)用中合并在一起,即:
          void uart_init(void) interrupt 4 {
          if (TI){
          TI = 0;
          …;
          }
          if (RI){
          RI = 0;
          …;
          }
          }
          例程中分開(kāi)表述,只是為了將流程說(shuō)得更明白些。
          上述例程中,未包含環(huán)形收發(fā)緩沖區(qū)溢出狀況的處理,需要時(shí)自行添加。
          上述例程表明了正確使用中斷方式處理串口通訊的思路。當(dāng)然程序還可以有其它的寫(xiě)法,特別是環(huán)形緩沖區(qū)中數(shù)據(jù)出入的方法和信號(hào)量的用法。如在有操作系統(tǒng)的情況下,上述信號(hào)量的使用就可以得到操作系統(tǒng)更好支持。
          完全中斷方式收發(fā)數(shù)據(jù)總結(jié):
          1。數(shù)據(jù)的收發(fā)操作,完全由中斷程序自動(dòng)進(jìn)行,可以達(dá)到最快的收發(fā)速度。即,接收時(shí)中斷程序負(fù)責(zé)把數(shù)據(jù)放入緩沖區(qū),數(shù)據(jù)的處理由應(yīng)用程序另行處理;發(fā)送時(shí)應(yīng)用程序直接將數(shù)據(jù)放入緩沖區(qū),啟動(dòng)發(fā)送中斷后,發(fā)送的工作由中斷程序自動(dòng)完成。
          2。由于發(fā)送的工作完全由中斷處理,因此,應(yīng)用程序?qū)?shù)據(jù)放入緩沖區(qū)后,就可以繼續(xù)運(yùn)行其它工作,這種“發(fā)了不管”的方式極大地提高程序運(yùn)行效率。
          3。接收數(shù)據(jù)時(shí),由中斷負(fù)責(zé)將數(shù)據(jù)放入緩沖區(qū),再由應(yīng)用程序處理。應(yīng)用程序輪詢(xún)及處理的時(shí)間長(zhǎng)短,不會(huì)影響接收,就不會(huì)導(dǎo)致數(shù)據(jù)丟失。
          4。由于應(yīng)用程序中不出現(xiàn)開(kāi)關(guān)中斷的操作,因此,發(fā)送和接收互不影響,可以達(dá)到全雙工收發(fā)的效果。
          期望上述文字能給予大家借鑒,如有差錯(cuò),望予指正,謝謝。


          關(guān)鍵詞: 中斷方式串口通

          評(píng)論


          技術(shù)專(zhuān)區(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); })();