娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

歷史上的今天

今天是:2024年12月17日(星期二)

正在發生

2018年12月17日 | STM32系統學習——USART(串口通信)

發布者:bin0990 來源: eefocus關鍵字:STM32  系統學習  USART  串口通信 手機看文章 掃描二維碼
隨時隨地手機看文章

串口通信是一種設備間非常常用的串行通行方式,其簡單便捷,大部分電子設備都支持。 


一、物理層 


常用RS-232標準,主要規定了信號的用途、通信接口以及信號的電平標準。 

 

這里寫圖片描述 


“DB9接口”之間通過串口信號線建立起連接,串口信號線使用”RS-232標準“傳輸數據信號,這些信號通過記過電平轉換芯片轉換成控制器能識別的TLL標準的電平信號,才能實現通信。 


1.電平標準 


可分為TTL標準以及RS-232標準。 


常見的電子電路中常見TTL的電平標準,理想狀態使用5V表示二進制邏輯1,0V表示邏輯0;而為了增加串口通信的遠距離傳輸以及抗干擾能力,RS-232使用-15V表示邏輯1,+15V表示邏輯0。 

 

這里寫圖片描述 


因為控制器一般使用TTL電平標準,所以常常使用MA3232芯片將TTL以及RS-232電平的信號進行互相轉換。


2.RS-232信號線 


最初RS-232串口標準常用于計算機、路由與調制調節器(“貓”)之間通信,設備被分為數據終端設備DTE(計算機、路由)和數據通信設備DCE(調制調節器)。舊臺式計算機,一般都有RS-232標準的COM口,也稱DB9接口。


DB9信號線說明

這里寫圖片描述 

 

公頭標準接法,只要使用直通型串口線連接起來即可。


二、協議層 


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


1、波特率 


異步通信中由于沒有時鐘信號,所以2個通信設備需約定好波特率,常見的有4800、9600、115200等。 


2、通信的起始和停止信號 


串口通信的一個數據包從起始信號開始,知道停止信號結束。數據包的起始信號由一個邏輯0的數據位表示,而數據包的停止信號可由0.5、1、1.5或2個邏輯1的數據位表示,只要雙方約定一致即可。 


3、有效數據 


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


4、數據校驗 


在有效數據之后,有一個可選的數據校驗位。由于數據通信相對容易受到外部干擾導致傳輸數據出現偏差,可以在傳輸過程加上校驗位來解決這個問題。校驗方法有奇校驗(odd)、偶校驗(even)、0校驗(space)、1校驗(mark)以及無校驗(noparity)。 奇校驗要求有效數據和校驗位中“1”的個數為奇數,比如一個 8 位長的有效數據為:01101001,此時總共有 4 個“1”,為達到奇校驗效果,校驗位為“1”,最后傳輸的數據將是 8 位的有效數據加上 1 位的校驗位總共 9 位。 


偶校驗與奇校驗要求剛好相反,要求幀數據和校驗位中“1”的個數為偶數,比如數據幀:11001010,此時數據幀“1”的個數為 4 個,所以偶校驗位為“0”。 0 校驗是不管有效數據中的內容是什么,校驗位總為“0”,1 校驗是校驗位總為“1”。


三、STM32的USART簡介 


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


串口通信一般是以幀格式傳輸數據,即一幀一幀傳輸,每幀包含有起始信號、數據信息、停止信息,可能還有校驗信息。 


USART 滿足外部設備對工業標準 NRZ 異步串行數據格式的要求,并且使用了小數波特率發生器,可以提供多種波特率,使得它的應用更加廣泛。USART 支持同步單向通信和半雙工單線通信;還支持局域互連網絡 LIN、智能卡(SmartCard)協議與 lrDA(紅外線數據協會) SIR ENDEC規范。 


USART支持使用 DMA,可實現高速數據通信。


四、USART功能框圖剖析 

 

這里寫圖片描述 


