1. 程式人生 > >串列埠通訊和RS485

串列埠通訊和RS485

1 通訊有關的常見概念

1.1 什麼是通訊

(1)人和人之間的通訊:說話、寫信、狼煙、手勢等。

(2)人和計算機之間的通訊:按鍵、顯示器、滑鼠、觸控式螢幕等。

(3)計算機和計算機之間的通訊?

1.2 通訊的關鍵

(1)事先約定。

(2)基本資訊單元。

(3)有效資訊的編碼、傳輸和解碼。

1.3 通訊的專業性概念

(1)同步和非同步。

(2)單工、半雙工、全雙工。

(3)並行和序列。

(4)電平訊號和差分訊號。

2 什麼是序列通訊

2.1 串列埠通訊基礎

(1)一種特定的通訊協議。

(2)序列通訊、串列埠通訊、UART、USART。

(3)非同步、序列、全雙工。

2.2 序列通訊的主要用途

(1)早期:計算機之間短距離通訊(15米內),完備通訊機制。

(2)現在:CPU之間近距離通訊、除錯資訊輸入輸出,非完備通訊。

2.3 序列通訊的工作方式

(1)3根線(GND、RxD、TxD)或者9根線,receive、transmit。

(2)傳送方有傳送移位暫存器,接收方有接收移位暫存器。

(3)資料在傳送方和接收方的CPU中都以位元組為單位整位元組處理。

(4)資料在通訊線上以位為單位逐個bit的傳輸。

2.4 序列通訊的主要概念

(1)起始位、資料位、奇偶校驗位、停止位(幀)。

(2)波特率:一秒鐘傳輸多少個bit位,傳送方和接收方必須波特率設定為一樣。

(3)流控:速率協商,現在一般都要禁用掉。

3 51微控制器的序列通訊

3.1 先搞清楚以下問題

(1)序列通訊功能是SoC的一個(內部)外設提供的,與CPU本身無關。

(2)各種不同SoC的序列通訊大同小異。

(3)序列通訊經常作為主控SoC與其他外部晶片之間的通訊介面。

3.2 STC51微控制器的序列通訊簡介

這裡寫圖片描述

4 STC51的序列通訊相關暫存器

這裡寫圖片描述

STC90C51RC/RD+系列微控制器的序列口設有兩個控制暫存器:序列控制暫存器SCON和波特率選擇特殊功能暫存器PCON。序列控制暫存器SCON用來選擇序列通訊的工作方式和某些控制功能。

4.1 SCON

SM0/FE SM1 SM2 REN TB8 RB8 TI RI
0    1   0  1/0  0 0  0  0  0x40/0x50

4.2 PCON

SMOD SMOD0 -
1/0   0     0x80/0x00

4.3 串列埠傳送時的軟硬體協作方式

(1)查詢方式。硬體在傳送完一幀資料後會將一個標誌位置位(標誌位本來是0),軟體需要不斷讀取這個標誌位的值來判斷硬體是否完成了傳送(如果讀出來是0就表示硬體還在發還沒完還在忙,所以我們就不能認為硬體發完了,所以就不能給硬體安排下一幀資料的傳送;如果讀出來的是1則說明硬體已經發完了上一幀資料,這時候軟體就應該給硬體再給一幀資料去傳送)。 因為串列埠傳送完這個事件對CPU來說是個非同步事件,所以這裡查詢方式來處理和之前講過的查詢方式處理按鍵是非常類似的。

(2)中斷方式。查詢方式處理的劣勢是CPU必須一直守著串列埠傳送,在串列埠傳送完所有位元組之前CPU不能離開去做別的事情,這對CPU來說是極大的浪費(因為CPU的速度比串列埠傳送的速度快多了)。因此用中斷方式來處理串列埠傳送是非常合適的,可以提升CPU使用率。

(3)常見情況下:串列埠傳送會使用查詢方式,而串列埠接收會使用中斷方式。

4.4 波特率加倍

(1)所謂波特率加倍,就是正常計算出的波特率假設是2400,那麼SMOD=1時則實際的波特率就是4800;當SMOD=0時不加倍,也就是2400還是2400。

5 STC51的序列通訊實戰

5.1 硬體接線分析

(1)目標:將PC機與51微控制器通過串列埠連線起來。

(2)PC機的串列埠情況:桌上型電腦串列埠、筆記本USB轉串列埠。

(3)開發板原理圖分析。
MAX232晶片的作用是:在RS232電平(DB9為RS232電平)和TTL電平(微控制器內部使用的為TTL電平)之間做轉換。

5.2 接線方案

(1)使用板載CH340:什麼都不用動,預設就用這個,最簡單最省事,最推薦。

(2)使用DB9介面USB轉串列埠線:用DB9介面的USB轉串列埠線、注意跳線冒接到DB9一側。

(3)使用TTL介面USB轉串列埠線:只接三根線:TxD、RxD、GND。

5.3 使用板載CH340進行串列埠實踐

(1)接線+下載程式。

(2)查裝置管理器確定COM號。

(3)使用普中下載軟體自帶的串列埠助手監視。

(4)使用第三方串列埠助手軟體監視。

(5)使用SecureCRT軟體監視。

5.4 使用DB9介面USB轉串列埠線

(1)接線+跳線帽調整。

(2)注意對下載程式的影響。

(3)使用各種方式進行監視。

5.6 程式碼實踐

