色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

STM32串口通信詳解

哈哈hfgfdf ? 來源:嵌入式學習資料 ? 作者:嵌入式學習資料 ? 2023-08-22 22:53 ? 次閱讀

一.數據通信方式

1.串行與并行通信

按數據傳送的方式,通訊可分為串行通訊與并行通訊。

串行通訊:是指設備之間通過一根數據信號線,地線以及控制信號線,按數據位形式一位一位地傳輸數據的通訊方式,同一時刻只能傳輸一位(bit)數據。

并行通訊:是指使用 8、16、32 及 64 根或更多的數據線(有多少信號為就需要多少信號位)進行傳輸的通訊方式,可以同一時刻傳輸多個數據位的數據。

cac069ce-4002-11ee-852b-dac502259ad0.png

串行通訊與并行通訊的特性對比:

cae6095e-4002-11ee-852b-dac502259ad0.png

并行可以同時發送多位數據所以速度比串行的速度要快很多,但并行要的數據線也更多相對成本會更高,而且并行傳輸對同步要求較高,且隨著通訊速率的提高,信號干擾的問題會顯著影響通訊性能。

2.全雙工、半雙工及單工通訊

單工通信:信息只能單方向傳輸的工作方式,一個固定為發送設備,另一個固定為接收設備,發送端只能發送信息不能接收信息,接收端只能接收信息不能發送信息,只需一根信號線

半雙工通信:可以實現雙向的通信,但不能在兩個方向上同時進行,必須輪流交替進行,其實也可以理解成一種可以切換方向的單工通信,同一時刻必須只能一個方向傳輸,只需一根數據線

全雙工通信:在同一時刻,兩個設備之間可以同時收發數據,全雙工方式無需進行方向的切換,這種方式要求通訊雙方均有發送器和接收器,同時,需要2根數據線。

cb1049e4-4002-11ee-852b-dac502259ad0.png

常見串口通信接口

cb229748-4002-11ee-852b-dac502259ad0.png

3.同步通訊與異步通訊

同步通訊:收發設備雙方會使用一根信號線表示時鐘信號,在時鐘信號的驅動下雙方進行協調,同步數據,通訊中通常雙方會統一規定在時鐘信號的上升沿或下降沿對數據線進行采樣,對應時鐘極性與時鐘相位。

SPI 的同步通信:

cb312ef2-4002-11ee-852b-dac502259ad0.png

異步通訊:不需要時鐘信號進行數據同步,它們直接在數據信號中穿插一些同步用的信號位,或者把主體數據進行打包,以數據幀(串口:起始位 數據 校驗位(可以沒有) 停止位)的格式傳輸數據,某些通訊中還需要雙方約定數據的傳輸速率(波特率),以便更好地同步。

cb3fd52e-4002-11ee-852b-dac502259ad0.png

二.串口通訊協議

通訊協議:分為物理層和協議層。物理層規定通訊系統中具有機械電子功能部分的特性,確保原始數據在物理媒體的傳輸(通俗一點就是硬件部分)。協議層主要規定通訊邏輯,統一收發雙方的數據打包、解包標準(軟件)。

STM32串口簡介

USART-通用同步異步收發器(Universal Synchronous Asynchronous Receiver and Transmitter)是一個串行通信設備,可以靈活地與外部設備進行全雙工數據交換。有別于 USART 還有一個UART(Universal Asynchronous Receiver and Transmitter),它是在 USART 基礎上裁剪掉了同步通信功能(時鐘同步),只有異步通信。簡單區分同步和異步就是看通信時需不需要對外提供時鐘輸出,我們平時用的串口通信基本都是 UART。

串行通信一般是以幀格式傳輸數據,即是一幀一幀的傳輸,每幀包含有起始信號、數據信息、校驗信息(由我們自己設置)、停止信號。

1.物理層

1)RS232標準

很多單片機內部例如我們所用的STM32,以及一些傳感器一般都是TTL電平。