下文結合圖片看加深理解。 


1、功能引腳 


TX:發送數據輸出引腳。 


RX:接收。 


SW_RX:數據接收引腳,屬于內部引腳。 


nRTS:請求以發送,n表示低電平有效。如果使能 RTS 流控制,當USART接收器準備好接收新數據時就會將nRTS變成低電平;當接收寄存器已滿時,nRTS將被設置為高電平。該引腳只適用于硬件流控制。 


nCTS:清除以發送(Clear To Send),n表示低電平有效。如果使能 CTS流控制,發送器在發送下一幀數據之前會檢測 nCTS 引腳,如果為低電平,表示可以發送數據,如果為高電平則在發送完當前數據幀之后停止發送。該引腳只適用于硬件流控制。 


SCLK:發送器時鐘輸出引腳。這個引腳僅適用于同步模式。 


USART:下圖是STM32F103VET6芯片的USART引腳 

 

這里寫圖片描述

USART1的時鐘來源于APB2總線時鐘,最大頻率為72MHZ,其他4個時鐘來源于APB1總線時鐘,最大頻率36MHZ。UART只有異步傳輸功能,沒有SCLK、nCTS和nRTS功能引腳。

 

2.數據寄存器 


USART說數據寄存器(USART_DR)只有低 9 位有效,并且第 9 位數據是否有效要取決于USART 控制寄存器 1(USART_CR1)的 M 位設置,當 M 位為 0 時表示 8 位數據字長,當 M位為 1 表示 9 位數據字長,我們一般使用 8位數據字長。 


USART_DR包含了已發送的數據或者接收到的數據。USART_DR實際是包含了兩個寄存器,一個專門用于發送的可寫 TDR,一個專門用于接收的可讀 RDR。當進行發送操作時,往 USART_DR寫入數據會自動存儲在 TDR內;當進行讀取操作時,向 USART_DR讀取數據會自動提取 RDR 數據。 


TDR和RDR都是介于系統總線和移位寄存器之間。串行通信是一個位一個位傳輸的,發送時把 TDR 內容轉移到發送移位寄存器,然后把移位寄存器數據每一位發送出去,接時把接收到的每一位順序保存在接收移位寄存器內然后才轉移到 RDR。 


USART 支持 DMA 傳輸,可以實現高速數據傳輸。


3.控制器 


USART有專門控制發送的發送器、控制接收的接收器,還有喚醒單元、中斷控制等。 


使用USART之前需要向USART_CR1寄存器的UE位置1使能USART,UE位用于開啟供給串口的時鐘。發送或者接收數據字長可選8或9位,由USARTT_CR1的M位控制。 


1)發送器 


當USART_CR1寄存器的發送使能位TE置1時,啟動數據發送,發送移位寄存器的數據會在TX引腳輸出,低位在前,高位在后。如果是同步模式SCLK也輸出時鐘信號。 


一個字符幀發送需要3部分:起始位、數據幀、停止位。起始位是一個位周期的低電平,位周期就是每一位占用的時間 ;數據幀就是我們要發送的8或9位數據,數據是最低位開始傳輸的;停止位是一定時間周期的高電平。 


停止位的時間長短可以通過USART控制寄存器2(USART_CR2)的STOP[1:0]位控制,可選0.5個、1個、1.5個、2個停止位。默認使用1個停止位。2個停止位適用于正常USART模式、單線模式和調制解調器模式。0.5和1.5個停止位用于智能卡模式。 


當發使能位TE置1之后,發送器開始會發送一個空閑幀(一個數據幀長度的高電平),接下來就可以往USART_DR寄存器寫入要發送的數據。在寫入最后一個數據后,需等待USART狀態寄存器(USART_SR)的TC位為1,表示數據傳輸完成。USART_CR1寄存器的TCIE位置1,則產生中斷。 


發送數據時,幾個重要的標志位如下: 


TE:發送使能。 


