STM32---串口通信USART

目錄

一、串口通信協議????????

二、USART模塊介紹

(1)移位寄存器

(2)控制電路

(3)波特率

(4)C語言接口

三、串口的引腳初始化

(1)引腳分布表

(2)重映射表

(3)GPIO配置表

(4)C語言接口使用

四、標志位的使用

(1)讀寫標志位

(2)錯誤標志位

五、發送數據代碼

六、接收數據代碼


一、串口通信協議????????

? ? ? ? 在學習網絡通信的時候,我們曾認識到兩臺主機想要進行通信,必須要有協議的存在,否則對方根本不知道你說了啥,因為在網絡中沒有信息的概念,只有二進制電平信號。如果不規定協議,對方的操作系統就不知道如何解析該二進制信號。于是演變出來OSI的7層模型,每一層都相當于一層協議,對數據包進行封裝,從而讓對方的同層協議可以解析提取真正想要的數據。

????????那么我們STM32單片機自然也可以認為屬于網絡協議中的物理層協議。因為他并沒有經過交換機路由器等設備,僅僅只是把兩臺主機直連,所以他并不可能在數據鏈路層、或者網絡層。但是也有人認為他屬于數據鏈路層,以為他有數據幀封裝,盡管這個封裝十分簡單。而且他沒有mac地址其實是因為他沒有負責的連接環境,但是本質上他這個簡單的協議是可以做到傳輸mac地址的。其實這種理解也是有道理的,因為規定上物理層沒有任何協議存在,是單純的數據流傳輸。

? ? ? ? 真實的物理連接圖:

????????正是因為它屬于物理層協議,那么可以預見的是他的協議必然很簡單。我們來看看他的協議格式:

????????它的協議格式非常簡單,由一位低電平起始位+7-8位數據位+(一位校驗位)+一位高電平停止位組成。

? ? ? ? 其中這里的數據位為7-8位是可以選擇的,不過我們一般都是要傳遞一個字節,所以一般情況下只會選擇8位數據位,至于校驗位,如果你的精確度要求高可以選擇,通常來說并無較大差異。

二、USART模塊介紹

????????在結構圖中可以看到UART有三個,APB1和APB2線上都存在。可以根據你對時鐘頻率的不同選取。

(1)移位寄存器

????????在這幅圖中有兩個移位寄存器,他的作用就是接收和發送數據。

????????當我們想要發送數據的時候,就把值填入發送寄存器。之后該模塊會自動把該寄存器的數據在時鐘的頻率下,一位位得把數據的二進制流交給控制電路。

? ? ? ? 反過來,接收數據的時候,是先交給到了控制電路,控制電路對接收到的數據幀,進行解包(去除起始位、停止位、并檢驗校驗位是否正確),把數據取出交給接收寄存器,然后由該寄存器把數據向上傳遞即可。

? ? ? ? 在這個過程中兩個寄存器的作用主要是串轉并、并轉串。因為在物理線路中的傳遞都是二進制流的串行數據,而用戶想看到的則是8位一起的并行數據。

(2)控制電路

? ? ? ? 控制電路主要就是進行封包和解包分用的。在這里可以通過配置寄存器來決定數據包的格式:數據位是7位還是8位?有沒有校驗位?、停止位是多少個時鐘周期的高電平?

(3)波特率

? ? ? ? 波特率指的是一分鐘的時間,比特位傳輸的數量。比如你的串口選擇的波特率是9600,那么他一分鐘能傳遞的比特位就是9600個,即9600/8=1200個字節。大多數情況下波特率都會被配置成9600、115200、921600,這個和時鐘的頻率有關,盡可能選擇可以由時鐘頻率直接分頻得到的,精確度較高。

? ? ? ? 在這幅圖中,波特率是由時鐘經過波特率寄存器BRR和一個16分頻的分頻器得到的。因為STM32的時鐘頻率往往是36、72MHz比較大,經過這些分頻降低頻率更好用。不過如果你對數據的傳輸時間限制很短,可以嘗試較高的頻率。