RS232是一種串行數據傳輸形式,稱其為串行連接,最經典的標志就是 9 針孔的 DB9 電纜RS232電壓表示邏輯 1 ,0的范圍大極大的增強了容錯率,主要用于工業設備直接通信。

cb4f8384-4002-11ee-852b-dac502259ad0.png

由上圖可知,TLL與RS-232標準邏輯相反,而且電平也大不相同,若單片機與單片機或其他設備TLL設備通信采用RS-232通信(DB9),肯定先要進行電平的轉化TLL->RS232 RS232->TTL

cb6bd5a2-4002-11ee-852b-dac502259ad0.png

兩個通訊設備的“DB9 接口”之間通過串口信號線建立起連接,串口信號線中使用“RS-232 標準”傳輸數據信號。由于 RS-232 電平標準的信號不能直接被控制器直接識別,所以這些信號會經過一個“電平轉換芯片”轉換成控制器能識別的“TTL 標準”的電平信號,才能實現通訊。

BD9串口線:

cb9486a0-4002-11ee-852b-dac502259ad0.png

2)USB轉串口(重點)

至于為什么是重點因為這是我實驗用的方式重點介紹:

USB轉串口:主要用于設備(STM32)與電腦通信

cbada9aa-4002-11ee-852b-dac502259ad0.png

電平轉換芯片一般有CH340、PL2303、CP2102、FT232

使用的時候電腦要按照電平轉換芯片的驅動(虛擬出一個串口)我這里裝的是CH340

cbc94034-4002-11ee-852b-dac502259ad0.png

原理圖:一定要搞懂下面這張圖

cc220322-4002-11ee-852b-dac502259ad0.png

這里是拿的野火的原理圖,因為我覺得原子的圖畫的不好,不過原理是一致的。

3原生的串口到串口

cc43b274-4002-11ee-852b-dac502259ad0.png

原生的串口通信主要是控制器跟串口的設備或者傳感器通信他們但是TLL電平,不需要經過電平轉換芯片來轉換電平,直接就用TTL電平通信,GPS模塊、GSM模塊、串口轉WIFI模塊、HC04藍牙模塊

2.協議層

串口通訊的協議層中,規定了數據包的內容,它由啟始位、主體數據、校驗位以及停止位組成,通訊雙方的數據包格式要約定一致(一樣的起始位 數據 校驗位 停止位)才能正常收發數據

cc5bec9a-4002-11ee-852b-dac502259ad0.png

1)通訊的起始和停止信號

串口通訊的一個數據包從起始信號開始,直到停止信號結束。數據包的起始信號由一個邏輯 0 的數據位表示,而數據包的停止信號可由 0.5、1、1.5 或 2 個邏輯 1 的數據位表示

1個停止位:停止位位數的默認值。

2個停止位:可用于常規USART模式、單線模式以及調制解調器模式。

0.5個停止位:在智能卡模式下接收數據時使用。

1.5個停止位:在智能卡模式下發送和接收數據時使用。

2)有效數據

在數據包的起始位之后緊接著的就是要傳輸的主體數據內容,也稱為有效數據,有效數據的長度常被約定為 5、6、7 或 8 位長

3)數據校驗

偶校驗:校驗位使得一幀中的7或8個LSB數據以及校驗位中’1’的個數為偶數。

例如:數據=00110101,有4個’1’,如果選擇偶校驗(在USART_CR1中的PS=0),校驗位將是’0’,最后數據檢驗如果數據有偶數個1則數據傳輸沒有出錯(但不是絕對的,如果同時兩個數據為發送錯誤(0變成1)則還是偶數個1)

cc71a56c-4002-11ee-852b-dac502259ad0.png

奇校驗:此校驗位使得一幀中的7或8個LSB數據以及校驗位中’1’的個數為奇數。

例如:數據=00110101,有4個’1’,如果選擇奇校驗(在USART_CR1中的PS=1),校驗位將是’1’,最后數據檢驗如果數據有奇數個1則數據傳輸沒有出錯,但同樣不是絕對的(同時兩個1變成0)