TXE:發送寄存器為空,發送單個字節時使用。 


TC:發送完成,發送多個字節數據時候使用。 


TXIE:發送完成中斷使能。 


2)接收器 


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


接收數據時,幾個重要的標志位如下: 


RE: 接收使能。 


RXNE:讀數據寄存器非空。 


RXNEIE:發送完成中斷使能。


4.小數波特率生成 


USART 的發送器和接收器使用相同的波特率。計算公式如下: 

 

這里寫圖片描述 


其中,f PLCK 為 USART 時鐘, USARTDIV 是一個存放在波特率寄存器(USART_BRR)的一個無符號定點數。其中 DIV_Mantissa[11:0]位定義 USARTDIV 的整數部分,DIV_Fraction[3:0]位定義 USARTDIV 的小數部分。 


例如:DIV_Mantissa=24(0x18),DIV_Fraction=10(0x0A),此時 USART_BRR 值為0x18A;那么USARTDIV的小數位10/16=0.625;整數位24,最終USARTDIV的值為24.625。 


如果知道 USARTDIV 值為 27.68,那么 DIV_Fraction=16*0.68=10.88,最接近的正整數為 11,所以 DIV_Fraction[3:0]為 0xB;DIV_Mantissa=整數(27.68)=27,即為 0x1B。 


波特率的常用值有 2400、9600、19200、115200。下面以實例講解如何設定寄存器值得到波特率的值。 


我們知道 USART1 使用 APB2 總線時鐘,最高可達 72MHz,其他 USART 的最高頻率為 36MHz。我們選取 USART1 作為實例講解,即 f PLCK =72MHz。為得到 115200bps 的波特率,此時:115200 =72000000/(16 ? USARTDIV)   解 得 USARTDIV=39.0625 , 可 算 得 DIV_Fraction=0.0625*16=1=0x01 ,DIV_Mantissa=39=0x17,即應該設置 USART_BRR 的值為 0x171。


5.校驗控制 


STM32F103系列控制器USART支持奇偶校驗。使用校驗位時,串口傳輸的長度將在8位數據幀上加上1位的校驗位,總共9位,此時USART_CR1寄存器的M位需要設置位1,即9數據位。將USART_CR1寄存器的PCE位置1就可以啟動奇偶校驗控制,奇偶校驗由硬件自動完成。啟動了奇偶校驗控制之后,發送數據幀時會自動添加校驗位,接收數據自動驗證校驗位。接收數據時如果出現奇偶校驗位驗證失敗,會將USART_SR寄存器的PE置1,并可以產生奇偶校驗中斷。 


使用了奇偶校驗控制位后,每個字符幀的格式變成了:起始位+數據幀+校驗位+停止位。


6.中斷控制 


這里寫圖片描述


五、USART初始化結構體 


初始化結構體的定義在stm32f10x_usart.h文件中,初始化庫函數定義在stm32f10x_usart.c中。


                                    USART初始化結構體


typedef struct {

 uint32_t USART_BaudRate; // 波特率

 uint16_t USART_WordLength; // 字長

 uint16_t USART_StopBits; // 停止位

 uint16_t USART_Parity; // 校驗位

 uint16_t USART_Mode; // USART 模式

 uint16_t USART_HardwareFlowControl; // 硬件流控制

 } USART_InitTypeDef;


1)USART_BaudRate:波特率設置。標準庫函數會根據設定值計算得到USARTDIV值,從而設置USART_BRR的寄存器值。 


2)USART_WordLength:.數據幀字長,它設定USART_CR1寄存器M位的值。如果沒有使能奇偶位校驗控制,一般使用8數據位。 


3)USART_StopBits停止位設置。 


4)USART_Parity:奇偶校驗控制選擇。 


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


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


