3个回答
2016-01-02 · 知道合伙人教育行家
关注
展开全部
中断方式下进行串口通讯的正确方法
一般普遍的把串口通讯分为查询方式和中断方式。查询方式比较容易理解,各种书籍上都介绍的比较清楚。但中断方式,没有几本书讲得好的,甚至有些例程根本无法实际应用。
问题有:
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,应用程序不发生等待,以达到最高运行效率。
undefined
正确的中断发送方法如下:
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++;//累加信号量
一般普遍的把串口通讯分为查询方式和中断方式。查询方式比较容易理解,各种书籍上都介绍的比较清楚。但中断方式,没有几本书讲得好的,甚至有些例程根本无法实际应用。
问题有:
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,应用程序不发生等待,以达到最高运行效率。
undefined
正确的中断发送方法如下:
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++;//累加信号量
意法半导体(中国)投资有限公司
2023-06-12 广告
2023-06-12 广告
STM32F103是一款高性能的嵌入式芯片,由意法半导体(STMicroelectronics)公司生产。它是STM32系列芯片之一,具有紧凑、低功耗、高性能等特点,被广泛应用于嵌入式系统中。STM32F103的主要特点包括:1. 集成了A...
点击进入详情页
本回答由意法半导体(中国)投资有限公司提供
展开全部
中断标志位清零不会将缓冲区的数据清零,但是如果不把标志位清零,就算缓冲区接收完一个完整的数据,也不会将数据保存到sbuf寄存器中,也不会产生中断请求。
UART中断一般都分为3种,发送完毕中断,接收完毕中断,错误中断。同其他通信模块一样,发送中断用于检测模块发送信息完毕。接收中断用于使程序调至读取UART模块接收到的数据的中断子程序。错误中断用于检测通信模块在通信过程中是否出错。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
UART中断一般都分为3种,发送完毕中断,接收完毕中断,错误中断。
同其他通信模块一样,发送中断用于检测模块发送信息完毕。接收中断用于使程序调至读取UART模块接收到的数据的中断子程序。错误中断用于检测通信模块在通信过程中是否出错。
由于你没有写具体是那款单片机的UART模块,所以我对你提到的UART模块的中断配置不能具体到寄存器进行讲解,你可以参照你那款单片机的数据手册进行学习。
中断的意思就是让你的程序暂时停止按照正常顺序的运行,先跳转到指定的子程序(相关中断服务程序)进行执行相应的任务,任务执行完毕在返回主程序恢复原来按照顺序正常执行的状态,如果你对中断还不太了解,建议先学习学习中断的定义。
同其他通信模块一样,发送中断用于检测模块发送信息完毕。接收中断用于使程序调至读取UART模块接收到的数据的中断子程序。错误中断用于检测通信模块在通信过程中是否出错。
由于你没有写具体是那款单片机的UART模块,所以我对你提到的UART模块的中断配置不能具体到寄存器进行讲解,你可以参照你那款单片机的数据手册进行学习。
中断的意思就是让你的程序暂时停止按照正常顺序的运行,先跳转到指定的子程序(相关中断服务程序)进行执行相应的任务,任务执行完毕在返回主程序恢复原来按照顺序正常执行的状态,如果你对中断还不太了解,建议先学习学习中断的定义。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询