(1)串列埠初始化。

(2)波特率計算。

這裡寫圖片描述

(3)串列埠傳送字元。

(4)串列埠傳送字串。

(5)串列埠接收函式編寫。

#include <reg51.h>

// 函式宣告
void uart_init(void);
void uart_send_byte(unsigned char c);
void delay(void);
void uart_send_string(unsigned char *str);


void main(void)
{
    // 第一步:初始化好串列埠到正確狀態
    uart_init();
/*
    // 第2步:通過串列埠傳送資訊出去
    while (1)
    {
        uart_send_byte('x');
        delay();
    }
    */
/*
    // 測試傳送字串
    while (1)
    {
        //uart_send_string("abcdefg");
        uart_send_string("朱老師物聯網大講堂www.zhulaoshi.org");
        delay();
    }
 */
    uart_send_string("串列埠迴環測試\r\n"); 
    while (1);


}




// 串列埠初始化函式
// 預設一個串列埠條件:8資料位、1停止位、0校驗位、波特率4800
// 初始化的主要工作就是去設定相關的暫存器
void uart_init(void)
{
    // 波特率加倍的

    SCON = 0x50;    // 串列埠工作在模式1(8位串列埠)、允許接收
    PCON = 0x80;    // 波特率加倍,意思是本來需要波特率4800,等下計算時按
                    // 2400去計算就可以了。

    // 通訊波特率相關的設定
    TMOD = 0x20;    // 設定T1為模式2
    TH1 = 243;
    TL1 = 243;      // 8位自動重灌,意思就是TH1用完了之後下一個週期TH1會
                    // 自動重灌到TL1去

    TR1 = 1;        // 開啟T1讓它開始工作
    ES = 1;
    EA = 1;



/*
    // 波特率不加倍
    SCON = 0x50;    // 串列埠工作在模式1(8位串列埠)、允許接收
    PCON = 0x00;    // 波特率不加倍

    // 通訊波特率相關的設定
    TMOD = 0x20;    // 設定T1為模式2
    TH1 = 249;
    TL1 = 249;      // 8位自動重灌,意思就是TH1用完了之後下一個週期TL1會
                    // 自動重灌到TH1去

    TR1 = 1;        // 開啟T1讓它開始工作
    ES = 1;
    EA = 1;
*/
 /*
    // 波特率9600
    SCON = 0x50;    // 串列埠工作在模式1(8位串列埠)、允許接收
    PCON = 0x00;    // 波特率不加倍

    // 通訊波特率相關的設定
    TMOD = 0x20;    // 設定T1為模式2
    TH1 = 253;
    TL1 = 253;      // 8位自動重灌,意思就是TH1用完了之後下一個週期TL1會
                    // 自動重灌到TH1去

    TR1 = 1;        // 開啟T1讓它開始工作
    ES = 1;
    EA = 1;

    */
}

// 通過串列埠傳送1個位元組出去
void uart_send_byte(unsigned char c)
{
   // 第1步,傳送一個位元組
   SBUF = c;

   // 第2步,先確認串列埠傳送部分沒有在忙
   while (!TI);

   // 第3步,軟體復位TI標誌位
   TI = 0;
}

void uart_send_string(unsigned char *str)
{
    while (*str != '\0')
    {
        uart_send_byte(*str);       // 傳送1個字元
        str++;                      // 指標指向下一個字元
    }
}


void delay(void)
{
    unsigned char i, j;

    for (i=0; i<200; i++)
        for (j=0; j<200; j++);
}


void uart_isr(void) interrupt 4 using 1
{
    unsigned char tmp;

    if (RI)
    {
        tmp = SBUF;     // 讀取SBUF,其實就是讀出了串列埠接收到的1位元組
        RI = 0;
    }
    // 至此已經讀到了PC發給微控制器的1個位元組,但是微控制器沒有顯示器沒法顯示
    // 給人看。
    // 我們這裡用一個最簡單的方法來測試,就是直接回發
    uart_send_byte(tmp);
}

6 RS485介紹

6.1 UART的缺點:傳輸距離受限

(1)理論上RS232不超過15米。

(2)理論上TTL電平通訊距離更短。

(3)實際上幾百米也有人宣稱做到了,但是穩定性不能保證。

(4)波特率越高通訊距離越近。

6.2 遠距離傳輸怎麼辦?

(1)提高電壓標準。

(2)提高通訊線抗干擾能力、降低阻抗。

(3)使用差分訊號。

6.3 RS485(RS422)

(1)最大通訊距離1200多米,最快通訊速率10Mbps,距離和速度成反比。

(2)差分訊號負邏輯。

(3)更遠距離可以加中繼器。

(4)半雙工。

(5)RS485只提供物理層通訊能力,不提供資料層協議,需要使用者自定義,或者使用標準協議如MODBUS協議。

6.4 MAX485介紹

(1)CPU本身只會提供UART介面,而不會提供RS485介面。CPU根本不認識RS485。

(2)RS485使用時場景是:CPUA->UART轉RS485——遠距離通訊—–RS485轉UART->CPUB。

(3)大家對RS485的理解,應該是這樣的:RS485是純硬體實現的,硬體晶片如MAX485來管理的,根本不涉及軟體程式設計。軟體工程師只關注串列埠,只通過串列埠將資料傳送出去或者接收回來即可。UART轉485和485轉UART對CPU來說是透明的。