利用中断实现UART串口

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

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

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

问题有:

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++;//累加信号量

相关文档
最新文档