第一個例子:
避免死循環,一直發數據(用自設接收數據標志位法,不用關串口中斷ES方法)flag必須放if語句中的最后位置,否則死循環
#include<reg52.h> #define uchar unsigned char #define uint unsigned int uchar flag=0,temp; void init() { TMOD=0X20;//定時器1方式2作為波特率發生器 TH1=0XF3;//裝初值 波特率為4800bps的初值 TL1=0XF3; TR1=1;//啟動定時器1 SCON=0X50;//設置串口工作方式為方式1 PCON=0X80;//加倍波特率后為4800 EA=1;//開總中斷 ES=1;//允許串口中斷 TI=0;//清發送中斷標志位 RI=0;//清接收中斷標志位 } void main() { init(); while(1) { if(flag==1) { //ES=0;//flag為1說明接收完引起中斷 //flag=0;//清中斷標志 RI=0;//對接收中斷標志清零,為下一幀數據接收作準備 temp=SBUF;//讀入接收數據,在不關中斷ES前提下,CPU讀入接收數據也不會引起中斷,接收數據由接收SBUF接收緩存器自動執行 P0=temp; //讀入數據送P0口 SBUF=temp; //向發送方返回接收數據 //TI=0; //要等待發送完,否則數據沒發送完TI=0,flag=0已經執行 //flag=0; //發送完后引起中斷,flag又置1,進入死循環,一直發數據 while(!TI);//等待發送完,!!要等待!! TI=0;//數據發送完對發送中斷標志清零,為下一幀數據發送作準備 flag=0; //必須有否則進入死循環,放最后 //ES=1;//允許串口中斷繼續接收數據 } } } void serial() interrupt 4 { flag=1; }
----------------------第2個例子:-----------------------------------------------
/*********************************************** 中斷法串口通信(用關串口中斷ES方法)推薦不丟幀 ***********************************************/ #include<reg52.h> #define uchar unsigned char #define uint unsigned int uchar flag=0,temp; void init() { TMOD=0X20;//定時器1方式2作為波特率發生器 TH1=0XF3;//裝初值 波特率為4800bps的初值 TL1=0XF3; TR1=1;//啟動定時器1 SCON=0X50;//設置串口工作方式為方式1 PCON=0X80;//加倍波特率后為4800 EA=1;//開總中斷 ES=1;//允許串口中斷 TI=0;//清發送中斷標志位 RI=0;//清接收中斷標志位 } void main() { init(); while(1) { if(flag==1) { ES=0;//flag為1說明接收完引起中斷,關串口中斷,處理當前幀 flag=0;//清中斷標志 RI=0;//對接收中斷標志清零,為下一幀數據接收作準備,此處清零不丟幀 temp=SBUF;//讀入接收數據,在不關中斷ES前擔下,CPU讀入接收數據也不會引起中斷,接收數據由接收SBUF接收緩存器自動執行 P0=temp; //讀入數據送P0口 SBUF=temp; //向發送方返回接收數據 //TI=0; //要等待發送完,否則數據沒發送完TI=0,flag=0已經執行 //flag=0; //發送完后引起中斷,flag又置1,進入死循環,一直發數據 while(!TI);//等待發送完,!!要等待!! TI=0;//數據發送完對發送中斷標志清零,為下一幀數據發送作準備 //flag=0; //必須有否則進入死循環,放最后 ES=1;//允許串口中斷繼續接收數據 } } } void serial() interrupt 4//執行此句,即產生中斷表示數據已接收完 { //RI=0;//不在此清零接收中斷標志,否則接收SUBF處于一直接收狀態,中斷一直進行影響其它指令進行,造成返回丟幀現象實驗得出 flag=1; }