日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

中断方式下进行串口通讯的正确方法

發(fā)布時間:2024/4/15 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 中断方式下进行串口通讯的正确方法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

轉(zhuǎn)載:http://bbs.ednchina.com/BLOG_ARTICLE_277752.HTM

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

?

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

?

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

?

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

?

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

?

C51的例程如下:
//變量定義
#define BUF_SIZE 0x10//環(huán)形收發(fā)緩沖區(qū)長度
//發(fā)送參數(shù)
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ā)送參數(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--;//累減信號量
????? tx_run = True;//置發(fā)送標志位
??? }
??? else tx_run = False;//清除發(fā)送標志位
? }
}

?

//發(fā)送處理程序,由應(yīng)用程序調(diào)用
//輸入:發(fā)送數(shù)據(jù)指針,發(fā)送數(shù)據(jù)長度
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++;//累減信號量
??? len--;
??? if (tx_run == False)TI=1;//查詢發(fā)送狀態(tài)標志。若發(fā)送空閑,觸發(fā)中斷,發(fā)送數(shù)據(jù)的工作由中斷程序自動完成。
? }
}

?


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

?

C51的例程如下:
//變量定義
#define BUF_SIZE 0x10//環(huán)形收發(fā)緩沖區(qū)長度
//接收參數(shù)
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){
? //硬件初始化 略

?

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

?

//接收處理程序,由應(yīng)用程序調(diào)用
//輸出:讀出數(shù)據(jù)指針;返回:接收到的數(shù)據(jù)長度
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--;//累減信號量
??? i++;
? }
? return i;
}

?


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

?

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

?

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

?

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

?

轉(zhuǎn)載于:https://www.cnblogs.com/chasing/p/3802840.html

總結(jié)

以上是生活随笔為你收集整理的中断方式下进行串口通讯的正确方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。