目錄
1.簡介
2.串口和UART?
2.1串口的簡介
2.2UART的簡介
2.3UART通信協議
2.3.1波特率
2.3.2空閑位
2.3.3起始位
2.3.4數據位
2.3.5校驗位
2.3.6停止位
3.STM32的UART
4.HAL庫中常用的操作UART的函數
4.1UART初始化函數 --?HAL_UART_Init
4.2硬件初始化回調函數 -- HAL_UART_MspInit
4.3發送數據函數 --?HAL_UART_Transmit?
4.4接收數據的函數 --?HAL_UART_Receive
4.5使能中斷源 --?__HAL_UART_ENABLE_IT
4.6獲取UART的狀態標志 --?__HAL_UART_GET_FLAG
4.7清除指定的 UART 狀態標志位 --?__HAL_UART_CLEAR_FLAG
5.發送接收數據實驗 并 打開串口printf功能
5.1硬件連接
5.2代碼編寫
5.2.1配置UART
5.2.2中斷函數
5.2.3重定義fputc -- 支持printf函數
6.整體代碼 && 實驗現象
6.1uart1.h
6.2uart1.c
6.3main.c
6.4實驗現象
1.簡介
? ? ? ? 這個文章會介紹串口通信,然后編寫代碼完成單片機通過串口發送到電腦,電腦發送數據到單片機的過程。
? ? ? ? 作者使用的開發板是正點原子的精英版,寫文章用于記錄學習和經驗分享。
2.串口和UART?
2.1串口的簡介
????????串口(Serial Port) 是一種常見的數據通信接口,用于實現設備之間的串行通信(Serial Communication)。所謂“串行”,是指數據是按 一位一位的順序進行發送或接收的,與并行通信(一次性傳輸多個比特)相對。
2.2UART的簡介
????????UART(Universal Asynchronous Receiver/Transmitter),UART 全稱是通用異步收發器,是一種硬件模塊,用于實現異步串行通信。它是實現串口通信的核心邏輯電路。
????????UART也是一種廣泛應用于嵌入式系統中的異步串行通信協議,通過定義數據幀格式和波特率實現設備之間的點對點數據傳輸。它僅需兩根信號線(TXD發送、RXD接收),無需共享時鐘,具有結構簡單、使用方便、兼容性強等優點,常用于調試輸出、傳感器通信、模塊交互等場景。
? ? ? ? 設備1的TX(發送端)接入設備2的RX(接收端),設備1的RX(接收端)接入設備2的(發送端),這樣就實現了全雙工通信。也可以單工通信,就是一發一收,接通一路TX、RX即可。
2.3UART通信協議
????????UART的一個完整的數據幀通常包括起始位、數據位、可選的校驗位和停止位,通信雙方必須保持波特率和數據格式一致才能正常工作。
2.3.1波特率
????????波特率(Baud Rate) 是串行通信中的一個關鍵參數,用于表示每秒傳輸的信號變化次數,單位是 bps(bits per second) 。在 UART 通信中,波特率決定了數據傳輸的速度。
????????在 UART 通信中,發送端和接收端必須設置相同的波特率,否則會導致數據接收不到或者接收內容與發送的內容不一致的問題。
2.3.2空閑位
????????空閑位(Idle State) 是指當串口未發送或接收任何數據時,數據線(通常是 TXD 或 RXD)處于高電平狀態。數據幀以一個起始位(Start Bit,低電平)開始,空閑位作為幀與幀之間的間隔,確保接收方能正確識別下一幀數據。
2.3.3起始位
????????起始位(Start Bit) 是 UART 數據幀中的第一個信號位,用于通知接收端:一幀數據即將開始傳輸。電平狀態固定為低電平(0);長度為 1 位。
2.3.4數據位
????????數據位(Data Bits) 是 UART 數據幀中承載實際信息的部分,表示一次通信中傳輸的有效數據內容。數據的長度通常為 5 到 8 位,8位用的最廣泛,因為正好是1字節的大小。
????????發送的順序是低位先發(LSB First)。例如字符 'A' 的 ASCII 碼為:0x41(十六進制)二進制表示為:01000001? ? ?UART 發送順序(LSB 先發):1 0 0 0 0 0 1 0
2.3.5校驗位
????????校驗位(Parity Bit)是 UART 數據幀中一個可選的錯誤檢測位,用于在通信過程中簡單判斷數據是否出錯。校驗位的位置在數據位之后、停止位之前。可以選擇無校驗(None)、偶校驗(Even)、奇校驗(Odd)。
校驗方式 | 要求總“1”個數為... | 示例(數據位:01000001 → 有兩個“1”) |
---|---|---|
偶校驗(Even) | 偶數個“1” | 校驗位 =?0(使總數仍為偶數) |
奇校驗(Odd) | 奇數個“1” | 校驗位 =?1(使總數變為奇數) |
????????接收端收到后會重新計算并比對校驗位,若不一致則判定為傳輸錯誤。即使數據吃錯,也不會糾正錯誤,就僅僅簡單的校驗而已。
2.3.6停止位
????????停止位(Stop Bit) 是 UART 數據幀中的最后一個部分,用于標識一次數據傳輸的結束,同時為下一次通信提供時間間隔。電平狀態固定為高電平(1);長度可選為 1 位、1.5 位 或?2 位。
3.STM32的UART
? ? ? ? 作者使用的是STM32F103ZET6為微控制器的開發板,該微控制器內置了3個通用同步/異步收發器(USART1、USART2和USART3),和2個通用異步收發器(UART4和UART5)。
????????UART 只支持異步串行通信,而USART 是 UART 的“升級版”,既支持異步也支持同步通信,功能更強大。在這里就把USART當作UART用就好。
? ? ? ? 附上框圖,雖然我沒咋看懂。
4.HAL庫中常用的操作UART的函數
? ? ? ? 打開HAL庫的stm32f1xx_hal_uart.c文件。
4.1UART初始化函數 --?HAL_UART_Init
HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart);
????????這個函數是 STM32 HAL 庫中用于 初始化 UART 外設 的核心函數。主要配置使用哪個UART、波特率、數據位、校驗位、停止位、CTS/RTS硬件流控位和收發模式。
? ? ? ? 函數的參數 UART_HandleTypeDef *huart 是指向一個 UART 句柄結構體的指針,該結構體包含了 UART 的配置信息和運行狀態。
? ? ? ? 函數的返回值(HAL_StatusTypeDef):
返回值 | 含義 |
---|---|
HAL_OK | 初始化成功 |
HAL_ERROR | 初始化失敗(如參數錯誤、硬件故障) |
HAL_BUSY | UART 正在被使用 |
HAL_TIMEOUT | 操作超時 |
4.2硬件初始化回調函數 -- HAL_UART_MspInit
__weak void HAL_UART_MspInit(UART_HandleTypeDef *huart);
? ? ? ? 這個函數是 HAL 庫中 UART 的底層硬件初始化函數,必須由用戶根據實際硬件平臺實現,用于配置 GPIO、時鐘、中斷等。這是一個公共的函數,通過HAL_UART_Init函數進行調用。同時也是虛函數,意思是要我們自己寫函數的內容。
????????函數的參數 UART_HandleTypeDef *huart 是指向一個 UART 句柄結構體的指針,該結構體包含了 UART 的配置信息和運行狀態。
4.3發送數據函數 --?HAL_UART_Transmit?
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
????????該函數用于 通過 UART 以阻塞方式發送一組數據(一個字節數組),直到全部發送完成或發生錯誤/超時。使用簡單,適合 不使用中斷或 DMA 的場景。
參數說明:
參數名 | 類型 | 說明 |
---|---|---|
huart | UART_HandleTypeDef* | UART 句柄指針,指向已配置好的 UART 實例(如?&huart1 ) |
pData | uint8_t* | 指向要發送數據的緩沖區(字節數組) |
Size | uint16_t | 要發送的數據長度(字節數) |
Timeout | uint32_t | 等待發送完成的最大時間(單位:ms),設為?HAL_MAX_DELAY ?表示無限等待 |
4.4接收數據的函數 --?HAL_UART_Receive
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
????????該函數用于 通過 UART 以阻塞方式接收指定數量的字節數據。會一直等待直到:接收到指定數量的數據(Size 字節)或發生錯誤 / 超時。
參數說明:
huart | UART_HandleTypeDef* | UART 句柄指針(如?&huart1 ) |
pData | uint8_t* | 指向接收緩沖區的指針(用于存儲接收到的數據) |
Size | uint16_t | 要接收的數據長度(字節數) |
Timeout | uint32_t | 接收等待最大時間(單位:ms),設為?HAL_MAX_DELAY ?表示無限等待 |
4.5使能中斷源 --?__HAL_UART_ENABLE_IT
__HAL_UART_ENABLE_IT(__HANDLE__, __INTERRUPT__)
? ? ? ? 這是一個宏函數。該宏用于直接使能 UART 的某個中斷源。
參數說明:
__HANDLE__:就是 UART的句柄指針 UART_HandleTypeDef* 。
__INTERRUPT__:中斷源?
宏定義 | 中斷名稱 | 觸發條件 | 是否常用 |
---|---|---|---|
UART_IT_CTS | CTS 變化中斷 | 當 CTS 引腳電平變化時觸發(硬件流控相關) | ? 較少使用 |
UART_IT_LBD | LIN 斷點檢測中斷 | 檢測到 LIN 總線斷點標志(用于 LIN 協議) | ? 特定場景 |
UART_IT_TXE | 發送緩沖區空中斷 | 當發送寄存器為空,可以寫入新數據時觸發 | ? 常用 |
UART_IT_TC | 發送完成中斷 | 整個數據幀傳輸完成后觸發 | ? 常用 |
UART_IT_RXNE | 接收緩沖區非空中斷 | 當收到一個字節數據時觸發 | ? 最常用 |
UART_IT_IDLE | 空閑總線檢測中斷 | 當 UART 接收線上檢測到空閑時觸發(常用于接收不定長數據幀) | ? 高級應用 |
UART_IT_PE | 校驗錯誤中斷 | 接收到的數據發生奇偶校驗錯誤時觸發 | ?? 錯誤檢測 |
UART_IT_ERR | 錯誤中斷(綜合) | 包括幀錯誤、噪聲錯誤、溢出錯誤等 | ?? 錯誤處理 |
4.6獲取UART的狀態標志 --?__HAL_UART_GET_FLAG
__HAL_UART_GET_FLAG(__HANDLE__, __FLAG__)
????????用于讀取 UART 狀態標志位的宏,常用于輪詢或中斷中判斷事件是否發生,是實現串口通信控制和錯誤檢測的關鍵工具。
參數說明:
__HANDLE__:就是 UART的句柄指針 UART_HandleTypeDef* 。
__FLAG__:
宏定義 | 對應標志 | 描述 |
---|---|---|
UART_FLAG_CTS | CTS 標志位 | CTS 引腳狀態變化(硬件流控) |
UART_FLAG_LBD | LIN 斷點標志 | LIN 總線斷點檢測 |
UART_FLAG_TXE | 發送緩沖區空標志 | 表示可以寫入新數據 |
UART_FLAG_TC | 發送完成標志 | 整幀數據發送完成 |
UART_FLAG_RXNE | 接收緩沖區非空標志 | 表示已接收到一個字節 |
UART_FLAG_IDLE | 空閑總線標志 | UART 總線空閑檢測(常用于不定長接收) |
UART_FLAG_ORE | 溢出錯誤標志 | 接收緩沖區溢出 |
UART_FLAG_NE | 噪聲錯誤標志 | 接收到噪聲干擾 |
UART_FLAG_FE | 幀錯誤標志 | 數據格式錯誤 |
UART_FLAG_PE | 校驗錯誤標志 | 奇偶校驗失敗 |
4.7清除指定的 UART 狀態標志位 --?__HAL_UART_CLEAR_FLAG
__HAL_UART_CLEAR_FLAG(__HANDLE__, __FLAG__)
????????該宏用于 清除指定的 UART 狀態標志位。在某些中斷或輪詢操作中,需要手動清除標志以避免重復觸發或狀態錯誤。
參數說明:
__HANDLE__:就是 UART的句柄指針 UART_HandleTypeDef* 。
__FLAG__:
宏定義 | 對應標志 | 是否需要手動清除 | 說明 |
---|---|---|---|
UART_FLAG_CTS | CTS 標志 | ? 是 | 清除 CTS 中斷標志 |
UART_FLAG_LBD | LIN 斷點標志 | ? 是 | 清除 LIN 檢測標志 |
UART_FLAG_TC | 發送完成標志 | ? 是 | 清除發送完成標志 |
UART_FLAG_IDLE | 空閑總線標志 | ? 是 | 常用于接收不定長數據幀后需清除 |
UART_FLAG_RXNE | 接收緩沖區非空標志 | ? 否 | 讀取 DR 寄存器自動清除 |
UART_FLAG_TXE | 發送緩沖區空標志 | ? 否 | 寫入 DR 自動清除 |
UART_FLAG_ORE | 溢出錯誤標志 | ? 是 | 清除溢出標志 |
UART_FLAG_NE | 噪聲錯誤標志 | ? 是 | 清除噪聲錯誤標志 |
UART_FLAG_FE | 幀錯誤標志 | ? 是 | 清除幀錯誤標志 |
UART_FLAG_PE | 校驗錯誤標志 | ? 是 | 清除奇偶校驗錯誤標志 |
5.發送接收數據實驗 并 打開串口printf功能
5.1硬件連接
? ? ? ? 一般地,STM32處理器的PA9和PA10就是對應的USART的TX和RX引腳。而且帶有type-c USB線直接連接到電腦上進行調試的功能。如果讀者使用的是最小系統板,就用USB轉TTL再進行連線到核心板就好,功能是一樣的。
5.2代碼編寫
5.2.1配置UART
????????使用上面介紹的HAL_UART_Init配置UART1。
UART_HandleTypeDef g_uart1_handle; //UART1句柄
/*** @brief 串口1初始化函數* @param baudrate: 波特率, 根據自己需要設置波特率值* @retval 無*/
void uart1_init(unsigned int baudrate)
{g_uart1_handle.Instance = USART1; //配置的是USART1g_uart1_handle.Init.BaudRate = baudrate; //波特率g_uart1_handle.Init.WordLength = UART_WORDLENGTH_8B; //數據位為8位g_uart1_handle.Init.StopBits = UART_STOPBITS_1; //停止位為1位g_uart1_handle.Init.Parity = UART_PARITY_NONE; //無校驗位g_uart1_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE; //不使用CTS/RTS硬件流控位g_uart1_handle.Init.Mode = UART_MODE_TX_RX; //UART發送和接收HAL_UART_Init(&g_uart1_handle); //調用初始化函數進行初始化
}
????????再使用HAL_UART_MspInit進行底層硬件初始化,進行打開時鐘,配置GPIO和打開中斷。
? ? ? ? 對于發送數據引腳PA9,要求是推挽復用輸出模式,上拉模式,速度中速高速都行。
? ? ? ? 對于 接收數據引腳PA10,要求是復用輸入模式,上拉模式。
? ? ? ? 要使用HAL_NVIC_EnableIRQ函數打開USART1的中斷,并設置中斷優先級,然后再使用宏函數打開具體的UART中斷。這里打開的是空閑中斷和接收中斷。
*** @brief UART底層初始化函數* @param huart: UART句柄類型指針* @note 此函數會被HAL_UART_Init()調用* 完成時鐘使能,引腳配置,中斷配置* @retval 無*/
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{if(huart->Instance == USART1){/* 1.打開時鐘 */__HAL_RCC_USART1_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();/* 2.配置GPIO */GPIO_InitTypeDef gpio_handle = {0};gpio_handle.Pin = UART1_TX_PIN;gpio_handle.Mode = GPIO_MODE_AF_PP;gpio_handle.Pull = GPIO_PULLUP;gpio_handle.Speed = GPIO_SPEED_FREQ_MEDIUM;HAL_GPIO_Init(UART1_TX_PORT, &gpio_handle);gpio_handle.Pin = UART1_RX_PIN;gpio_handle.Mode = GPIO_MODE_AF_INPUT;gpio_handle.Pull = GPIO_PULLUP;HAL_GPIO_Init(UART1_RX_PORT, &gpio_handle);/* 3.打開中斷 */HAL_NVIC_SetPriority(USART1_IRQn, 2, 2);HAL_NVIC_EnableIRQ(USART1_IRQn);__HAL_UART_ENABLE_IT(huart, UART_IT_RXNE); //打開接收中斷__HAL_UART_ENABLE_IT(huart, UART_IT_IDLE); //打開空閑中斷}
}
5.2.2中斷函數
? ? ? ? 打開了接收中斷之后,當接收到數據時,就跳到中斷函數進行接收數據。當接收完成后,即進入空閑中斷。在空閑中斷中可進行其他操作。
? ? ? ? 這里的邏輯比較簡單,當觸發了接收緩沖區非空中斷(接收到1字節數據),就進行接收數據的操作。數據一字節一字節的拷貝進g_uart1_rx_buf數組中,用于存儲接收的數據。接收中斷的標志會自動的清除。
? ? ? ? 當觸發空閑總線檢測中斷(數據接收完成),就進行打印操作,并且清空用于存儲接收數據的數組。然后要手動的清除空閑中斷標志,否則程序會一直在這里。
/*** @brief 串口1中斷服務函數* @note 在此使用接收中斷,實現不定長數據收發* @param 無* @retval 無*/
void USART1_IRQHandler(void)
{unsigned char recv_data;if(__HAL_UART_GET_FLAG(&g_uart1_handle, UART_FLAG_RXNE) != RESET){if(g_uart1_rx_len >= sizeof(g_uart1_rx_buf))g_uart1_rx_len = 0;HAL_UART_Receive(&g_uart1_handle, &recv_data, 1, 1000);g_uart1_rx_buf[g_uart1_rx_len++] = recv_data;}if(__HAL_UART_GET_FLAG(&g_uart1_handle, UART_FLAG_IDLE) != RESET){printf("recv:%s\r\n", g_uart1_rx_buf);uart1_clear_rx_buf();__HAL_UART_CLEAR_IDLEFLAG(&g_uart1_handle);}
}
5.2.3重定義fputc -- 支持printf函數
????????fputc() 是 printf() 的底層輸出函數通過重寫該函數,可以將 printf() 輸出重定向到串口,便于調試和日志輸出。
/*** @brief 重定義fputc函數* @note printf函數最終會通過調用fputc輸出字符串到串口*/
int fputc(int ch, FILE *f)
{while ((USART1->SR & 0X40) == 0); /* 等待上一個字符發送完成 */USART1->DR = (uint8_t)ch; /* 將要發送的字符 ch 寫入到DR寄存器 */return ch;
}
????????USART1->SR 是 UART 的狀態寄存器(Status Register);0x40 對應的是 TXE(Transmit Data Register Empty)標志位。當 TXE=1 表示 DR 寄存器為空,即可以寫入新數據。將字符 ch 寫入數據寄存器(Data Register),開始通過USART1向外發送。
6.整體代碼 && 實驗現象
6.1uart1.h
? ? ? ? 主要進行了UART1的引腳宏定義和函數聲明。
#ifndef __UART1_H__
#define __UART1_H__#include "stdio.h"
#include "sys.h"/**********************宏定義**************************************/
/* 引腳定義 */
#define UART1_TX_PORT GPIOA
#define UART1_TX_PIN GPIO_PIN_9#define UART1_RX_PORT GPIOA
#define UART1_RX_PIN GPIO_PIN_10/* UART收發緩沖大小 */
#define UART1_RX_BUF_SIZE 128
#define UART1_TX_BUF_SIZE 64/* 錯誤代碼 */
#define UART1_EOK 0 /* 沒有錯誤 */
#define UART1_ERROR 1 /* 通用錯誤 */
#define UART1_ETIMEOUT 2 /* 超時錯誤 */
#define UART1_EINVAL 3 /* 參數錯誤 *//**********************函數聲明**************************************/
void uart1_init(unsigned int baudrate); /* 串口初始化函數 */#endif
6.2uart1.c
? ? ? ? 操作USART1的函數。
#include "sys.h"
#include "uart1.h"
#include "string.h"/* 全局變量 */
unsigned char g_uart1_rx_buf[UART1_RX_BUF_SIZE]; //保存接收的數據
unsigned short g_uart1_rx_len = 0; //接收數據的長度
UART_HandleTypeDef g_uart1_handle; //UART1句柄/*** @brief 重定義fputc函數* @note printf函數最終會通過調用fputc輸出字符串到串口*/
int fputc(int ch, FILE *f)
{while ((USART1->SR & 0X40) == 0); /* 等待上一個字符發送完成 */USART1->DR = (uint8_t)ch; /* 將要發送的字符 ch 寫入到DR寄存器 */return ch;
}/*** @brief 串口1初始化函數* @param baudrate: 波特率, 根據自己需要設置波特率值* @retval 無*/
void uart1_init(unsigned int baudrate)
{g_uart1_handle.Instance = USART1; //配置的是USART1g_uart1_handle.Init.BaudRate = baudrate; //波特率g_uart1_handle.Init.WordLength = UART_WORDLENGTH_8B; //數據位為8位g_uart1_handle.Init.StopBits = UART_STOPBITS_1; //停止位為1位g_uart1_handle.Init.Parity = UART_PARITY_NONE; //無校驗位g_uart1_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE; //不使用CTS/RTS硬件流控位g_uart1_handle.Init.Mode = UART_MODE_TX_RX; //UART發送和接收HAL_UART_Init(&g_uart1_handle); //調用初始化函數進行初始化
}/*** @brief UART底層初始化函數* @param huart: UART句柄類型指針* @note 此函數會被HAL_UART_Init()調用* 完成時鐘使能,引腳配置,中斷配置* @retval 無*/
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{if(huart->Instance == USART1){/* 1.打開時鐘 */__HAL_RCC_USART1_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();/* 2.配置GPIO */GPIO_InitTypeDef gpio_handle = {0};gpio_handle.Pin = UART1_TX_PIN;gpio_handle.Mode = GPIO_MODE_AF_PP;gpio_handle.Pull = GPIO_PULLUP;gpio_handle.Speed = GPIO_SPEED_FREQ_MEDIUM;HAL_GPIO_Init(UART1_TX_PORT, &gpio_handle);gpio_handle.Pin = UART1_RX_PIN;gpio_handle.Mode = GPIO_MODE_AF_INPUT;gpio_handle.Pull = GPIO_PULLUP;HAL_GPIO_Init(UART1_RX_PORT, &gpio_handle);/* 3.打開中斷 */HAL_NVIC_SetPriority(USART1_IRQn, 2, 2);HAL_NVIC_EnableIRQ(USART1_IRQn);__HAL_UART_ENABLE_IT(huart, UART_IT_RXNE); //打開接收中斷__HAL_UART_ENABLE_IT(huart, UART_IT_IDLE); //打開空閑中斷}
}/*** @brief UART1接收緩沖區清除* @param 無* @retval 無*/
void uart1_clear_rx_buf(void)
{memset(g_uart1_rx_buf, 0, sizeof(g_uart1_rx_buf));g_uart1_rx_len = 0;
}/*** @brief 串口1中斷服務函數* @note 在此使用接收中斷,實現不定長數據收發* @param 無* @retval 無*/
void USART1_IRQHandler(void)
{unsigned char recv_data;if(__HAL_UART_GET_FLAG(&g_uart1_handle, UART_FLAG_RXNE) != RESET){if(g_uart1_rx_len >= sizeof(g_uart1_rx_buf))g_uart1_rx_len = 0;HAL_UART_Receive(&g_uart1_handle, &recv_data, 1, 1000);g_uart1_rx_buf[g_uart1_rx_len++] = recv_data;}if(__HAL_UART_GET_FLAG(&g_uart1_handle, UART_FLAG_IDLE) != RESET){printf("recv:%s\r\n", g_uart1_rx_buf);uart1_clear_rx_buf();__HAL_UART_CLEAR_IDLEFLAG(&g_uart1_handle);}
}
6.3main.c
? ? ? ? 在主函數中調用uart1_init函數,傳遞的參數115200是波特率。
#include "main.h"int main(void)
{HAL_Init(); /* 初始化HAL庫 */stm32_clock_init(RCC_PLL_MUL9); /* 設置時鐘, 72Mhz */uart1_init(115200);while(1){delay_ms(10);}
}
6.4實驗現象
????????首先在KEIL5中魔術棒中勾選 Use MicroLIB選項。
? ? ? ? 寫好程序之后下載程序到開發板,然后打開電腦的串口調試助手,并且按照上面配置的波特率、停止位、數據位、校驗位打開串口。
? ? ? ? 之后發送數據,對應的接收區會有 recv:[數據]返回。就正常了。