久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術學習與研究
當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

中斷方式下進行串口通訊的正確方法

作者:佚名   來源:本站原創(chuàng)   點擊數:  更新時間:2013年01月01日   【字體:

   一般普遍的把串口通訊分為查詢方式和中斷方式。查詢方式比較容易理解,各種書籍上都介紹的比較清楚。但中斷方式,沒有幾本書講得好的,甚至有些例程根本無法實際應用。
    問題有:
1,半中斷法。只使用接收中斷,不使用發(fā)送中斷,發(fā)送時還是依靠查詢中斷標志的辦法;如下:
  ES = 0;//若是接收使用中斷方式,某些單片機需要關中斷。但C51不一定需要。這里只是示例。
  SBUF = needsendchar;
  While (!TI);
  TI = 0;
  ES = 1;
這里的問題是:發(fā)送數據時需要等待數據發(fā)完才能繼續(xù)其他工作,程序效率降低;發(fā)送時需要關中斷,影響數據接收。

2,接收中斷的處理方法錯誤。如下:
  中斷程序:
  void ser() interrupt 4 {
    RI = 0;
    temp = SBUF;     //讀走數據,放入緩存(全局的)變量
    rx_flag = 1; //設置接收標志
  }
  主程序:
  void main(){
    …;//初始化
    While (1) {
      If (rx_flag ==1){//查詢接收標志
        rx_flag = 0; //清楚接收標志
        x = temp; //從暫存變量讀取數據
        …;//接收處理
      }
      …;  //其它操作
    }
  }
這里的問題是:如果串口接收數據的間隔時間小于“接收處理”和“其它操作”所用的時間時,接收數據會丟失一部分。

    正確使用中斷方式處理串口收發(fā)應達到以下目的:
1,完全使用中斷控制接收和發(fā)送,以達到最快的收發(fā)速度。
2,接收和發(fā)送互不影響,達到全雙工通訊效果。
3,應用程序不發(fā)生等待,以達到最高運行效率。

正確的中斷發(fā)送方法如下:
1,建立一個足夠大小的環(huán)形發(fā)送緩沖區(qū),建立一個信號量(用于指示發(fā)送的數據量),建立一個發(fā)送標志位(用于指示發(fā)送狀態(tài))。
2,應用程序將數據寫入環(huán)形發(fā)送緩沖區(qū),查詢發(fā)送接收標志,若不在發(fā)送狀態(tài),手動觸發(fā)中斷。
3,產生發(fā)送中斷時,查詢信號量,以判別發(fā)送緩沖區(qū)內是否有數據;若有,置發(fā)送標志位,從緩沖區(qū)讀取數據發(fā)送,累減信號量;若無,清除發(fā)送標志位。

C51的例程如下:
//變量定義
#define BUF_SIZE 0x10//環(huán)形收發(fā)緩沖區(qū)長度
//發(fā)送參數
char tx_circbuf[BUF_SIZE];//環(huán)形發(fā)送緩沖區(qū)
uint8 tx_sem;//信號量
bool tx_run;//發(fā)送標志位
uint8 tx_circin;//進環(huán)形緩沖區(qū)的位置指示
uint8 tx_circout;//出環(huán)形緩沖區(qū)的位置指示

//發(fā)送初始化程序
void tx_init(void){
  //硬件初始化 略
 
  //發(fā)送參數初始化
  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--;//累減信號量
      tx_run = True;//置發(fā)送標志位
    }
    else tx_run = False;//清除發(fā)送標志位
  }
}

//發(fā)送處理程序,由應用程序調用
//輸入:發(fā)送數據指針,發(fā)送數據長度
void tx_data(char * txbuf,uint8 len){
  while (len){
    tx_circbuf [tx_circin] = *txbuf++;// 存入數據到發(fā)送緩沖區(qū)
    if (++tx_circin >= BUF_SIZE) tx_circin = 0;
    tx_sem++;//累減信號量
    len--;
    if (tx_run == False)TI=1;//查詢發(fā)送狀態(tài)標志。若發(fā)送空閑,觸發(fā)中斷,發(fā)送數據的工作由中斷程序自動完成。
  }
}


正確的中斷接收方法如下:
1,建立一個足夠大小的環(huán)形接收緩沖區(qū),建立一個信號量(用于指示接收的數據量)。
2,發(fā)生接收中斷時,讀出字節(jié)放入接收緩沖區(qū),并累加信號量。
3,應用程序查詢接收標志,如信號量不為0,則從接收緩沖區(qū)讀取數據進行處理,累減信號量。

