在进行单片机项目开发的时候,串口通信是经常会用到的,在进行串口通信程序设计的时候,我们经常采用的是两种数据接收方式:一种是采用中断法接收串口数据,另一种是使用查询法接收串口数据。
这两种方式各有优缺点:

采用中断法接收串口数据的优点是:可以实时接收到串口数据,缺点是:串口中断一次只能接收一个字节,如果数据较多,那就会是程序频繁的进出中断。如果系统中有其它中断,要使用中断嵌套的方法才能确保正确接收数据。
采用查询法接收串口数据的优点是:在数据接收期间,避免其它干扰,可以完整的接收到全部数据,缺点是:在数据接受过程中不能进行其他任何操作,导致单片机程序效率变低。
最近我们在调试串口数据的时候,采用了一种“半中断“的方法,一方面可以避“免查询法”在没有串口中断数据时候的空闲等待时间,另一方面可以避免“中断法”的频繁进出中断服务程序。
这种方法的实现流程如下:程序中打开串口中断,一旦有串口数据过来,中断马上响应,而在中断服务程序中,关闭中断,转而采用查询法接收串口数据,这样不但提高了单片机的效率,含有效避免了其它中断的干扰,从而能够高效,完整的接收串口数据。
下面是采用MSP430单片机的“半中断”串口数据接收程序。
首先是串口中断服务程序的编写,如下:
#pragma vector=USCI_A1_VECTOR
  • __interrupt void USCI_A1_ISR(void)
  • {
  • if(UCRXIFG&UCA1IFG)
  • {
  • ReceiveData();//进入数据接收函数
  • UCA1IFG=~(UCRXIFG)&UCA1IFG;//清中断标志
  • }
  • }
  • 下面是串口数据查询接收程序
  • unsigned char RX_Data_Buf[50]={0};//定义串口数据接收数组全局变量,并初始化为0
  • void UCA1_ReceiveDataPro(void)
  • {
  • int iTemp=0;
  • do
  • {
  • if(UCRXIFG&UCA1IFG)
  • {
  • RX_Data_Buf[iTemp3]=UCA1RXBUF;
  • iTemp3++;
  • }
  • }while(iTemp3>20);//接收到20个字节,退出
  • }
  • 复制代码
    当然,这个程序只是一个简单的演示,在实际使用中,要考虑到数据干扰问题,并且要考虑不能使程序进入死循环。所以应当加一个最长接收时间,如果达到最长接收时间,那么不论数据是否接收完毕,接受是否正确,都要退出数据接收函数。