計算機串行通信:
并行通信:
串行通信:
異步通信:
同步通信:
串行通信的傳輸方向:
串行通信常見的錯誤校驗:
傳輸速率比特率(波特率):
(fosc是晶振頻率,要將Mhz轉化為hz(乘10的6次方),若不設置SMOD則默認是0,有想設置的波特率就可以求出T初了,將它賦給TH和TL就行了)
串行通信接口標準:
傳輸距離與傳輸速率的關系:
采用RS-232C接口存在的問題:
串行接口的結構:
使用串口前的準備工作:
與串行通信相關的寄存器:
可位尋址的意思是可以寫為像以下這樣的形式:
SM0=0; SM1=1;//串口工作方式1,8位UART波特率可變REN=1;//串口允許接收
定時計數器控制寄存器TCON:
單片機同優先級中內部查詢順序:
串口通信示例(通過定時中斷刷新數碼管顯示PC端發送的數據):
#include <reg52.h>
#include <intrins.h>#define uint unsigned int
#define uchar unsigned charsbit DU = P2^6;//數碼管段選
sbit WE = P2^7;//數碼管位選
sbit key_s2 = P3^0;//獨立按鍵S2
sbit key_s3 = P3^1;//獨立按鍵S3
uchar num;//數碼管顯示的值//共陰數碼管段選表
uchar code SMGduan[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,};
//數碼管位選碼
uchar code SMGwei[] = {0xfe, 0xfd, 0xfb};void display(uchar i)
{static uchar wei; P0 = 0XFF;//清除斷碼WE = 1;//打開位選寄存器P0 = SMGwei[wei];WE = 0;//鎖存位選寄存器switch(wei){case 0: DU = 1; P0 = SMGduan[i / 100]; DU = 0; break;case 1: DU = 1; P0 = SMGduan[i % 100 / 10]; DU = 0; break; case 2: DU = 1; P0 = SMGduan[i % 10]; DU = 0; break; }wei++;if(wei == 3)wei = 0;
}
//定時器0初始化
void timer0Init()
{EA = 1; //打開總中斷ET0 = 1;//打開定時器0中斷TR0 = 1; //啟動定時器0TMOD |= 0X01; //定時器工作模式,16位定時模式TH0 = 0xED;TL0 = 0xFF; //定時5ms
}
//串口初始化
void UARTInit()
{EA=1;//打開總中斷ES=1;//打開串口中斷SM0=0; SM1=1;//串口工作方式1,8位UART波特率可變REN=1;//串口允許接收TR1=1;//啟動定時器一(用來串口通信設置波特率)TMOD |=0x20;// 定時器1,工作模式2 8位自動重裝TH1=0xfd;TL1=0xfd;//設置波特率9600
}void main()//main函數自身會循環
{ timer0Init();//定時器0初始化UARTInit();//串口初始化while(1);
} //定時器中斷函數,達到時間后進入中斷函數
void timer0() interrupt 1
{TH0 = 0xED;TL0 = 0xFF; //定時5msdisplay(num); //數碼管顯示函數
}
//串口中斷函數
void UART() interrupt 4
{uchar temp;if(RI)//判斷接收數否完成{num=SBUF;//讀SBUF,讀串口接收到的數據RI=0;//軟件清0接收標志位temp=num;SBUF=++temp;//寫SBUF,把要發送的數據發送給緩存器}if(TI)//判斷是否發送完成TI=0;//清0發送完成標志位
}
當單片機接收到一幀數據后,RI會置1,向CPU申請中斷,若之前有中斷允許,則產生了中斷,進入中斷服務程序。當然,單片機發送完一幀數據,TI也會置1,同樣會產生中斷!
補充:其實,不管你有沒有允許中斷,上位機(此時即給單片機發送信息的機器)只要給單片機發送數據,單片機就會自動接收數據,并把它放在數據緩沖器SBUF中,如果你之前有允許串行口中斷,RI就會置1,向單片機CPU申請中斷,并進入中斷服務程序,即你問題中的serial()函數,做完這個函數后就會自動返回斷點。如果你沒有允許中斷,便不會產生串行中斷。