C51的例程如下:
//變量定義
#define BUF_SIZE 0x10//環(huán)形收發(fā)緩沖區(qū)長度
//接收參數
char rx_circbuf[BUF_SIZE];// 環(huán)形接收緩沖區(qū)
uint8 rx_sem;// 信號量
uint8 rx_circin;//進環(huán)形緩沖區(qū)的位置指示
uint8 rx_circout;//出環(huán)形緩沖區(qū)的位置指示

//接收初始化程序
void rx_init(void){
  //硬件初始化 略

  //接收參數初始化
  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++;//累加信號量
  }
}

//接收處理程序,由應用程序調用
//輸出:讀出數據指針;返回:接收到的數據長度
uint8 rx_data(char * rxbuf){
  uint8 i;
  i = 0;
  while (rx_sem){
    *rxbuf++ = rx_circbuf [rx_circout];// 從接收緩沖區(qū)讀取數據
    if (++rx_circout >= BUF_SIZE) rx_circout = 0;
    rx_sem--;//累減信號量
    i++;
  }
  return i;
}


上述的收發(fā)中斷程序在應用中合并在一起,即:
void uart_init(void) interrupt 4 {
  if (TI){
    TI = 0;
    …;
  }
  if (RI){
    RI = 0;
    …;
  }
}
例程中分開表述,只是為了將流程說得更明白些。

上述例程中,未包含環(huán)形收發(fā)緩沖區(qū)溢出狀況的處理,需要時自行添加。

上述例程表明了正確使用中斷方式處理串口通訊的思路。當然程序還可以有其它的寫法,特別是環(huán)形緩沖區(qū)中數據出入的方法和信號量的用法。如在有操作系統(tǒng)的情況下,上述信號量的使用就可以得到操作系統(tǒng)更好支持。

完全中斷方式收發(fā)數據總結:
1。數據的收發(fā)操作,完全由中斷程序自動進行,可以達到最快的收發(fā)速度。即,接收時中斷程序負責把數據放入緩沖區(qū),數據的處理由應用程序另行處理;發(fā)送時應用程序直接將數據放入緩沖區(qū),啟動發(fā)送中斷后,發(fā)送的工作由中斷程序自動完成。
2。由于發(fā)送的工作完全由中斷處理,因此,應用程序將數據放入緩沖區(qū)后,就可以繼續(xù)運行其它工作,這種“發(fā)了不管”的方式極大地提高程序運行效率。
3。接收數據時,由中斷負責將數據放入緩沖區(qū),再由應用程序處理。應用程序輪詢及處理的時間長短,不會影響接收,就不會導致數據丟失。
4。由于應用程序中不出現開關中斷的操作,因此,發(fā)送和接收互不影響,可以達到全雙工收發(fā)的效果。

期望上述文字能給予大家借鑒,如有差錯,望予指正,謝謝。

關閉窗口

相關文章

主站蜘蛛池模板: 精品在线一区 | 污视频在线免费观看 | 欧美影院 | 国产一区在线看 | 在线免费黄色 | 午夜精品视频在线观看 | 91精品中文字幕一区二区三区 | 国产亚洲精品精品国产亚洲综合 | 黄网站免费在线 | 在线一区二区三区 | 狠狠躁躁夜夜躁波多野结依 | 久久久女 | 国产精品久久久久久久久久久久久 | 一级看片免费视频囗交动图 | 伊人春色在线观看 | 精品久久国产老人久久综合 | 在线视频国产一区 | 日韩精品999| 色妞av | 男女网站免费 | 精品综合久久久 | 国产中文在线 | 亚洲 欧美 日韩在线 | av一二三区| 久久久久亚洲 | 精品国产免费人成在线观看 | 中文字幕一区二区在线观看 | 精品乱码一区二区 | 国产a区| 嫩草一区二区三区 | 欧美久久一级特黄毛片 | 国产精品久久久久国产a级 欧美日韩国产免费 | 欧美日韩高清免费 | 欧美一区二区三区精品免费 | 这里有精品 | 69亚洲精品 | 在线中文字幕第一页 | 九色.com| 国产伦精品一区二区三区精品视频 | 欧美日韩久久精品 | 亚洲天堂免费在线 |