(4)C語言接口

在庫函數中可以找到一個USART_Init,他就是用來配置UART(上述)模塊的函數。可以在這里設置波特率、數據位長度、校驗方式、接收還是發送數據等。

當然還需要一個時鐘總開關使能

USART_Cmd(USART1,ENABLE);//使能USART模塊

三、串口的引腳初始化

? ? ? ? 我們在上面已經了解了UART模塊的配置方法。那么既然要向外傳輸數據,必然會有引腳暴露出來供我們使用,那么他們是誰呢?

????????USART的引腳有這5個,其中Tx和Rx最為熟悉,是用來傳輸數據的。而硬件流控我們暫時并不會涉及到,也不過多講解。同步模式的時鐘線,則是如果你想讓兩個STM32單片機進行數據交流,則可以用這個時鐘線把兩臺主機連接到一起,讓他們都遵循一個時鐘,在該時鐘的指導下進行串口通信,保證數據的準確性。

(1)引腳分布表

在數據手冊中有這樣兩幅圖,他們表示了當前芯片的封裝情況、重映射情況。

由于他比較多,我直接把和UASRT相關的引腳內容挑出來看,所以知道了我們在不使用重映射的情況下USART的輸入輸出引腳是接在PA9和PA10上面的。如果你就想使用默認情況,則直接配置PA9和PA10兩個引腳即可。

當然,在重映射后他們的位置則變為了PB6和PB7。注意你如果把他們配置成了USART的引腳,則原本的GPIO功能是無法使用的。

(2)重映射表

在上面直接看引腳分布表比較麻煩,可以直接到使用手冊中查看。內容是一樣的。

(3)GPIO配置表

????????我們已經找到了其引腳,配置成什么模式呢?

在使用手冊中同樣有一個表格,明確說明了各種外設在使用GPIO的時候,應當被配置為什么模式。

在這里我們看到全雙工模式下,Tx要配置成推挽復用輸出、Rx要配置成上拉輸入。

????????復用推挽輸出和通用推挽輸出的區別就是:一個是由CPU直接控制引腳的電平高低,另一個把引腳電平的控制權交給外設模塊自己操作,更加方便。

(4)C語言接口使用

默認情況:

重映射情況:

四、標志位的使用

????????在USART的框圖中我們曾有一部分沒有講解,就是右上角的標志位。通過讀取標志位,可以讓我們時刻檢查到USART模塊的運行情況。

(1)讀寫標志位

TxE:檢查能否填入數據到發送寄存器

TC:檢查檔次發送過程是否結束

RxNE:

(2)錯誤標志位

????????我們在通過USART協議傳輸數據的時候,難免會出現某些原因,使得數據的發送端和接收端并不一致,我們就認為他出錯了。雖然USART的控制電路會自動檢測錯誤,但是我們上層應用要想知道仍需要查看這些標志位來獲取狀態。

? ? ? ? 錯誤標志位是一個協議中非常重要的存在。通過檢驗錯誤標志位,你可以對不同的錯誤做出不同的處理,比如:如果接受數據錯誤,你可以選擇向對端發送消息,告訴他你的數據錯了,請重新發。有沒有回想到我們之前學習TCP也是這樣的!

PE:

FE:

比如沒有接收到停止位,就是一種幀格式錯誤。

NE:

我們實際在接受一個USART協議的信號的時候,會在一個時鐘周期內多次檢測,看看每次檢測的結果是不是一樣的,如果不一樣則表示有噪音,該數據不可信。

ORE:

當接受寄存器中有數據沒有被上層應用取走,他會停留在原地(字節1),如果有數據又來了,他就保存在了接收端的移位寄存器(字節2),此時仍然沒有問題。但是如果繼續來了數據(字節3),他就會覆蓋掉移位寄存器中的字節2,此時控制電路就會監測到該情況,并把ORE置1。