當使用同步模式,需配置SCLK引腳輸出脈沖的屬性,標準庫使用一個時鐘初始化結構體USART_ClockInitTypeDef來設置,該結構體內容只有在同步模式下才設置。


                USART時鐘初始化結構體


 typedef struct {

 uint16_t USART_Clock; // 時鐘使能控制

 uint16_t USART_CPOL; // 時鐘極性

 uint16_t USART_CPHA; // 時鐘相位

 uint16_t USART_LastBit; // 最尾位時鐘脈沖

 } USART_ClockInitTypeDef;


1)USART_Clock:同步模式下SCLK引腳上時鐘輸出使能控制,可選禁止時鐘輸出(USART_Clock_Disable)或開啟時鐘輸出(USART_Clock_Enable);如果使用同步模式發送,一般都需要開啟時鐘。它設定 USART_CR2 寄存器的 CLKEN 位的值。 ? 


2)USART_CPOL:同步模式下 SCLK 引腳上輸出時鐘極性設置,可設置在空閑時SCLK引腳為低電平(USART_CPOL_Low)或高電平(USART_CPOL_High)。它設定USART_CR2寄存器的 CPOL位的值。 


3)USART_CPHA:同步模式下 SCLK 引腳上輸出時鐘相位設置,可設置在時鐘第一個變化沿捕獲數據(USART_CPHA_1Edge)或在時鐘第二個變化沿捕獲數據。它設定 USART_CR2寄存器的 CPHA位的值。USART_CPHA與 USART_CPOL配合使用可以獲得多種模式時鐘關系。 


4)USART_LastBit:選擇在發送最后一個數據位的時候時鐘脈沖是否在SCLK引腳輸出,可以是不輸出脈沖(USART_LastBit_Disable) 、 輸出脈沖(USART_LastBit_Enable)。它設定 USART_CR2 寄存器的 LBCL位的值。


六、USART1接發通信實驗 


USART 只需兩根信號線即可完成雙向通信,對硬件要求低,使得很多模塊都預留USART 接口來實現與其他模塊或者控制器進行數據傳輸,比如 GSM 模塊,WIFI 模塊、藍牙模塊等等。在硬件設計時,注意還需要一根“共地線”。 


來編寫一個程序實現開發板與電腦通信,在開發板上電時通過USART發送一串字符串給電腦,然后開發板進入中斷接收等待狀態,如果電腦有發送數據過來,開發板就會產生中斷,我們在中斷服務函數接收數據,并馬上把數據返回發送給電腦。 


1、編程思路 


1) 使能 RX和 TX 引腳 GPIO時鐘和 USART時鐘; 


2) 初始化 GPIO,并將 GPIO復用到 USART上; 


3) 配置 USART 參數; 


4) 配置中斷控制器并使能 USART接收中斷; 


5) 使能 USART; 


6) 在 USART接收中斷服務函數實現數據接收和發送。 


2、代碼分析 


1)GPIO和USART宏定義


 /**

 * 串口宏定義,不同的串口掛載的總線和 IO 不一樣,移植時需要修改這幾個宏

 */ 

 // 串口 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


使用宏定義方便程序移植和升級 。開發板中的 CH340G 的收發引腳默認通過跳帽連接到 USART1,如果想使用其他串口,可以把 CH340G 跟 USART1 直接的連接跳帽拔掉,然后再把其他串口的 IO用杜邦線接到 CH340G的收發引腳即可。 


這里我們使用USART1,設定波特率為115200,選定USART的GPIO為PA9和PA10。


2)嵌套向量中斷控制器NVIC配置


 static void NVIC_Configuration(void)

 {

 NVIC_InitTypeDef NVIC_InitStructure; 

 /* 嵌套向量中斷控制器組選擇 */

 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);


 /* 配置 USART 為中斷源 */

 NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ;

 /* 搶斷優先級為 1 */

 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

 /* 子優先級為 1 */

 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

 /* 使能中斷 */

 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

 /* 初始化配置 NVIC */

 NVIC_Init(&NVIC_InitStructure);

 }