cc93af4a-4002-11ee-852b-dac502259ad0.png

cca655c8-4002-11ee-852b-dac502259ad0.png

傳輸模式:如果USART_CR1的PCE位被置位,如果奇偶校驗失敗USART_SR寄存器中的PE標志被置’1’,并且如果USART_CR1寄存器的PEIE在被預先設置的話,中斷產生(我們可以在相應的中斷服務函數中,寫處理校驗失敗的代碼)

ccc8687a-4002-11ee-852b-dac502259ad0.png

cced708e-4002-11ee-852b-dac502259ad0.png

三.USART 功能框圖(超級重要)

只要把功能框圖分析透徹,寫代碼不就是信手拈來,一定一定要掌握!!!

cd0094fc-4002-11ee-852b-dac502259ad0.png

1.功能引腳:

cd41e9de-4002-11ee-852b-dac502259ad0.png

2.數據寄存器(重點)

cd96675c-4002-11ee-852b-dac502259ad0.png

cdadb1d2-4002-11ee-852b-dac502259ad0.png

cdc8fbea-4002-11ee-852b-dac502259ad0.png

下面這張圖也非常重要理解理解!

ce2acfbe-4002-11ee-852b-dac502259ad0.png

3.控制單元(重點)

發送器

發送器根據M位的狀態發送8位或9位的數據字。當發送使能位(TE)被設置時,發送移位寄存器中的數據在TX腳上輸出,相應的時鐘脈沖在CK腳上輸出。

一個字符幀發送需要三個部分:起始位+數據幀(可能有校驗位)+停止位。每個字符(一個數據幀)之前都有一個低電平的起始位,之后跟著的停止位,其數目可配置,數據幀就是我們要發送的 8 位或 9 位數據,數據是從最低位開始傳輸的,停止位是一定時間周期的高電平。

配置步驟:

1.通過在USART_CR1寄存器上置位UE位來激活USART

ce59636a-4002-11ee-852b-dac502259ad0.png

2.編程USART_CR1的M位來定義字長。

ce6a5ecc-4002-11ee-852b-dac502259ad0.png

3.在USART_CR2中編程停止位的位數。

ce87f0b8-4002-11ee-852b-dac502259ad0.png

4.如果采用多緩沖器通信,配置USART_CR3中的DMA使能位(DMAT)。按多緩沖器通信中的描述配置DMA寄存器,關于DMA下期再詳細講解。

ce9eeb74-4002-11ee-852b-dac502259ad0.png

5.利用USART_BRR寄存器選擇要求的波特率。

ceaf575c-4002-11ee-852b-dac502259ad0.png

發送和接收由一共用的波特率發生器驅動,當發送器和接收器的使能位分別置位時,分別為其產生時鐘。

ced95584-4002-11ee-852b-dac502259ad0.png

cef14fc2-4002-11ee-852b-dac502259ad0.png

這里舉個例子:以115200波特率

cf04601c-4002-11ee-852b-dac502259ad0.png

6.設置USART_CR1中的TE位,發送一個空閑幀幀(一個數據幀長度的高電平)作為第一次數據發送。

cf2f99a8-4002-11ee-852b-dac502259ad0.png

7.把要發送的數據寫進USART_DR寄存器(此動作清除TXE位)。在只有一個緩沖器的情況下,對每個待發送的數據重復步驟7。

cf49855c-4002-11ee-852b-dac502259ad0.png

8.在USART_DR寄存器中寫入最后一個數據字后,要等待TC=1,它表示最后一個數據幀的傳輸結束(移位寄存器中的數據全部發送完畢)。當需要關閉USART或需要進入停機模式之前,需要確認傳輸結束,避免破壞最后一次傳輸。

cf5ed006-4002-11ee-852b-dac502259ad0.png

深入理解TXE位與TC位:

清零TXE位總是通過對數據寄存器的寫操作(CPU 或 DMA)來完成的,當TXE位已經被硬件置1它表明:

● 數據已經從TDR移送到移位寄存器,數據發送已經開始(發送移位寄存器正在一位一位向外傳輸數據)

● TDR寄存器被清空

● 下一個數據可以被寫進USART_DR寄存器而不會覆蓋先前的數據如果TXEIE位被設置,此標志將產生一個中斷。

如果此時USART正在發送數據(發送移位寄存器正在一位一位向外傳輸數據),對USART_DR寄存器的寫操作把數據存進TDR寄存器,并在當前傳輸結束時把該數據復制進移位寄存器,也就是說移位寄存器里面的數據并不會被覆蓋,所以我覺得只要你發送一幀數據等待TXE置1,就算是發送多幀數據時最后也不用等待TC=1。

如果此時USART沒有在發送數據,處于空閑狀態,對USART_DR寄存器的寫操作直接把數據放進移位寄存器,數據傳輸開始,TXE位立即被置起。

當一幀發送完成時(停止位發送后)并且設置了TXE位,TC位被置起,如果USART_CR1寄存器中的TCIE位被置起時,則會產生中斷

使用下列軟件過程清除TC位:

1.讀一次USART_SR寄存器;

2.寫一次USART_DR寄存器。

TC位也可以通過軟件對它寫’0’來清除。此清零方式只推薦在多緩沖器通信模式下使用

接收器

如果將 USART_CR1 寄存器的 RE 位置 1,使能 USART 接收,使得接收器在 RX 線開始搜索起始位。在確定到起始位后就根據 RX 線電平狀態把數據存放在接收移位寄存器內。接收完成后就把接收移位寄存器數據移到 RDR 內,并把 USART_SR 寄存器的 RXNE 位置1,同時如果 USART_CR2 寄存器的 RXNEIE 置 1 的話可以產生中斷。

當一字符被接收到時,

● RXNE位被置1。它表明移位寄存器的內容被轉移到RDR。換句話說,數據已經被接收并且可以被讀出。

● 如果RXNEIE位被設置,產生中斷。

● 在多緩沖器通信時,RXNE在每個字節接收后被置起,并由DMA對數據寄存器的讀操作而清零。

● 在單緩沖器模式里,由軟件讀USART_DR寄存器完成對RXNE位清除,RXNE標志也可以通過對它寫0來清除。RXNE位必須在下一字符接收結束前(接收移位寄存器接收滿)被清零(要將數據讀出),以避免溢出錯誤(移位寄存器的數據會被覆蓋)。

溢出錯誤

如果RXNE還沒有被復位(還沒有讀出DR寄存器的數據),又接收到一個字符,則發生溢出錯誤,數據只有當RXNE位被清零后才能從移位寄存器轉移到RDR寄存器。RXNE標記是接收到每個字節后被置位的。如果下一個數據已被收到或先前DMA請求還沒被服務時,RXNE標志仍是1,溢出錯誤產生。

當溢出錯誤產生時:

ORE位被置位。

● RDR內容將不會丟失。讀USART_DR寄存器仍能得到先前的數據。

● 移位寄存器中以前的內容將被覆蓋。隨后接收到的數據都將丟失。

● 如果RXNEIE位被設置或EIE和DMAR位都被設置,中斷產生。

● 順序執行對USART_SR和USART_DR寄存器的讀操作,可復位ORE位

cf763bba-4002-11ee-852b-dac502259ad0.png

USART相關中斷:

cf95fb76-4002-11ee-852b-dac502259ad0.png

cfb617a8-4002-11ee-852b-dac502259ad0.png

4. USART初始化結構體

cfe6d0dc-4002-11ee-852b-dac502259ad0.png

上面結構體成員要配置的哪個寄存器哪一位前面基本都講了這里不在贅述。

1) USART_BaudRate:波特率設置。一般設置為 2400、9600、19200、115200。標準庫函數會自己計算計算得到 USARTDIV 值,從而寫入USART_BRR 寄存器。

