通訊方式
並行
適合短距離通訊,並行通訊控制簡單、相對傳輸速度快(8位一塊兒傳輸)。數組
![](http://static.javashuo.com/static/loading.gif)
串行
只能一位一位的傳送。異步
![](http://static.javashuo.com/static/loading.gif)
同步(瞭解)
創建發送方時鐘對接收方時鐘的直接控制,使雙方達到徹底同步。此時,傳輸數據的位之間的距離均爲「位間隔」的整數倍,同時傳送的字符間不留間隙。函數
發送方對接收方的同步能夠經過外同步和自同步工具
異步(常)
以字符(構成的幀)爲單位進行傳輸。數據位從低到高傳送。ui
格式:spa
![](http://static.javashuo.com/static/loading.gif)
這裏的空閒時間是任意的。3d
串行通訊的制式(傳輸方向)
單工(僅能沿一個方向)
![](http://static.javashuo.com/static/loading.gif)
半雙工(可進行雙向,但需分時)
![](http://static.javashuo.com/static/loading.gif)
全雙工
![](http://static.javashuo.com/static/loading.gif)
串行通訊的錯誤校驗
奇偶校驗
在發送數據時,數據位尾隨的1位爲奇偶校驗位(1/0)。奇校驗時,數據中1的個數與檢驗位1的個數之和應爲奇數;偶校驗時,數據中1的個數與校驗位1的個數之和應爲偶數。接收字符時,對1的個數進行校驗,若字符不一致,則說明傳輸數據過程當中出現錯誤。code
代碼和校驗
發送方將所發數據塊求和(或各字節異或),產生一個字節的校驗字符(校驗和)附加到數據塊末尾。接收方接收數據時,同時對數據塊(除校驗字節外)求和(或各字節異或),將所得的結果與發送方的「校驗和」進行比較,一致則無差。blog
循環冗餘校驗
經過某種數學預算實現有效信息與校驗位之間的循環校驗,經常使用語對磁盤信息的傳輸、存儲區的完整性校驗。字符串
串口的基本結構
SBUF:51單片機中的特殊寄存器,串行數據緩衝器(一個接收一個發送),兩個實際上是共用的一個地址99H,可是兩個在物理上面是分開的。
當發送使用時,就採用SBUF=XXX; (XXX爲須要傳送的數據)
當接收使用時,採用XXX=SBUF;
記得由於是串行的因此傳輸都是一位一位進行的。
T1溢出率:T1計時器的溢出頻率(就是計時器每次低位計滿向高位進位時間的倒數)
用處:用於計算波特率(每秒傳輸二進制代碼的位數)
實現單片機與電腦之間的互相傳送字符串通訊
工具:STC-ISP
代碼:
- #include <reg52.h>
- #include <stdio.h> //printf頭文件
- #define uc unsigned char
- #define uint unsigned int
-
- uc flag,i,flag_t,s[50]="",j=0,flag_n=0;
- uc code table[]="I get ";
-
- void init()
- {
- TMOD=0x20; //定時器工做方式,選擇了定時器1,工做方式2 八位初值自動重裝的8位定時器。
- TH1=0xfd; //定時器1初值 ,設置波特率爲9600 晶振11.0529MHZ?
- TL1=0xfd;
- TR1=1; //開啓定時器1
-
- SM0=0;
- SM1=1; //10位異步接收,(8位數據)波特率可變
- REN=1; //容許串行口接收位
- EA=1; //容許中斷(總閘)
- ES=1; //容許串口中斷
- }
- void main()
- {
- init();
- while(1)
- {
- if(flag==1)
- { if(flag_n!=0) //使第二個及之後I get xx 換行,不與You transfer在一行(單純爲了格式好看)
- {TI=1;
- printf("\n");
- while(!TI);
- TI=0;
- }
- for(i=0;i<6;i++)
- {
- SBUF=table[i];
- while(!TI);
- TI=0;
- }
- for(i=0;s[i]!='#'&&i<50;i++)
- {
- SBUF=s[i];
- while(!TI);
- TI=0;
- }
- flag=0;
- }
- if(flag_t==1) //發送完畢以後,在電腦端輸出。
- {
- TI=1; //printf以前必須將T1置爲1才行。
- printf ("\nYou transfer %s",s);
- while(!TI);
- TI=0;
- flag_t=0;
- }
- }
- }
-
- void ser() interrupt 4
- {
- if(RI) //接收數據,手動將RI清0
- {
- RI=0;
-
- if(flag==0&&j!=0)//1.循環賦值爲'\0'(字符串結尾標誌符),j=0,爲了第二次傳遞字符串是又是從頭輸出
- { //2.flag爲0和j不爲0時,保證是第二次及之後,傳輸字符串(控制輸出格式)
- flag_n++;
- for(j=0;s[j]!='#'&&j<50;j++)
- s[j]='\0';
- j=0;
- }
- s[j]=SBUF;
- flag=1;
- if(s[j]=='#'||j==49) //以'#'做爲傳送字符串的結尾符,我定義的字符數組最長爲50因此49也應該結束。
- flag_t=1;
- else
- j++;
- }
-
- if(TI) //發送數據
- {
- }
- }
運行截圖:
代碼解讀:基本上就是幾個模塊:計時器、中斷以及串口通訊
中斷
寄存器介紹
IE(interrupt enable):(可位尋址)設定各個中斷源的打開和關閉![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
IP(interrupt prior)中斷優先級寄存器:(可位尋址)用來設定各個中斷源屬於兩級中斷中的哪一級![](http://static.javashuo.com/static/loading.gif)
中斷源:
中斷響應條件:
1.中斷源有中斷請求
2.此中斷源的中斷容許位爲1
3.CPU開中斷(EA=1)
代碼書寫:
1.先開總中斷EA
void 函數名() interrupt 中斷號(上面圖示的序號)
//中斷函數返回值必定是void
//函數名隨便寫
//中斷號用來判斷是哪一個中斷源
計時器
寄存器介紹
TCON 支持位尋址 :控制寄存器,控制T一、T0的啓動和中止及設置溢出標誌
![](http://static.javashuo.com/static/loading.gif)
TMOD,不支持位尋址:定時/計數器的工做方式寄存器,肯定工做方式和功能
計時器代碼書寫步驟:
1.EA=1;
2.ETX=1; //開啓計時器X中斷
3.配置工做方式 TMOD=0x..; //根據本身需求按照上表來配
3.配置計時器初值
//THX=(65535-N)/256;
//TLX=(65535-N)%256;
//N由你要計時的時長決定。計時器計一個數花費一個時鐘週期來計算。
4.TRX=1; //開啓計時器X
串口通訊
寄存器介紹
PCON電源管理寄存器 :(不可位尋址)
用來管理單片機的電源部分,包括上電覆位檢測、掉電模式
、空閒模式等
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
SCON:(可位尋址)用以設定串行口的工做方式、接收/發送控制以及設置狀態標誌
波特率計算
SMOD就是PCON中的第一位,默認爲0
fosc爲晶振頻率,因此本身設定不一樣波特率時,也要考慮晶振不一樣的問題。
代碼書寫
1.上面都書寫完畢以後
2.還須要ES=1
3.傳輸數據時,SBUF=XX
接收數據時,XX=SBUF
4.中斷函數書寫
必定要將RI清0,可是TI的清0在主函數中進行
//由於TI在中斷中進行,(1)沒有if(TI)的判斷,那麼就會和RI的處理混淆(2)若是有TI判斷
//那麼有可能永遠進行不了傳輸數據,由於最開始TI是爲0的,沒法進入TI條件,就無傳
//輸數據(SBUF=XX)。並且在傳輸數據的時候會又一次進入中斷,就是還沒處理中
//斷就又進入了另一箇中斷,致使通訊出現異常。
相信有了這些模塊的講解以後加上代碼的註釋應該都懂了~
若是有任何問題和不懂的均可以提出~