3)USART初始化配置


 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);

 }


調用RCC_APB2PeriphClockCmd函數開啟GPIO端口時鐘,使用GPIO之前必須開啟對應的時鐘。RCC_APB2PeriphClockCmd函數開啟USART時鐘。 


使用GPIO之前需要初始化配置它,并且還要添加特殊設置,因為我們使用它作為外設引腳,一般都有特殊功能,模式設置為復用功能,把串口的Tx引腳配置為復用推挽輸出,Rx引腳為浮空輸入,數據完全由外部輸入決定。 


配置USAT1通信參數為:波特率115200,字長8,1個停止位,沒有校驗位,不使用硬件流控制,收發一體工作模式,然后調用USART初始化函數完成配置。 


USART接收中斷,需要配置NVIC,這里調用NVIC_Configuration函數完成配置,然后調用USART_ITConfig函數使能USART接收中斷。 


最后 調用USART_Cmd函數使能USART,最終配置的是USART_CR1的UE位,具體作用是開啟USART工作時鐘,沒有時鐘那USART這個外設就工作不了。


4)字符發送


/***************** 發送一個字符 **********************/

 void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch)

 {

 /* 發送一個字節數據到 USART */

 USART_SendData(pUSARTx,ch);


 /* 等待發送數據寄存器為空 */

 while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);

 }


 /***************** 發送字符串 **********************/

 void Usart_SendString( USART_TypeDef * pUSARTx, char *str)

 {

 unsigned int k=0;

 do {

 Usart_SendByte( pUSARTx, *(str + k) );

 k++;

 } while (*(str + k)!='\0');


 /* 等待發送完成 */

 while (USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET) {

 }

 }


Usart_SendByte用來指定USART發送一個ASCLL碼字符,它有2個形參:第一個USART第二個待發送的字符,它通過調用庫函數USART_SendData來實現等待,并且增加了等待發送完成功能,它接收兩個參數:一個是USART,一個是事件標志。這里循環檢測發送數據寄存器這個標志,當跳出while循環時,說明發送數據寄存器為空。 


Usart_SendString函數用來發送一個字符串,實際調用Usar_SendByte函數發送每個字符,直到遇到空字符才停止發送。最后使用循環檢測發送完成的事件標志TC,保證數據完成后才退出函數。


5)USART中斷服務函數


void DEBUG_USART_IRQHandler(void)

 {

 uint8_t ucTemp;

 if (USART_GetITStatus(DEBUG_USARTx,USART_IT_RXNE)!=RESET) 

 {

 ucTemp = USART_ReceiveData( DEBUG_USARTx );

 USART_SendData(USARTx,ucTemp);

 }


 }


該代碼在stm32f10x_it.c文件中的,用來集中存放中斷服務函數。當使能了中斷并中斷發生時,就會執行這里的中斷服務函數。 


6)main函數


int main(void)

 {

 /*初始化 USART 配置模式為 115200 8-N-1,中斷接收*/

 USART_Config();


 Usart_SendString( DEBUG_USARTx,"這是一個串口中斷接收回顯實驗\n");


 while (1) {


 }

 }


USART_Config()函數完成USART初始化配置,包括GPIO USART配置,接收中斷使能等。 


接下來調用字符發送函數把數據發給串口調試助手。 


最后什么也不做,等待接收中斷產生,并在中斷服務函數中回傳數據。


七、USART1指令控制RGB彩燈實驗 


1、思路要點 


1)初始化配置RGB彩色燈GPIO 


2)使能RX和TX引腳GPIO時鐘和USART時鐘 


3)初始化GPIO,并將GPIO復用到USART上 


4)配置USART參數 


5)使能USART 


6)獲取指令輸入,根據控制RGB彩色燈 


2、代碼分析 


1)GPIO和USART宏定義


1 #define DEBUG_USARTx USART1

2 #define DEBUG_USART_CLK RCC_APB2Periph_USART1

3 #define DEBUG_USART_APBxClkCmd RCC_APB2PeriphClockCmd

4 #define DEBUG_USART_BAUDRATE 115200

6 // USART GPIO 引腳宏定義

7 #define DEBUG_USART_GPIO_CLK (RCC_APB2Periph_GPIOA)

8 #define DEBUG_USART_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd

10 #define DEBUG_USART_TX_GPIO_PORT GPIOA

11 #define DEBUG_USART_TX_GPIO_PIN GPIO_Pin_9

12 #define DEBUG_USART_RX_GPIO_PORT GPIOA

13 #define DEBUG_USART_RX_GPIO_PIN GPIO_Pin_10

14 

15 #define DEBUG_USART_IRQ USART1_IRQn

16 #define DEBUG_USART_IRQHandler USART1_IRQHandler


2)USART初始化配置


1 void USART_Config(void)

2 {

3 GPIO_InitTypeDef GPIO_InitStructure;

4 USART_InitTypeDef USART_InitStructure;

6 // 打開串口 GPIO 的時鐘

7 DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);

9 // 打開串口外設的時鐘

10 DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);

11 

12 // 將 USART Tx 的 GPIO 配置為推挽復用模式

13 GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;

14 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

15 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

16 GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);

17 

18 // 將 USART Rx 的 GPIO 配置為浮空輸入模式

19 GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN;

20 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

21 GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);

22 

23 // 配置串口的工作參數

24 // 配置波特率

25 USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE;

26 // 配置 針數據字長

27 USART_InitStructure.USART_WordLength = USART_WordLength_8b;

28 // 配置停止位

29 USART_InitStructure.USART_StopBits = USART_StopBits_1;

30 // 配置校驗位

31 USART_InitStructure.USART_Parity = USART_Parity_No ;

32 // 配置硬件流控制

33 USART_InitStructure.USART_HardwareFlowControl =

34 USART_HardwareFlowControl_None;

35 // 配置工作模式,收發一起

36 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

37 // 完成串口的初始化配置

38 USART_Init(DEBUG_USARTx, &USART_InitStructure);

39 

40 // 使能串口

41 USART_Cmd(DEBUG_USARTx, ENABLE);

42 }


與上實驗基本一樣,唯一不同沒使用使能中斷 


3)重定向printf和scanf函數


1 ///重定向 c 庫函數 printf 到串口,重定向后可使用 printf 函數

2 int fputc(int ch, FILE *f)

3 {

4 /* 發送一個字節數據到串口 */

5 USART_SendData(DEBUG_USARTx, (uint8_t) ch);

7 /* 等待發送完畢 */

8 while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);

10 return (ch);

11 }

12 

13 ///重定向 c 庫函數 scanf 到串口,重寫向后可使用 scanf、getchar 等函數

14 int fgetc(FILE *f)

15 {

16 /* 等待串口輸入數據 */

17 while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_RXNE) == RESET);

18 

19 return (int)USART_ReceiveData(DEBUG_USARTx);

20 }


fputc函數是printf函數內部的一個函數,功能是將字符ch寫入文件指針f所指向文件的當前寫指針位置,我們使用USART函數重新修改fputc函數內容,達到類似寫入的功能。 


fgetc實現字符讀取功能。 


還有一點需要注意的,使用 fput和 fgetc函數達到重定向 C語言標準庫輸入輸出函數必須在 MDK的工程選項把“Use MicroLIB”勾選上,MicoroLIB 是缺省 C庫的備選庫,它對標準 C庫進行了高度優化使代碼更少,占用更少資源。 


為使用 printf、scanf 函數需要在文件中包含 stdio.h頭文件。 


4)輸出提示信息


1 static void Show_Message(void)

2 {

3 printf("\r\n 這是一個通過串口通信指令控制 RGB 彩燈實驗 \n");

4 printf("使用 USART 參數為:%d 8-N-1 \n",USART_BAUDRATE);

5 printf("開發板接到指令后控制 RGB 彩燈顏色,指令對應如下:\n");

6 printf(" 指令 ------ 彩燈顏色 \n");

7 printf(" 1 ------ 紅 \n");

8 printf(" 2 ------ 綠 \n");

9 printf(" 3 ------ 藍 \n");

10 printf(" 4 ------ 黃 \n");

11 printf(" 5 ------ 紫 \n");

12 printf(" 6 ------ 青 \n");

13 printf(" 7 ------ 白 \n");

14 printf(" 8 ------ 滅 \n");

15 }


5)main函數


1 int main(void)

2 {

3 char ch;

5 /* 初始化 RGB 彩燈 */

6 LED_GPIO_Config();

8 /* 初始化 USART 配置模式為 115200 8-N-1 */

9 USART_Config();

10 

11 /* 打印指令輸入提示信息 */

12 Show_Message();

13 while (1)

14 {

15 /* 獲取字符指令 */

16 ch=getchar();

17 printf("接收到字符:%c\n",ch);

18 

19 /* 根據字符指令控制 RGB 彩燈顏色 */

20 switch (ch)

21 {

22 case '1':

23 LED_RED;

24 break;

25 case '2':

26 LED_GREEN;

27 break;

28 case '3':

29 LED_BLUE;

30 break;

31 case '4':

32 LED_YELLOW;

33 break;

34 case '5':

35 LED_PURPLE;

36 break;

37 case '6':

38 LED_CYAN;

39 break;

40 case '7':

41 LED_WHITE;

42 break;

43 case '8':

44 LED_RGBOFF;

45 break;

46 default:

47 /* 如果不是指定指令字符,打印提示信息 */

48 Show_Message();

49 break;

50 }

51 }

52 }


首先我們定義一個字符變量來存放接收到的字符。 


接下來調用 LED_GPIO_Config 函數完成 RGB 彩色 GPIO 初始化配置,該函數定義在bsp_led.c 文件內。 


調用 USART_Config 函完成 USART初始化配置。 


Show_Message函數使用 printf 函數打印實驗指令說明信息。 


getchar函數用于等待獲取一個字符,并返回字符。我們使用 ch變量保持返回的字符,接下來判斷 ch內容執行對應的程序。 


我們使用 switch語句判斷 ch 變量內容,并執行對應的功能程序。


關鍵字:STM32  系統學習  USART  串口通信 引用地址:STM32系統學習——USART(串口通信)

上一篇:STM32 時鐘配置之寄存器操作
下一篇:STM32筆記:RCC結構與配置流程

推薦閱讀

1、STM32對內部Flash的保護措施 所有STM32的芯片都提供對Flash的保護,防止對Flash的非法訪問 - 寫保護和讀保護。 1)、讀保護即大家通常說的“加密”,是作用于整個Flash存儲區域。一旦設置了Flash的讀保護,內置的Flash存儲區只能通過程序的正常執行才能讀出,而不能通過下述任何一種方式讀出:通過調試器(JTAG或SWD);從RAM中啟動并執行的程序; ...
豐田首款 EV 的電池《中國首款豐田品牌 EV》這是這幾天看到群里有朋友分享的材料,這款豐田設計的電池系統的一些信息也逐步公布了,本文我們來看一看這個平臺的電池一開始是采用了松下的方殼電池,應用于以小型 SUV 車型 C-HR 及奕澤為基礎研發電動汽車上,根據公告的信息來看,C-HR EV 的電池能量密度為 131Wh/kg,整車耗電量為 13.1kWh/100km。...
################################################################################################## SHELL常用內部參數:  # $# —— 傳遞給程序的總的參數數目# $? —— 上一個代碼或者shell程序在shell中退出的情況,如果正常退出則返回0,反之為非0值。# $* —— 傳遞給程序的所有參數組成的字符串。# $n —— 表示第幾個參數,$1...
整活兒從整術語開始,是很多品牌在宣傳中慣用的套路。為了不讓一臉懵逼的消費者看著滿屏的英文字母發怵,今天本篇中盡量不出現更多英文縮寫的專有名詞。 先從遠古時期的車燈說起。這是一臺經過修復的奔馳290 Cabriolet A(W18),誕生于1933年的工業神作。造型和設計是可以逃脫時代的輪回的,但技術不行,就像這對大而無神的白熾燈。在此之前,人類還經歷...