2) USART_WordLength:數據幀字長,可選 8 位或 9 位。它設置了USART_CR1 寄存器的 M 位的值。如果沒有使能奇偶校驗位,一般使用 8 數據位;如果使能了奇偶校驗則一般設置為 9 數據位,最后一位是奇偶校驗位。

3) USART_StopBits:停止位設置,可選 0.5 個、1 個、1.5 個和 2 個停止位,它設定USART_CR2 STOP位,一般我們選擇 1 個停止位。

4) USART_Parity :奇 偶 校 驗 控 制 選 擇 ,USART_CR1 寄存器的 PCE 位和 PS 位的值。

5) USART_Mode:USART 模式選擇,有 USART_Mode_Rx 和 USART_Mode_Tx,允許使用邏輯或運算選擇兩個,USART_CR1 寄存器的 RE 位和 TE 位。

6) USART_HardwareFlowControl:硬件流控制選擇,只有在硬件流控制模式才有效,可選有⑴使能 RTS、⑵使能 CTS、⑶同時使能 RTS 和 CTS、⑷不使能硬件流。

四.USART1收發通信實驗

編程要點: 1) 使能 RX 和 TX 引腳 GPIO 時鐘和 USART 時鐘; 2) 初始化 GPIO,并將 GPIO 復用到 USART 上; 3) 配置 USART 參數初始化結構體; 4) 配置中斷控制器并使能 USART 接收中斷; 5) 使能 USART; 6) 在 USART 接收中斷服務函數實現數據接收和發送。

usart.h

相關宏定義與函聲明: #ifndef _USART_H #define _USART_H #include "stm32f10x.h" #include #define DEBUG_USART1 1 #define DEBUG_USART2 0 #if DEBUG_USART1 // 串口1-USART1 #define DEBUG_USARTx USART1 #define DEBUG_USART_CLK RCC_APB2Periph_USART1 #define DEBUG_USART_APBxClkCmd RCC_APB2PeriphClockCmd #define DEBUG_USART_BAUDRATE 115200 // USART GPIO 引腳宏定義 #define DEBUG_USART_GPIO_CLK (RCC_APB2Periph_GPIOA) #define DEBUG_USART_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd #define DEBUG_USART_TX_GPIO_PORT GPIOA #define DEBUG_USART_TX_GPIO_PIN GPIO_Pin_9 #define DEBUG_USART_RX_GPIO_PORT GPIOA #define DEBUG_USART_RX_GPIO_PIN GPIO_Pin_10 #define DEBUG_USART_IRQ USART1_IRQn #define DEBUG_USART_IRQHandler USART1_IRQHandler #elif DEBUG_USART2 // 串口2-USART2 #define DEBUG_USARTx USART2 #define DEBUG_USART_CLK RCC_APB1Periph_USART2 #define DEBUG_USART_APBxClkCmd RCC_APB1PeriphClockCmd #define DEBUG_USART_BAUDRATE 115200 // USART GPIO 引腳宏定義 #define DEBUG_USART_GPIO_CLK (RCC_APB2Periph_GPIOA) #define DEBUG_USART_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd #define DEBUG_USART_TX_GPIO_PORT GPIOA #define DEBUG_USART_TX_GPIO_PIN GPIO_Pin_2 #define DEBUG_USART_RX_GPIO_PORT GPIOA #define DEBUG_USART_RX_GPIO_PIN GPIO_Pin_3 #define DEBUG_USART_IRQ USART2_IRQn #define DEBUG_USART_IRQHandler USART2_IRQHandler #endif void USART_Config(void); void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t date); void Usart_SendString( USART_TypeDef * pUSARTx, char *str); void Usart_SendHalfWord( USART_TypeDef * pUSARTx, uint16_t date); void Usart_SendArray(USART_TypeDef * pUSARTx,uint8_t *arr,uint16_t num); #endif /* _USART_H */

usart.c

#include "usart.h" #include "led.h" static void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_InitStructure.NVIC_IRQChannel =DEBUG_USART_IRQ; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =0x01; NVIC_InitStructure.NVIC_IRQChannelSubPriority =0x01; NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE; NVIC_Init(&NVIC_InitStructure); } void USART_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; // 打開串口GPIO的時鐘 DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);

