每日一言
????????那些讓你喘不過氣的日子,正是蛻變的開始。
?
串口編程寄存器分析(紅色框里面的這個是串口助手里面生成的波特率初始化函數哈)
我們就根據以上的寄存器分析,因為這個是配置波特率的需要的寄存器
PCON
smod= 0 就是PCON的bit 7 這個位置為0 也就是 我們用8421法可以推算出 0x7F 為 0111 1111 ,那么&上個0x7F那么就會等于 &上一個0111 1111 ?那么我們smod這個位置就會為0 ?,那么我們的波特率就不會加倍
SCON
SCON寄存器的話是控制串口工作的模式??有4種方式 ,然后這個TH1也是通過這個SCON寄存器里面的講解來算的
先介紹一下8 位 UART 的含義
在串口工作模式 1(你代碼中使用的模式)中,“8 位 UART” 指:
- 數據位為 8 位:每次傳輸 1 個字節(8 位)的數據,例如 ASCII 字符(如'A'對應二進制0100 0001)。
- 無第 9 位:與模式 2/3(9 位 UART)不同,模式 1 不使用 TB8/RB8 位,適合簡單的數據傳輸(如發送文本、傳感器數據等)。
TMOD
這個就是老朋友了,定時器的工作模式
我們一般用按位與和按位或來設置
我們對于串口通信的定時器的模式的話我們就設置為8位的自動重裝載模式
波特率的計算和定時器不可分家
TL1 和TH1 這個啊就是定時器1的兩個8位寄存器
在串口通信中啊,一般使用的是8位自動重載的模式,這個模式是什么意思呢,就是為了計算波特率的準確度,在TL1溢出的時候,TH1會自動將自身的值給TL1,這樣就不會有誤差,精度更高,所以在配置串口通信的時候,我們會將TH1和TL1的值設置成相同的,就是為了計算波特率的精準度高。
Tips:這個scon的8位UART和TMOD 8位自動裝載的這個是沒有一點關系的,不要以為都是8就有什么關系,他們的功能都是獨立的!!!
但實際應用中,模式 1(8 位 UART)+ 定時器 1 模式 2?是最常用的組合,因為:
- 8 位數據格式滿足大多數場景(如 ASCII、傳感器數據)。
- 定時器模式 2 的自動重裝機制簡化了波特率控制。
5. 關鍵區別總結
參數 | 8 位 UART(SCON) | 8 位自動重裝(Timer1) |
作用 | 定義串口數據幀格式 | 生成穩定的波特率時鐘 |
相關位 | SM0=0, SM1=1 (模式 1) | TMOD.6=1, TMOD.5=0 (模式 2) |
數據位數 | 每幀 8 位數據 | 與數據位無關 |
波特率控制 | 依賴定時器溢出率 | 直接決定溢出率 |
總結
- 8 位 UART(SCON)和定時器 1 模式 2(8 位自動重裝)是串口通信的黃金組合,但兩者功能獨立。
講完這個寄存器那我們就要根據這個寄存器為什么要這樣配置我們要搞懂原理
PCON為什么配置PCON &=0x7F?
?這行代碼使用了按位與操作 。0x7F 轉換為二進制是 0111 1111 ,PCON 寄存器與 0x7F 按位與,會將 PCON 寄存器的最高位(即 SMOD 位 )清零,其他位保持不變 ,從而確保 SMOD = 0,使串口波特率不加倍 。
SCON為什么配置成0x50??
????????因為0x50相當于 0101 0000 就是我不用后面的四位不用的位都上0,就是TB8 RB8 TI RI,然后用8421法算出來就是0x50,那為什么是前面4位都是0101呢 ?因為和他們的工作方式有關,這邊我們選擇是是8位UART 所以SM0是0,SM1是1,還有我們運行串口通信所以REN要設為1,所以就是0101 0000 轉換為0x50
TMOD為什么設置為TMOD &= 0x0F; TMOD |= 0x20;????
????????因為我們定時器用的是定時器1,所以只用定時器1,定時器0不變,然后定時器1我們還要設置其為8位的自動重裝載模式,所以先定時器M1M0的位置要為1、0,也說明了這個模式的作用,所以我們先TMOD &= 0x0F;? ? 0x0F是00001111 &上這個之后 定時器0不變,定時器1清0,因為這個是按位&,后面TMOD |= 0x20就是讓M1M0的位置要為1、0 所以就是 0010 0000 ?| 上這個之后定時器1有1為1全0為0 ,所以此時定時器就算設置好了 然后這個0010 0000利用8421法就直接變成 0x20
TL1 TH1為什么設置為 0xFD ????
首先是定時器1,1的來頭
其次要搞清楚為什么相同為什么都是一樣的值
- 因為是我們的TMOD設置的是8位自動重裝載模式,為什么要設置的是8位自動重裝載模式,因為這個模式的特性是 TL1當溢出時將TH1存放的值自動重裝入TL1.這樣有利于我們計算波特率的精準度高,所以我們要設置成一樣的初始值。
這些配完就 TR1(運行控制位)=1啟動定時就可以了
別忘了AUXR這個寄存器,這個寄存器的話reg52.h里面是沒有定義的,所以我們用芯片手冊查出來用法為
就直接先sfr AUXR=0x8E先聲明一下 ?后面在初始里面加入 AUXR=0x01就好了