您的位置 首页 观点

中止办法下进行串口通讯的正确办法

一般普遍的把串口通讯分为查询方式和中断方式。查询方式比较容易理解,各种书籍上都介绍的比较清楚。但中断方式,没有几本书讲得好的,甚至

一般遍及的把串口通讯分为查询办法和中止办法。查询办法比较简单了解,各种书本上都介绍的比较清楚。但中止办法,没有几本书讲得好的,乃至有些例程底子无法实践运用。

问题有:
1,半中止法。只运用接纳中止,不运用发送中止,发送时仍是依托查询中止标志的办法;如下:
ES = 0;//若是接纳运用中止办法,某些单片机需求关中止。但C51不一定需求。这儿仅仅示例。
SBUF = needsendchar;
While (!TI);
TI = 0;
ES = 1;
这儿的问题是:发送数据时需求等候数据发完才干持续其他作业,程序功率下降;发送时需求关中止,影响数据接纳。
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; //从暂存变量读取数据
…;//接纳处理
}
…; //其它操作
}
}
这儿的问题是:假如串口接纳数据的间隔时刻小于“接纳处理”和“其它操作”所用的时刻时,接纳数据会丢掉一部分。
正确运用中止办法处理串口收发应到达以下意图:
1,彻底运用中止操控接纳和发送,以到达最快的收发速度。
2,接纳和发送互不影响,到达全双工通讯作用。
3,运用程序不产生等候,以到达最高运转功率。
正确的中止发送办法如下:
1,树立一个满足巨细的环形发送缓冲区,树立一个信号量(用于指示发送的数据量),树立一个发送标志位(用于指示发送情况)。
2,运用程序将数据写入环形发送缓冲区,查询发送接纳标志,若不在发送情况,手动触发中止。
3,产生发送中止时,查询信号量,以判别发送缓冲区内是否有数据;若有,置发送标志位,从缓冲区读取数据发送,累减信号量;若无,铲除发送标志位。
C51的例程如下:
//变量界说
#define BUF_SIZE 0x10//环形收发缓冲区长度
//发送参数
char tx_circbuf[BUF_SIZE];//环形发送缓冲区
uint8 tx_sem;//信号量
bool tx_run;//发送标志位
uint8 tx_circin;//进环形缓冲区的方位指示
uint8 tx_circout;//出环形缓冲区的方位指示
//发送初始化程序
void tx_init(void){
//硬件初始化 略
//发送参数初始化
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]; // 发送缓冲区中的字符
if (++tx_circout >= BUF_SIZE) tx_circout = 0;
tx_sem–;//累减信号量
tx_run = True;//置发送标志位
}
else tx_run = False;//铲除发送标志位
}
}
//发送处理程序,由运用程序调用
//输入:发送数据指针,发送数据长度
void tx_data(char * txbuf,uint8 len){
while (len){
tx_circbuf [tx_circin] = *txbuf++;// 存入数据到发送缓冲区
if (++tx_circin >= BUF_SIZE) tx_circin = 0;
tx_sem++;//累减信号量
len–;
if (tx_run == False)TI=1;//查询发送情况标志。若发送闲暇,触发中止,发送数据的作业由中止程序主动完结。
}
}
正确的中止接纳办法如下:
1,树立一个满足巨细的环形接纳缓冲区,树立一个信号量(用于指示接纳的数据量)。
2,产生接纳中止时,读出字节放入接纳缓冲区,并累加信号量。
3,运用程序查询接纳标志,如信号量不为0,则从接纳缓冲区读取数据进行处理,累减信号量。
C51的例程如下:
//变量界说
#define BUF_SIZE 0x10//环形收发缓冲区长度
//接纳参数
char rx_circbuf[BUF_SIZE];// 环形接纳缓冲区
uint8 rx_sem;// 信号量
uint8 rx_circin;//进环形缓冲区的方位指示
uint8 rx_circout;//出环形缓冲区的方位指示
//接纳初始化程序
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;// 读出字节放入接纳缓冲区
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];// 从接纳缓冲区读取数据
if (++rx_circout >= BUF_SIZE) rx_circout = 0;
rx_sem–;//累减信号量
i++;
}
return i;
}
上述的收发中止程序在运用中兼并在一起,即:
void uart_init(void) interrupt 4 {
if (TI){
TI = 0;
…;
}
if (RI){
RI = 0;
…;
}
}
例程中分隔表述,仅仅为了将流程说得更理解些。
上述例程中,未包括环形收发缓冲区溢出情况的处理,需求时自行添加。
上述例程表明晰正确运用中止办法处理串口通讯的思路。当然程序还能够有其它的写法,特别是环形缓冲区中数据收支的办法和信号量的用法。如在有操作系统的情况下,上述信号量的运用就能够得到操作系统更好支撑。
彻底中止办法收发数据总结:
1。数据的收发操作,彻底由中止程序主动进行,能够到达最快的收发速度。即,接纳时中止程序担任把数据放入缓冲区,数据的处理由运用程序另行处理;发送时运用程序直接将数据放入缓冲区,发动发送中止后,发送的作业由中止程序主动完结。
2。因为发送的作业彻底由中止处理,因而,运用程序将数据放入缓冲区后,就能够持续运转其它作业,这种“发了不论”的办法极大地进步程序运转功率。
3。接纳数据时,由中止担任将数据放入缓冲区,再由运用程序处理。运用程序轮询及处理的时刻长短,不会影响接纳,就不会导致数据丢掉。
4。因为运用程序中不呈现开关中止的操作,因而,发送和接纳互不影响,能够到达全双工收发的作用。
希望上述文字能给予我们学习,如有过失,望予纠正,谢谢。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/news/guandian/317846.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部