史海拾趣

問答坊 | AI 解惑

貢獻一些ARM開發板原理圖

2440的就不用貢獻了,傳下S3C2450開發板的原理圖 [ 本帖最后由 open82977352 于 2010-1-12 18:43 編輯 ]…

查看全部問答∨

【藏書閣】 集成電路(荒井英甫)——21世紀大學新型參考教材系列

目錄: 集成電路a 1 集成電路的學習方法 1·1 集成電路的發明 1·2 集成電路發展的動力 1·3 集成電路的未來 1·4 本書的構成 練習題 引用文獻 2 集成電路中的半導體器件 2·1 pn結 2·2 雙極型晶體管 2·3 mos晶體管 2·4 集成電路 ...…

查看全部問答∨

Toyato的 Hybrid和汽車方面的課程資料

無意在網上找到的,因此把目錄整理出來,有兄弟需要的發郵件給我yulzhu@gmail.com,注明需要哪一部分,直接發怕有些問題。 混合動力有關材料 Toyota Series - Hybrid Hybrid01 Hybrid System Overview.pdf   Hybrid02 Hybrid System ...…

查看全部問答∨

現代功率模塊及器件應用技術(6).

現代功率模塊及器件應用技術(6).…

查看全部問答∨

求助!!!定時器同步配置問題-一個上升沿信號觸發定時器TIM2,同時根據上升沿信號啟

最近在做一個RLC(電阻、電感、電容)測量儀,測量插座只有一個,因此需要利用程序區分三種不同的器件; 區分方法是利用通過三種器件后的波形超前滯后關系判別,將正弦信號轉化為矩形波后輸入定時器通道1。與此同時將沒有經過原器件的正弦波也轉化為 ...…

查看全部問答∨

IAR_EW430使用入門

IAR_EW430的使用貼,是我學習時找到的資料…

查看全部問答∨

求教個整流電路的問題

我用了個整流電路,用multisim仿真,負載開路時,測其內阻,發現竟然有2M歐姆左右,怎么會那么大?如圖。…

查看全部問答∨

關于濾波電容的計算,急求解釋~~~

下面貼了一張圖,圖中(2.12)那個公式看不懂啊,沒找到相關解釋的資料, 哪位大神能解釋一下嗎? …

查看全部問答∨

疊層電感可以用在升壓電路里嗎?

哥們太菜了,對這方面一點不懂,我想實現150mA的升壓電路,IC手冊上使用2.2uH的電感,我找到一些功率電感1A以上,感覺用不上,價格也高。不知道使用圖片里這種疊層電感是否可行,我找了一些資料,沒發現有關于這種電感電流的參數。 …

查看全部問答∨
小廣播
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 诸暨市| 杂多县| 金湖县| 楚雄市| 阳谷县| 遂平县| 油尖旺区| 开阳县| 海南省| 靖宇县| 姚安县| 乌兰浩特市| 榆林市| 固镇县| 田阳县| 新晃| 稻城县| 万荣县| 沾化县| 桂林市| 晋宁县| 巴里| 武强县| 罗源县| 剑河县| 五家渠市| 东山县| 济阳县| 钟祥市| 南澳县| 乡城县| 泌阳县| 睢宁县| 依兰县| 黑河市| 营口市| 辽宁省| 新竹市| 五指山市| 上饶县| 古田县|