五、發送數據代碼

向發送寄存器寫入數據的函數

對上述代碼進行封裝:

void Init_USART()
{//USART配置RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);USART_InitTypeDef USART_InitStruct;USART_InitStruct.USART_BaudRate=115200;USART_InitStruct.USART_Mode=USART_Mode_Tx | USART_Mode_Rx;USART_InitStruct.USART_WordLength=USART_WordLength_8b;USART_InitStruct.USART_Parity=USART_Parity_No;USART_InitStruct.USART_StopBits=USART_StopBits_1;USART_Init(USART1,&USART_InitStruct);//GPIO配置RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);//使能USARTUSART_Cmd(USART1,ENABLE);}void My_USART_SendBytes(USART_TypeDef* USARTx,uint8_t* pData,uint16_t Number)
{for(uint16_t i=0;i<Number;i++){//不為空的時候就在while循環中出不來while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);//走到這說明發送寄存器為空了USART_SendData(USARTx,pData[i]);//如果移位寄存器沒有清空,就不退出這個函數while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);}
}int main(void)
{Init_USART();uint8_t datas[]={10,50,90,100,66};while(1){My_USART_SendBytes(USART1,datas,5);}
}

如果你上述步驟都正確的話你是可以成功的通過STM32單片機向電腦主機發送消息的。結果如下:

六、接收數據代碼

具體使用如下:

示例代碼:

void Init_USART()
{//USART配置RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);USART_InitTypeDef USART_InitStruct;USART_InitStruct.USART_BaudRate=115200;USART_InitStruct.USART_Mode=USART_Mode_Tx | USART_Mode_Rx;USART_InitStruct.USART_WordLength=USART_WordLength_8b;USART_InitStruct.USART_Parity=USART_Parity_No;USART_InitStruct.USART_StopBits=USART_StopBits_1;USART_Init(USART1,&USART_InitStruct);//GPIO配置RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);//使能USARTUSART_Cmd(USART1,ENABLE);}void My_USART_SendBytes(USART_TypeDef* USARTx,uint8_t* pData,uint16_t Number)
{for(uint16_t i=0;i<Number;i++){//不為空的時候就在while循環中出不來while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);//走到這說明發送寄存器為空了USART_SendData(USARTx,pData[i]);//如果移位寄存器沒有清空,就不退出這個函數while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);}
}void My_Led_Init(void)
{//GPIO配置RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_OD;GPIO_InitStruct.GPIO_Pin=GPIO_Pin_13;GPIO_InitStruct.GPIO_Speed=GPIO_Speed_2MHz;GPIO_Init(GPIOC,&GPIO_InitStruct);//初始設置為滅,即GPIOC_Pin_13為高電平GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_SET);
}int main(void)
{My_Led_Init();Init_USART();uint8_t datas[]={10,50,90,100,66};while(1){// My_USART_SendBytes(USART1,datas,5);//接收數據,并處理while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==RESET);uint8_t byteEecv=USART_ReceiveData(USART1);//處理//0滅if(byteEecv==0){GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_SET);}//1亮else if(byteEecv==1){GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_RESET);}}}

如果你的操作正確,則可以看到用串口控制芯片上的LED了。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/77943.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/77943.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/77943.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

流程架構是什么?為什么要構建流程架構,以及如何構建流程結構?

本文從&#xff1a;流程架構是什么&#xff1f;為什么要構建流程架構&#xff1f;如何構建流程結構三個方面來介紹。 一、首先&#xff0c;我們來了解流程架構是什么&#xff1f; 流程架構是人體的骨架&#xff0c;是大樓的砌筑&#xff0c;是課本的目錄&#xff0c;是流程管理…

網絡結構及安全科普

文章目錄 終端聯網網絡硬件基礎網絡協議示例&#xff1a;用戶訪問網頁 OSI七層模型網絡攻擊&#xff08;Hack&#xff09;網絡攻擊的主要類別&#xff08;一&#xff09;按攻擊目標分類&#xff08;二&#xff09;按攻擊技術分類 網絡安全防御 典型攻擊案例相關名詞介紹網絡連接…

同z科技面經

同z科技-2025-4-23 1.自我介紹 個人信息 校園經歷 實習經歷 項目經歷 個人技能掌握 目前學習技術 2.封裝緩存工具類怎么封裝的 先介紹使用緩存的問題 解決的邏輯 封裝的邏輯 應用 緩存穿透&#xff1a; 緩存雪崩&#xff1a; 緩存擊穿&#xff1a; https://www…

基于LoRA的Llama 2二次預訓練實踐:高效低成本的大模型領域適配

引言 近年來&#xff0c;大語言模型&#xff08;LLM&#xff09;如Meta的Llama 2系列憑借其強大的生成和理解能力成為NLP領域的核心工具。然而&#xff0c;直接將通用預訓練模型應用于垂直領域&#xff08;如醫療、法律、金融&#xff09;時&#xff0c;常面臨領域知識不足的問…

Python爬蟲(2)Python爬蟲入門:從HTTP協議解析到豆瓣電影數據抓取實戰

目錄 一、背景與需求?二、 Web基礎與HTTP協議核心解析?2.1 HTTP協議&#xff1a;數據交互的基石?2.2 為何爬蟲需理解HTTP協議&#xff1f;? 三、 Python爬蟲實戰&#xff1a;Requests庫核心用法?3.1 安裝與環境配置?3.2 案例1&#xff1a;GET請求抓取豆瓣電影Top250?3.3…

深度學習--ResNet殘差神經網絡解析

文章目錄 前言一、什么是ResNet網絡二、傳統卷積神經網絡存在的問題1、梯度消失和梯度爆炸2、退化問題 三、如何解決問題四、殘差結構五、18層殘差網絡1、解釋2、隔層相加優點3、隔層相加數值增大問題 六、18層殘差網絡以外的表格示例七、BN層&#xff08;Batch Normalization&…

【go】go run-gcflags常用參數歸納,go逃逸分析執行語句,go返回局部變量指針是安全的

go官方參考文檔&#xff1a; https://pkg.go.dev/cmd/compile 基本語法 go run 命令用來編譯并運行Go程序&#xff0c;-gcflags 后面可以跟一系列的編譯選項&#xff0c;多個選項之間用空格分隔。基本語法如下&#xff1a; go run -gcflags "<flags>" main.…

K8S探針的應用

目錄&#xff1a; 1、探針的簡介2、啟用探針2.1、啟用就緒探針2.2、啟用存活探針2.3、啟用啟動探針&#xff08;可選&#xff09; 1、探針的簡介 在Kubernetes中&#xff0c;探針&#xff08;Probes&#xff09;是用來檢查容器健康狀況的工具&#xff0c;它們幫助Kubernetes了…

體積小巧的 Word 轉 PDF 批量工具

軟件介紹 今天給大家介紹一款能批量把 Word 文檔轉換成 PDF 的實用小工具。 軟件特點 這款 Word 批量轉 PDF 軟件&#xff0c;身材小巧&#xff0c;體積不到 1M&#xff0c;還沒界面呢&#xff01;使用時&#xff0c;只要把軟件和要轉換的 Word 文檔放在一個文件夾&#xff…

JMeter介紹

文章目錄 1. JMeter簡介2. JMeter 下載3. JMeter修改編碼集4. 啟動并運行JMeter 1. JMeter簡介 JMeter 是 Apache 組織使用 Java 開發的一款測試工具&#xff1a; 1、可以用于對服務器、網絡或對象模擬巨大的負載 2、通過創建帶有斷言的腳本來驗證程序是否能返回期望的結果 優…

URP-UGUI相關知識

一、UGUI的基本組成部分 Canvas &#xff08;畫布&#xff09;所有UI都需要放在Canvas畫布下面&#xff0c;不然無法顯示EventSystem 所有的事件響應系統都需要依賴于EventSystem,若刪除該組件&#xff0c;交互效果就 不會顯示 1.Canvas(畫…

ShenNiusModularity項目源碼學習(20:ShenNius.Admin.Mvc項目分析-5)

ShenNiusModularity項目的系統管理模塊主要用于配置系統的用戶、角色、權限、基礎數據等信息&#xff0c;上篇文章中學習的日志列表頁面相對獨立&#xff0c;而后面幾個頁面之間存在依賴關系&#xff0c;如角色頁面依賴菜單頁面定義菜單列表以便配置角色的權限&#xff0c;用戶…

JavaFX 實戰:從零打造一個功能豐富的英文“劊子手”(Hangman)游戲

大家好&#xff01;今天我們要挑戰一個經典的單詞猜謎游戲——“劊子手”&#xff08;Hangman&#xff09;&#xff0c;并使用 JavaFX 這個強大的 GUI 工具包來賦予它現代化的交互體驗。這個項目不僅有趣&#xff0c;而且是學習和實踐 JavaFX 核心概念的絕佳途徑&#xff0c;涵…

【自我介紹前端界面分享】附源碼

我用夸克網盤分享了「800套HTML模板」&#xff0c;鏈接&#xff1a;https://pan.quark.cn/s/a205a794552c <!DOCTYPE HTML> <html> <head> <title>Miniport</title> <meta http-equiv"content-type" content&q…

安寶特分享|AR智能裝備賦能企業效率躍升

AR裝備開啟智能培訓新時代 在智能制造與數字化轉型浪潮下&#xff0c;傳統培訓體系正面臨深度重構。安寶特基于工業級AR智能終端打造的培訓系統&#xff0c;可助力企業構建智慧培訓新生態。 AR技術在不同領域的助力 01遠程指導方面 相較于傳統視頻教學的單向輸出模式&#x…

今日html筆記

原手寫筆記 ------------------------------------------------------------------------------------------------------- 關于超鏈接的使用 <a href"https://www.luogu.com.cn/" target"_blank">//href屬性指定了超鏈接的目標地址,即當用戶點擊超…

【人工智能】Ollama 負載均衡革命:多用戶大模型服務的高效調度與優化

《Python OpenCV從菜鳥到高手》帶你進入圖像處理與計算機視覺的大門! 解鎖Python編程的無限可能:《奇妙的Python》帶你漫游代碼世界 在 多用戶大模型推理 場景下,負載均衡 是確保高并發、低延遲的關鍵挑戰。本文以 Ollama(一個流行的本地大模型運行框架)為例,深入探討 …

線上救急-AWS限頻

線上救急-AWS限頻 問題 在一個天氣炎熱的下午&#xff0c;我正喝著可口可樂&#xff0c;悠閑地看著Cursor生成代碼&#xff0c;忽然各大群聊中出現了加急?全體的消息&#xff0c;當時就心里一咯噔&#xff0c;點開一看&#xff0c;果然&#xff0c;線上服務出問題&#xff0…

Maven 項目中引入本地 JAR 包

在日常開發過程中&#xff0c;我們有時會遇到一些未上傳到 Maven 中央倉庫或公司私有倉庫的 JAR 包&#xff0c;比如第三方提供的 SDK 或自己編譯的庫。這時候&#xff0c;我們就需要將這些 JAR 包手動引入到 Maven 項目中。本文將介紹兩種常見方式&#xff1a;將 JAR 安裝到本…

解鎖webpack:對html、css、js及圖片資源的抽離打包處理

面試被問到webpack&#xff0c;可別只知道說 HtmlWebpackPlugin 了哇。 前期準備 安裝依賴 npm init -y npm install webpack webpack-cli --save-dev配置打包命令 // package.json {"scripts": {// ... 其他配置信息"build": "webpack --mode pr…