// 打開串口外設的時鐘 DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE); // 將USART Tx的GPIO配置為推挽復用模式 GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure); // 將USART Rx的GPIO配置為浮空輸入模式 GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);

// 配置串口的工作參數 // 配置波特率 USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE; // 配置 針數據字長 USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 配置停止位 USART_InitStructure.USART_StopBits = USART_StopBits_1; // 配置校驗位 USART_InitStructure.USART_Parity = USART_Parity_No ; // 配置硬件流控制 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 配置工作模式,收發一起 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 完成串口的初始化配置 USART_Init(DEBUG_USARTx, &USART_InitStructure); //中斷配置 NVIC_Configuration(); //開啟串口接收中斷 USART_ITConfig(DEBUG_USARTx,USART_IT_RXNE, ENABLE); //使能串口 USART_Cmd(DEBUG_USARTx, ENABLE); } //發送一個字節 void Usart_SendByte(USART_TypeDef * pUSARTx,uint8_t date) { USART_SendData(pUSARTx,date); while( USART_GetFlagStatus(pUSARTx,USART_FLAG_TXE)== RESET); } //發送一個16位的數據 void Usart_SendHalfWord(USART_TypeDef * pUSARTx,uint16_t date) { uint16_t tmp_h; uint16_t tmp_l; tmp_h =date>>0x08; tmp_l =date & 0xff; Usart_SendByte(pUSARTx,tmp_h); Usart_SendByte(pUSARTx,tmp_l); } //發送一個8位的數組 void Usart_SendArray(USART_TypeDef * pUSARTx,uint8_t *arr,uint16_t num) { while(num--) { Usart_SendByte( pUSARTx ,*arr++); } while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TC)== RESET); } //發送字符串 void Usart_SendString( USART_TypeDef * pUSARTx, char *str) { while( *str!='?' ) { Usart_SendByte( pUSARTx, *str++); } while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TC)== RESET); } ///重定向c庫函數printf到串口,重定向后可使用printf函數 int fputc(int ch, FILE *f) { /* 發送一個字節數據到串口 */ USART_SendData(DEBUG_USARTx, (uint8_t) ch);

/* 等待發送完畢 */ while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);

return (ch); } ///重定向c庫函數scanf到串口,重寫向后可使用scanf、getchar等函數 int fgetc(FILE *f) { /* 等待串口輸入數據 */ while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_RXNE) == RESET); return (int)USART_ReceiveData(DEBUG_USARTx); } //中斷服務函數 void DEBUG_USART_IRQHandler(void) { uint16_t tmp; if(USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_RXNE) != RESET) { tmp=USART_ReceiveData(DEBUG_USARTx); USART_SendData(DEBUG_USARTx,tmp); while( USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE)== RESET);

} }

d02daf20-4002-11ee-852b-dac502259ad0.png

main.c

#include "stm32f10x.h" #include "led.h" #include "usart.h" #include #define SOFT_DELAY Delay(0x0FFFFF); void Delay(__IO u32 nCount); int main(void) { uint16_t ch;

uint8_t arr[10]={1,2,3,4,5,6,7,8,9,10}; /* LED 端口初始化 */ LED_GPIO_Config(); /*初始化USART 配置模式為 115200 8-N-1,中斷接收*/ USART_Config(); //發送一個字符 printf("發送一個字節:rn"); Usart_SendByte(DEBUG_USARTx ,97); printf("rn"); //發送一個16位數據 Usart_SendHalfWord(DEBUG_USARTx,0xffee); //發送一個數組 Usart_SendArray(DEBUG_USARTx, arr,10); //發送一個字符串 printf("發送一個字符串:rn"); Usart_SendString( DEBUG_USARTx, "hello worldrn"); while(1); }

關于printf函數,scanf函數 重定向問題

