stm32 usart 異步傳輸示例


STM32F103xE的USART異步數據傳輸示例

USART全稱Universal Synchronous/Asynchronous Receiver/Transmitter,是一種可以進行同步/異步通信的串行設備接口。

通過查閱STM32官方手冊得之,STM32f10x系列一共有五個USART傳輸串口。其中USART1、USART2、USART3為同步/異步串行通信接口,USART4、USART5為異步串行通信接口。

USART

STM32外設的初始化步驟基本上是:

  1. 使能外設時鍾
  2. 配置外設所需要的I/O端口
  3. 配置外設
  4. 使能外設

根據這個步驟首先我們使能外設時鍾

使能外設時鍾

查閱手冊

Clock-Tree

通過該圖我們看到USART1位於總線APB2上面,而USART2、3和UART4、5位於總線APB1上面。

因此我們開啟USART1的時鍾

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//開啟USART1時鍾

配置外設所需I/O端口

通過查閱STM32官方手冊得之,STM32f10x系列一共有五個USART傳輸串口。其中USART1、USART2、USART3為同步/異步串行通信接口,USART4、USART5為異步串行通信接口。

USART

在這里我們將使用USART1同步/異步串行通信接口為例,進行介紹。既然想通過USART1通信接口發送數據,那肯定GPIO引腳呀,因此繼續在官方手冊中查找

USART1-Port

該表格清楚明了的說明了USART1的各個引腳。其中TX(Transmit data發送數據輸出)、RX(Receive data接受數據輸入)、CK(Clock發送時鍾輸出)、CTS(Clear to Send允許發送)、RTS(Request to Send請求發送)分別對應於PA09、PA10、PA08、PA11、PA12。

因此我們配置I/O端口:

GPIO_InitTypeDef  GPIO_InitStrue;
//時鍾使能	
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
//GPIO10使能TX	
GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;//復用推挽輸出
GPIO_InitStrue.GPIO_Pin=GPIO_Pin_10;	//10腳
GPIO_InitStrue.GPIO_Speed=GPIO_Speed_50MHz;//IO口速度為50MHz
GPIO_Init(GPIOB,&GPIO_InitStrue);	//根據設定參數初始化GPIOB_10
//GPIO10使能RX 
GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING;//浮空輸入
GPIO_InitStrue.GPIO_Pin=GPIO_Pin_11;//11腳
GPIO_InitStrue.GPIO_Speed=GPIO_Speed_50MHz;//IO口速度為50MHz
GPIO_Init(GPIOB,&GPIO_InitStrue);	 //根據設定參數初始化GPIOB_11

配置外設

在這里外設當然是USART1啦。我們只需要根據自己的需要配置就行啦。主要的配置項有波特率有無硬件控制流發送/接受有無奇偶校驗停止位數據位

其中波特率指的是數據傳輸到速度指每秒鍾發送多少bit的數據;硬件控制流指是否通過CTS和RTS控制數據傳輸;有無奇偶校驗則比較簡單就是是否對傳輸的數據進行奇偶校驗;因為USART接口傳輸需要對數據進行封裝,即在原有的數據中加上開始位,在原始數據的尾部加上停止位,因此停止位值得就是停止位的長度;數據位指的是每次傳輸中有效數據的長度。

一個配置的示例:

USART_InitStrue.USART_BaudRate=9600;//波特率9600
USART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//無硬件流控制
USART_InitStrue.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//使能發送、接收
USART_InitStrue.USART_Parity=USART_Parity_No;//無基偶校驗
USART_InitStrue.USART_StopBits=USART_StopBits_1;//停止位1位
USART_InitStrue.USART_WordLength=USART_WordLength_8b;//數據8位
USART_Init(USART1,&USART_InitStrue);//根據設定初始化USART1

使能外設

直接使能USART即可

USART_Cmd(USART1,ENABLE);

接下來配置USART1的中斷

USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//開中斷USART1
NVIC_InitStrue.NVIC_IRQChannel=USART1_IRQn;//通道
NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE;//使能
NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=1;//搶占優先級
NVIC_InitStrue.NVIC_IRQChannelSubPriority=1;//子優先級
NVIC_Init(&NVIC_InitStrue);

以及中斷服務函數

在該函數中我們首先判斷中斷類型,是否為接受中斷;如果是接受中斷則接受字符並通過USART1發送出去,最后我們使用了一個while函數來確保數據成功發送。

//中斷服務函數
void USART1_IRQHandler(void)
{
	u8 USART1_in;
	if(USART_GetITStatus(USART1,USART_IT_RXNE))
	{
			USART1_in=USART_ReceiveData(USART1);
			USART_SendData(USART1, USART1_in);//向串口3發送數據
			while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待發送結束
	}
}

廢話少說,直接上最終代碼

配置IO引腳、USART、中斷向量優先級等參數:

