串口通信-輪詢方式
1 串口通信概述
1.1 計算機通信的基本概念
計算機通信: 將計算機技術和通信技術相結合,完成計算機與外部設備或計算機與計算機之間的信息交換。按照數據傳輸方式的不同,可以分為串行通信和并行通信兩類。
串行通信: 數據逐位傳輸,傳輸線少,長距離傳輸時成本低,但數據的傳輸控制較復雜。按照實現數據同步的方式,可以分為同步串行和異步串行兩種。
- 同步串行通信: 數據傳輸以數據塊(一組字符)為單位,在一個數據塊內,字符與字符間無間隔,收發雙方依靠獨立的時鐘線進行信號的同步。
- 異步串行通信: 數據傳輸以單個字符為單位,字符和字符之間的間隙任意,字符內部每一位持續的時間相同。收發雙方沒有專門的時鐘信號,而是依靠事先約定的字符格式和通信速率來完成通信適用于大批量的數據傳輸。
并行通信: 多位數據同時傳輸,傳輸控制簡單,傳輸速度快,但是在長距離傳輸時硬件成本較高。
1.2 異步串行通信
異步通信的兩個關鍵點是字符格式和 波特率 ,字符格式決定了數據的傳輸形式,波特率決定了字符中每一位數據的持續時間。
字符格式
? 1 位起始位,規定為低電平;
? 5~8 位數據位,即要傳送的有效信息;
? 1 位奇偶校驗位;
? 1~2 位停止位,規定為高電平。
常用字符格式:1位起始位,8位數據位,無奇偶校驗,1位停止位
傳輸時低位在前,高位在后,上圖發送數據為0xE9。
通信速率
波特率:每秒鐘傳送二進制數碼的位數,以bit/s(bps)為單位。
常用的波特率有:9600、19200、38400、57600和115200;
波特率為115200,表示每秒傳輸115200位,且每一位數據在數據線上持續時間為Tbit= 1/115200 ≈ 8.68us
異步串行通信的數據接收過程
接收過程的本質是數據采樣,假設接收端的采樣時鐘是波特率的16倍。
① 接收過程由起始位的下降沿啟動;
② 接收端等待8個時鐘周期,以便建立一個接近比特周期中間的采樣點;
③ 接收端等待16個時鐘周期,使其進入第一個數據位周期的中點;
④ 第一個數據位被采樣并存儲在接收寄存器中;
⑤ 串口模塊在采樣第二個數據位之前等待另外16個時鐘周期;
⑥ 重復此過程,直到所有數據位都被采樣和存儲;
⑦ 由停止位的上升沿使數據線返回到空閑狀態。
串口通信的數據傳輸方向
錯誤校驗方式
- 奇偶校驗:奇校驗表示數據中“1”的個數與校驗位“1”的個數之和為奇數;偶校驗表示數據中“1”的個數與校驗位“1”的個數之和為偶數。
- 代碼和校驗:發送方將所發數據塊求和,產生一個字節的校驗字符附加到數據塊末尾。接收方采用同樣方式進行檢測。
- 循環冗余校驗:通過某種數學運算實現有效信息與校驗位之間的循環校驗,常用于磁盤信息的傳輸、存儲區的完整性校驗等。
2 STM32串口通信
2.1 串口收發單元
串口收發單元主要利用數據寄存器DR,發送引腳TX,接收引腳RX,以及三個通信狀態位TXE、TC和RXNE來完成數據的接收和發送。
- TXE:發送數據寄存器空標志。當TDR寄存器的內容已經傳送到發送移位寄存器 時,該位由硬件置1。如果串口控制寄存器CR1中的TXEIE位為1,將會觸發發送數據寄存器空中斷。注意:當TXE置1時,數據有可能還在發送。
- TC:發送完成標志。當發送移位寄存器的內容發送完成,同時TDR寄存器也為 空時,該位由硬件置1,表示本次數據傳輸已經完成。如果串口控制寄存器CR1中的TCIE位為1,將會觸發發送完成中斷。注意:當TC置1時,數據才是真正地發送完成。
- RXNE:接收數據寄存器不為空標志。當移位寄存器的內容已經傳送到接收數據寄存器RDR時,該位由硬件置1。如果串口控制寄存器CR1中的RXNEIE位為1,將會觸發接收數據寄存器不為空中斷。
數據寄存器DR在硬件上分為TDR和RDR兩個寄存器,通過數據的流向進行區分,在結構設計上采用了雙緩沖結構;
發送時,數據通過數據總線送入TDR寄存器,然后傳送到發送移位寄存器完成數據轉換,從并行數據轉為串行數據,最后通過TX引腳發送;
接收時,數據通過RX引腳逐位送入接收移位寄存器,8位數據接收完成后,送入RDR寄存器,供用戶讀取。
USB轉TTL串口模塊
2.2 串口的數據類型定義
①外設句柄的定義:
HAL庫在結構上,對每個外設抽象成了一個稱為ppp_HandleTypeDef
的結構體,其中ppp就是每個外設的名字。所有的函數都是工作在ppp_HandleTypeDef
指針之下。
例如,使用USART2時,可以定義USART初始化結構體變量(全局變量)huart2
。
UART_HandleTypeDef huart2;
huart2
就被稱為串口的句柄,它被貫穿整個USART收發的流程。
②外設句柄數據類型的組成:
③串口初始化數據類型:
成員變量WordLength的取值范圍
宏常量定義 | 含義 |
---|---|
UART_WORDLENGTH_8B | 數據位長度為8位 |
UART_WORDLENGTH_9B | 數據位長度為9位 |
成員變量StopBits的取值范圍
宏常量定義 | 含義 |
---|---|
UART_STOPBITS_1 | 停止位長度為1位 |
UART_STOPBITS_2 | 停止位長度為2位 |
成員變量Parity的取值范圍
宏常量定義 | 含義 |
---|---|
UART_PARITY_NONE | 無奇偶校驗 |
UART_PARITY_EVEN | 偶校驗 |
UART_PARITY_ODD | 奇校驗 |
成員變量Mode的取值范圍
宏常量定義 | 含義 |
---|---|
UART_MODE_RX | 串口僅處于接收模式,只能接收數據,不能發送數據 |
UART_MODE_TX | 串口僅處于發送模式,只能發送數據,不能接收數據 |
UART_MODE_TX_RX | 串口處于接收和發送模式,可以同時收發數據 |
成員變量HwFlowCtI的取值范圍
宏常量定義 | 含義 |
---|---|
UART_HWCONTROL_NONE | 無硬件流控 |
UART_HWCONTROL_RTS | 使能“請求發送(RTS)”引腳 |
UART_HWCONTROL_CTS | 使能“允許發送(CTS)”引腳 |
UART_HWCONTROL_RTS_CTS | 使能“請求發送(RTS)”和“允許發送(CTS)引腳 |
成員變量OverSampling的取值范圍
宏常量定義 | 含義 |
---|---|
UART_OVERSAMPLING_16 | 采樣頻率是信號傳輸頻率的16倍 |
UART_OVERSAMPLING_8 | 采樣頻率是信號傳輸頻率的8倍 |
2.3 外設初始化設計思想
①串口初始化過程:
抽象—串口初始化函數MX_USART2_UART_Init
: 將與MCU無關的通信參數存入句柄結構 + 使用HAL_UART_Init
執行串口初始化操作,將句柄參數寫入寄存器。
HAL_UART_Init
干了哪些事?
- 調用
HAL_UART_MspInit
- 修改狀態忙
- 配置寄存器
- 清除標志位
承載—與MCU相關的初始化函數HAL_UART_MspInit
:時鐘初始化 + 引腳初始化
3 串口通信方式
- 輪詢方式:CPU不斷檢測串口的狀態標志來判斷數據收發的情況。特點:程序設計簡單,但CPU在檢測標志位期間,無法執行其他任務,CPU利用率較低。
- 中斷方式:使能中斷后,接收一字節數據或發送一字節后申請中斷,在ISR中完成后續處理。在數據收發期間,CPU可以執行其他任務,CPU利用率較高。
- DMA方式:初始化時設置相關參數,啟動DMA傳輸后,數據傳輸過程不需要CPU的干預。傳輸完成后,再產生DMA中斷,由CPU進行后續處理。傳輸效率最高。
4 輪詢方式的串口通信 ##
串口初始化函數:
HAL_UART_Init
函數原型 HAL StatusTypeDef HAL_UART_Init (UART_HandleTypeDef *huart) 功能描述 按照串口句柄中指定的參數初始化串口 入口參數 huart:串口句柄的地址 返回值 HAL狀態值:HAL_OK表示初始化成功,HAL_ERROR表示初始化失敗 注意事項 1.該函數將調用與MCU相關的初始化函數HAL_UART_Msplnit完成時鐘、引腳和中斷等底層硬件的初始化操作2.該函數由CubeMX自動生成 接口函數:
HAL_UART_Transmit
函數原型 HAL_StatusTypeDef HAL_UART_Transmit(UART_Handle TypeDef *huart, uint 8_t *pData, uint 16_t Size, uint 32_t Timeout) 功能描述 在輪詢方式下發送一定數量的數據 入口參數1 huart:串口句柄的地址 入口參數 pData:待發送數據的首地址 入口參數3 Size:待發送數據的個數 入口參數4 Timeout:超時等待時間, 以ms為單位, HAL MAX DELAY表示無限等待 返回值 HAL狀態值:HAL_OK表示發送成功;HAL_ERROR表示參數錯誤;HAL_BUSY表示串口被占用;HAL_TIMEOUT表示發送超時 注意事項 1.該函數連續發送數據,發送過程中通過判斷TXE標志來發送下一個數據,通過判斷TC標志來結束數據的發送2.如果在等待時間內沒有完成發送,則不再發送,返回超時標志3.該函數由用戶調用 接口函數:
HAL_UART_Receive
函數原型 HAL_StatusTypeDef HAL_UART_Receive(UART_Handle TypeDef *huart, uint 8_t *pData, uint 16_t Size, uint 32_t Timeout) 功能描述 在輪詢方式下接收一定數量的數據 入口參數1 huart:串口句柄的地址 入口參數 pData:存放數據的首地址 入口參數3 Size:待接收數據的個數 入口參數4 Timeout:超時等待時間, 以ms為單位, HAL MAX DELAY表示無限等待 返回值 HAL狀態值:HAL_OK表示發送成功;HAL_ERROR表示參數錯誤;HAL_BUSY表示串口被占用;HAL_TIMEOUT表示發送超時 注意事項 1.該函數連續接收數據,接收過程中通過判斷RXNE標志來發送下一個數據2.如果在等待時間內沒有完成接收,則不再接收,返回超時標志3.該函數由用戶調用
5 任務實踐1
在PC上利用串口調試助手發送數據到MCU,MCU調用scanf函數讀取數據,然后調用printf函數發送應答信息到PC。
串口外設配置
- 異步模式,無硬件流控
- 設置通信參數:波特率115200,8位數據位,無奇偶校驗,1位停止位,使能接收和發送,16倍過采樣(CubeMX默認配置)
在Keil中勾選Use MicroLIB
編寫代碼
printf和scanf重定向/* USER CODE BEGIN Includes */ #include < stdio.h > /* USER CODE END Includes */ int fputc (int ch, FILE *f) { HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY); return ch; } int fgetc(FILE *f) { uint8_t ch = 0; HAL_UART_Receive(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY); return ch; } /* USER CODE END 4 */
用戶應用代碼——猜數游戲
/* USER CODE BEGIN 3 */ printf("Please guess a number between 0 to 9n"); if (scanf("%d", &guess_num) == 1) { if (guess_num == ans) { printf("You are right! It's %dn", ans); } else { printf("You are wrong! It is not %dn", guess_num); } } } /* USER CODE END 3 */
實驗現象
-
寄存器
+關注
關注
31文章
5355瀏覽量
120531 -
計算機
+關注
關注
19文章
7511瀏覽量
88078 -
STM32
+關注
關注
2270文章
10904瀏覽量
356367 -
串口通信
+關注
關注
34文章
1626瀏覽量
55562 -
異步串行通信
+關注
關注
0文章
16瀏覽量
8438
發布評論請先 登錄
相關推薦
評論