MicroLib是缺省c庫的備選庫,它可裝入少量內存中,與嵌入式應用程序配合使用,且這些應用程序不在操作系統中運行。

d044c3e0-4002-11ee-852b-dac502259ad0.png

如果要使用printf函數輸出數據到串口,printf函數默認是輸出到屏幕(標準輸出流—stdout),所以要重定把輸出流改成USART1串口1

當使用 printf 函數時,自動會調用 fputc 函數,而 fputc 函數內又將輸出 設備重定義為 STM32 的 USART1,所以要輸出的數據就會在串口 1 上輸出

d071d998-4002-11ee-852b-dac502259ad0.png

scanf函數(默認鍵盤輸入,我們要重定向到串口接收)類似我就不說了。

實驗效果

d08f6d96-4002-11ee-852b-dac502259ad0.png

d0a71568-4002-11ee-852b-dac502259ad0.png

d0d28388-4002-11ee-852b-dac502259ad0.png

五.向單片機發送指令點亮LED

main.c

#include "stm32f10x.h" #include "led.h" #include "usart.h" #include int main() { uint16_t ch; /* LED 端口初始化 */ LED_GPIO_Config(); /*初始化USART 配置模式為 115200 8-N-1,中斷接收*/ USART_Config(); printf("請輸入指令:rn"); printf("1:紅燈 2:綠燈 3:紅綠燈 其他:指令錯誤rn"); while(1) { ch=getchar(); switch(ch) { case '1': GPIOA->ODR^=GPIO_Pin_8; printf("1:紅燈rn"); break; case '2': printf("2:綠燈rn"); GPIOD->ODR^=GPIO_Pin_2; break; case '3': printf("3:紅綠燈rn"); GPIOA->ODR^=GPIO_Pin_8; GPIOD->ODR^=GPIO_Pin_2; break; default: printf("指令錯誤rn"); break; } } }

版權聲明:本文為CSDN博主「rivencode」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。原文鏈接:https://blog.csdn.net/k666499436/article/details/124354165

wKgaomTky8GAA-KQAAAvLbr3E7Q722.png

審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • STM32
    +關注

    關注

    2270

    文章

    10901

    瀏覽量

    356201
  • 串口通信
    +關注

    關注

    34

    文章

    1626

    瀏覽量

    55545
收藏 人收藏

    評論

    相關推薦

    STM32串口通信詳解(基本概念+易錯點)精選資料推薦

    STM32串口通信詳解串口通信是 串行通信里的 異步
    發表于 07-27 07:35

    STM32f103串口通信詳解原理

    STM32f103串口通信詳解原理分析首先,我們從串口通信的物理層和協議層來分別分析。物理層對于
    發表于 08-12 06:49

    STM32串口通信詳解以及通信異常或者卡死常見問題分析 精選資料分享

    藍牙耳機電路方案設計目錄藍牙耳機電路方案設計實現原理硬件介紹電路方案實現原理硬件介紹電路方案...
    發表于 08-20 06:37

    stm32f407串口通信的代碼

    stm32f407串口通信的代碼 原理圖還有封裝 很清楚自己畫的
    發表于 03-21 17:22 ?0次下載

    RS232-RS485串口通信詳解

    RS232-RS485串口通信詳解,很不錯的東東
    發表于 08-09 15:08 ?29次下載

    STM32串口DMA問題詳解

    昨天晚上在STM32串口DMA的問題上糾結了好長時間,所以今天上午寫篇博客來談談我對串口DMA發送的理解。
    的頭像 發表于 10-27 16:16 ?8451次閱讀
    <b class='flag-5'>STM32</b><b class='flag-5'>串口</b>DMA問題<b class='flag-5'>詳解</b>

    STM32串口通信數據亂碼的相關問題

    STM32串口通信以及溫度采集搞定,其中主要遇到STM32系列單片機時鐘樹的問題,串口通信遇到
    發表于 06-22 08:01 ?1.2w次閱讀
    <b class='flag-5'>STM32</b><b class='flag-5'>串口</b><b class='flag-5'>通信</b>數據亂碼的相關問題

    STM32串口通訊

    STM32串口通訊USART串口通信實踐USART串口通信實踐1、實驗環境參考資料 野火官
    發表于 12-06 20:21 ?13次下載
    <b class='flag-5'>STM32</b><b class='flag-5'>串口</b>通訊

    STM32串口通信

    STM32串口通信串口通信簡介編程代碼注意:本文參考STM32F10XXX數據手冊
    發表于 12-07 09:36 ?15次下載
    <b class='flag-5'>STM32</b><b class='flag-5'>串口</b><b class='flag-5'>通信</b>

    Stm32串口通信基礎實驗

    目錄二、stm32串口通信二級目錄三級目錄二、stm32串口通信1.本次實驗使用的是
    發表于 12-07 09:36 ?32次下載
    <b class='flag-5'>Stm32</b><b class='flag-5'>串口</b><b class='flag-5'>通信</b>基礎實驗

    "2個STM32串口之間的串口通信(RX,TX)"

    "2個STM32串口之間的串口通信(RX,TX)"
    發表于 12-09 17:21 ?83次下載
    "2個<b class='flag-5'>STM32</b><b class='flag-5'>串口</b>之間的<b class='flag-5'>串口</b><b class='flag-5'>通信</b>(RX,TX)"

    stm32串口代碼詳解

    stm32串口
    發表于 12-24 18:38 ?52次下載
    <b class='flag-5'>stm32</b><b class='flag-5'>串口</b>代碼<b class='flag-5'>詳解</b>

    STM32串口通信

    STM32串口通信串口通信簡介編程代碼注意:本文參考STM32F10XXX數據手冊
    發表于 01-14 13:47 ?12次下載
    <b class='flag-5'>STM32</b><b class='flag-5'>串口</b><b class='flag-5'>通信</b>

    STM32串口通信詳解

    按數據傳送的方式,通訊可分為串行通訊與并行通訊。
    的頭像 發表于 08-14 10:45 ?4662次閱讀
    <b class='flag-5'>STM32</b><b class='flag-5'>串口</b><b class='flag-5'>通信</b><b class='flag-5'>詳解</b>

    STM32串口通信簡明知識

    STM32串口通信簡明知識
    的頭像 發表于 10-25 15:48 ?1330次閱讀
    <b class='flag-5'>STM32</b><b class='flag-5'>串口</b><b class='flag-5'>通信</b>簡明知識
    主站蜘蛛池模板: 91久久精一区二区三区大全| 国产亚洲精品久久久久久禁果TV| 久久久久久88色偷偷| 国产精品九九久久精品视| 王晶三级作品| 国产亚洲精品在浅麻豆| 人体内射精一区二区三区| 纯肉高H啪短文合集| 我的漂亮朋友在线观看全集免费| 果冻传媒在线观看高清完整免费 | 日本肉肉口番工全彩动漫| 国产精品国产三级国产an| 一边亲着一面膜下奶韩剧免费| 猫咪最新破解版下载| 国产 高清 无码 在线播放| 亚洲色图另类小说| 欧洲内射XXX高清| 国产在线精品国自产拍影院午夜| 中文字幕a有搜索网站| 善良的小峓子2在钱中文版女主角 善良的小峓子2在钱免费中文字 | 熟女久久久久久久久久久| 精品日产1区2卡三卡麻豆| www色小姐| 伊人久久五月丁婷婷| 久久国语精品| jiapanese50欧美熟妇| 亚久久伊人精品青青草原2020| 国产午夜高潮熟女精品AV| 97在线观看免费| 亚洲成人精品| 九九精品在线播放| 竹菊影视一区二区三区| 麻豆官网入口| 国产精品高潮AV久久无码| 97色色极品av影院| 亚洲精品久久一区二区三区四区| 久久99re6热在线播放| 成人免费毛片观看| 永久免费在线视频| 午夜福利体验免费体验区| 欧美日韩精品一区二区三区四区 |