//串口初始化
void USART1_init()
{
	GPIO_InitTypeDef  GPIO_InitStrue;
	USART_InitTypeDef USART_InitStrue;
	NVIC_InitTypeDef NVIC_InitStrue;
	//時鍾使能	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	//GPIO10使能TX	
	GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;//復用推挽輸出
	GPIO_InitStrue.GPIO_Pin=GPIO_Pin_10;	//10腳
	GPIO_InitStrue.GPIO_Speed=GPIO_Speed_50MHz;//IO口速度為50MHz
	GPIO_Init(GPIOB,&GPIO_InitStrue);	//根據設定參數初始化GPIOB_10
	//GPIO10使能RX 
	GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING;//浮空輸入
	GPIO_InitStrue.GPIO_Pin=GPIO_Pin_11;//11腳
	GPIO_InitStrue.GPIO_Speed=GPIO_Speed_50MHz;//IO口速度為50MHz
	GPIO_Init(GPIOB,&GPIO_InitStrue);	 //根據設定參數初始化GPIOB_11
	//USART初始化
	USART_InitStrue.USART_BaudRate=9600;//波特率9600
	USART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//無硬件流控制
	USART_InitStrue.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//使能發送、接收
	USART_InitStrue.USART_Parity=USART_Parity_No;//無基偶校驗
	USART_InitStrue.USART_StopBits=USART_StopBits_1;//停止位1位
	USART_InitStrue.USART_WordLength=USART_WordLength_8b;//數據8位
	USART_Init(USART1,&USART_InitStrue);//根據設定初始化USART1
	//USART1使能
	USART_Cmd(USART1,ENABLE);
	//開中斷
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//開中斷USART1
	NVIC_InitStrue.NVIC_IRQChannel=USART1_IRQn;//通道
	NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE;//使能
	NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=1;//搶占優先級
	NVIC_InitStrue.NVIC_IRQChannelSubPriority=1;//子優先級
	NVIC_Init(&NVIC_InitStrue);
}

中斷接受函數

//中斷服務函數
void USART1_IRQHandler(void)
{
	u8 USART1_in;
	if(USART_GetITStatus(USART1,USART_IT_RXNE))
	{
			USART1_in=USART_ReceiveData(USART1);
			USART_SendData(USART1, USART1_in);//向串口3發送數據
				while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待發送結束
	}
}

將使用USART1同步/異步串行通信接口為例,進行介紹。既然想通過USART1通信接口發送數據,那肯定GPIO引腳呀,因此繼續在官方手冊中查找

USART1-Port

廢話少說,直接上代碼

配置IO引腳、USART、中斷向量優先級等參數:

//串口初始化
void USART1_init()
{
	GPIO_InitTypeDef  GPIO_InitStrue;
	USART_InitTypeDef USART_InitStrue;
	NVIC_InitTypeDef NVIC_InitStrue;
	//時鍾使能	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART1,ENABLE);
	//GPIO10使能TX	
	GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;//復用推挽輸出
	GPIO_InitStrue.GPIO_Pin=GPIO_Pin_10;	//10腳
	GPIO_InitStrue.GPIO_Speed=GPIO_Speed_50MHz;//IO口速度為50MHz
	GPIO_Init(GPIOB,&GPIO_InitStrue);	//根據設定參數初始化GPIOB_10
	//GPIO10使能RX 
	GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING;//浮空輸入
	GPIO_InitStrue.GPIO_Pin=GPIO_Pin_11;//11腳
	GPIO_InitStrue.GPIO_Speed=GPIO_Speed_50MHz;//IO口速度為50MHz
	GPIO_Init(GPIOB,&GPIO_InitStrue);	 //根據設定參數初始化GPIOB_11
	//USART初始化
	USART_InitStrue.USART_BaudRate=9600;//波特率9600
	USART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//無硬件流控制
	USART_InitStrue.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//使能發送、接收
	USART_InitStrue.USART_Parity=USART_Parity_No;//無基偶校驗
	USART_InitStrue.USART_StopBits=USART_StopBits_1;//停止位1位
	USART_InitStrue.USART_WordLength=USART_WordLength_8b;//數據8位
	USART_Init(USART1,&USART_InitStrue);//根據設定初始化USART1
	//USART1使能
	USART_Cmd(USART1,ENABLE);
	//開中斷
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//開中斷USART1
	NVIC_InitStrue.NVIC_IRQChannel=USART1_IRQn;//通道
	NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE;//使能
	NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=1;//搶占優先級
	NVIC_InitStrue.NVIC_IRQChannelSubPriority=1;//子優先級
	NVIC_Init(&NVIC_InitStrue);
}

中斷接受函數

//中斷服務函數
void USART1_IRQHandler(void)
{
	u8 USART1_in;
	if(USART_GetITStatus(USART1,USART_IT_RXNE))
	{
			USART1_in=USART_ReceiveData(USART1);
			USART_SendData(USART1, USART1_in);//向串口3發送數據
			while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待發送結束
	}
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM