51單片機UART通信與波特率的計算


UART通信原理

通訊過程描述

  1. 當沒有通信信號時,通信線路保持高電平。
  2. 發送數據之前, 先發送一個0表示起位,表示起始位
  3. 接着發送8位數據位,數據位是先低后高的順序。
  4. 數據位發送完畢,再發送一個1表示停止位

通訊數據幀圖

  • UART完整串行數據幀:

UART模塊的使用

51單片機的 UART 串口的結構由串行口控制寄存器 SCON發送電路接收電路三部分構成。

串口控制寄存器

  • SCON串行控制寄存器的位分配(地址為0x98, 可位尋址)
7 6 5 4 3 2 1 0
符號 SM0 SM1 SM2 REN TB8 RB8 TI RI
復位值 0 0 0 0 0 0 0 0
符號 描述
7 SM0 這兩位共同決定了串口通信的模式0 ~模式 3 共 4 種模式 。 最常用的就是模式 1 ,也就是 SM0=0 SM1=1 ,其它模式從略。
6 SM1
5 SM2 多機通信控制位(極少用),模式 1 直接清零。
4 REN 使能串行接收。由軟件置位使能接收,軟件清零則禁止接收。
3 TB8 模式2 和 3 中要發送的第 9 位數據(很少用)。
2 RB8 模式2 和 3 中接收到的第 9 位數據(很少用),模式 1 用來接收停止位。
1 TI 發送中斷標志位,當發送電路發送到停止位的中間位置時,TI 由硬件置 1必須通過軟件清零。
0 RI 接收中斷標志位,當接收電路接收到停止位的中間位置時,RI 由硬件置 1必須通過軟件清零。。
  • 串口模式1: 1 位起始位, 8 位數據位和 1 位停止位。

    • SM0 = 0; SM1 = 1;

波特率

波特率的概念

  • 波特率就是發送二進制數據位所用的時間,用baud表示。

  • 發送1位二進制數據的持續時間為1/baud

波特率計算公式

  • 對於STC89C52單片機來說, 波特率發生器只能由定時器T1/T2產生,不能由T0產生。

  • 使用T1的模式2[自動重裝模式], 定時器的重載值計算公式為:

    \[TH1 = TL1 = 256 - 晶振值 / 12 / 2 / 16 / 波特率 \]

    • 256 : 定時器模式2(8位)的溢出值
    • 晶振值: 11059200
    • 12 : 一個機器周期(STC89C52中一個時鍾周期等於12個時鍾周期, 具體看芯片手冊)
    • 16: 串口模塊將一位信號采集16次,將其中7,8,9次取出來,如果這三次中兩次如果是高電平就認為這位數據是1。
    • 波特率: 要設定的波特率
  • 電源管理寄存器PCON, 設置后它可以將波特率提高一倍

    PCON |= 0x80
    
    • 此時波特率公式為:

      \[TH1 = TL1 = 256 - 晶振值 / 12 / 16 / 波特率 \]

  • 參考代碼

    //  程序名稱: uart/main.c
    //  程序簡述: uart實例
    //  維護人員: ieeqc
    // 	創建日期:2020/9/13
    //	最后修改時間:2020/9/13
    
    /*
    	功能描述: 單片機usb接上計算機並實現通訊, 將其結果+1發送給計算機
    	
    	實現步驟:
    	- 1. 配置串口為模式1
    	- 2. 配置定時器T1為模式2
    	- 3. 根據波特率計算TH1和TL1的初值, 如果有需要則可以使用PCNF進行波特率加倍
    	- 4. 打開定時器控制寄存器, 讓定時器跑起來
    	- 5. 開啟UART中斷, 1.接收並解析數據, 2.處理數據, 3.發送數據 
    	
    	程序注釋:
    	- 波特率計算公式:
    		TH1 = TL1 = 256 - 晶振值 / 機器周期 / 2 / 16 / 波特率
    		- 機器周期: STC89C52RC的機器周期是'晶振/12'
    		- 16: 單片機uart模塊會將每一個數據位取16次, 然后判斷中間值來確定是'0'還是'1'
    	
    	- 波特率加倍:
    		PCON |= 0x80;那么計算公式為:
    			- TH1 = TL1 = 256 - 晶振值/12/16/波特率
    */
    
    
    #include<reg52.h>
    
    #define Crystal_Frequency 11059200 // 定義當前單片機的晶振頻率
    #define BAUDRATE 9600	             // 定義當前單片機UART所采用的波特率
    
    
    void ConfigUART(unsigned int baud); // 串口初始化
    
    void main() {
    	EA = 1; // 打開使能總中斷
    	ConfigUART(BAUDRATE);
    	while(1);
    }
    
    
    /* 串口配置函數, baud-通信波特率 */
    void ConfigUART(unsigned int baud) {
    	SCON = 0x50;  // 配置為串口為模式1
    	TMOD &= 0x0F; // 清0 T1的控制位
    	TMOD |= 0x20; // 配置T1為模式2
    	
    	TH1 = 256 - (Crystal_Frequency / 12 / 32) / baud; // 計算T1重載值
    	TL1 = TH1;  // 初值等於重載值
    	ET1 = 0;    // 禁止T1中斷
    	ES = 1;     // 使能串口中斷
    	TR1 = 1;    // 啟動T1
    }
    
    
    /* 串口中斷服務函數 */
    void Uart_Interrupt() interrupt 4 {
    	
    	if (RI) {// 接收到字節
    		RI = 0; // 手動清零接收中斷標志位
    		SBUF = SBUF + 1; // 接收的數據 +1 后發回,左邊是發送 SBUF ,右邊是接收 SBUF
    	}
    	
    	if (TI) {// 字節發送完畢
    		TI = 0; // 手動清零 發送中斷標志位
    	}
    }
    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM