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

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



来源:老马识途单片机