目錄
一、USART串口
1.串口參數及時序
2.USART簡介?
3.配置USART基本結構
4.初始化模板?
(1) 接收一個數據
(2) 發送一個數據
一、USART串口
1.串口參數及時序
- 波特率:串口通信的速率
- 起始位:標志一個數據幀的開始,固定為低電平
- 數據位:數據幀的有效載荷,1為高電平,0為低電平,低位先行
- 校驗位:用于數據驗證,根據數據位計算得來
- 停止位:用于數據幀間隔,固定為高電平
本節展示串口收發的功能,通常使用波特率為9600,8位數據位,即無校驗位,停止位長度為1的時序。
2.USART簡介?
·USART (Universal Synchronous/Asynchronous Receiver/Transmitter)通用同步/異步收發器
·USART是STM32內部集成的硬件外設,可根據數據寄存器的一個字節數據自動生成數據幀時序,從TX引腳發送出去,也可自動接收RX引腳的數據幀時序,拼接為一個字節數據,存放在數據寄存器里
·自帶波特率發生器,最高達4.5Mbits/s
·可配置數據位長度(8/9)、停止位長度(0.5/1/1.5/2)
·可選校驗位(無校驗/奇校驗/偶校驗)
·支持同步模式、硬件流控制、DMA、智能卡、IrDA、LIN
·STM32F103C8T6 USART資源:USART1、USART2、USART3(USART1是APB2總線的設備,剩下的是APB1的設備)
3.配置USART基本結構
4.初始化模板?
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//把PA9配置為復用推挽輸出,供USART的TX使用
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//復用推挽輸出
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
//初始化PA10引腳
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//可選浮空或上拉輸入
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化USART 9600波特率 無流控 無校驗 8位字長 1位停止位 選擇發送和接收模式
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate=9600;//波特率
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//硬件流控制
USART_InitStructure.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;//串口模式
USART_InitStructure.USART_Parity=USART_Parity_No;//校驗位選擇無校驗
USART_InitStructure.USART_StopBits=USART_StopBits_1;//停止位長度
USART_InitStructure.USART_WordLength=USART_WordLength_8b;//字長選擇8位
USART_Init(USART1,&USART_InitStructure);//開啟RXNE標志位到NVIC的輸出
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//優先級分組
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;//中斷通道
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&NVIC_InitStructure);USART_Cmd(USART1,ENABLE);
查看引腳定義表
可見USART1的TX和RX分別對應PA9和PA10引腳,初始化PA9時要配置成復用推挽輸出模式。
關于USART的結構體參數USART_Mode,需要接收或發送的哪一個功能就選哪一個,兩個都要就用“|”操作或起來。
(1) 接收一個數據
方法一:
模板里使用中斷觸發來接收數據,首先開啟RXNE到中斷的通道,用USART_ITConfig函數,再配置NVIC優先級分組等參數;關于RXNE標志位
RXNE:讀數據寄存器非空(Read data register not empty)
- 當RDR移位寄存器中的數據被轉移到USART DR寄存器中,該位被硬件置位。如果USART CR1寄存器中的RXNEIE為1,則產生中斷。對USARTDR的讀操作可以將該位清零。RXNE位也可以通過寫入0來清除,只有在多緩存通訊中才推薦這種清除程序。
- 0:數據沒有收到:
- 1:收到數據,可以讀出。
?有數據時會觸發中斷,中斷函數從啟動文件里找
中斷函數示例:
void USART1_IRQHandler(void)
{if(USART_GetFlagStatus(USART1,USART_IT_RXNE)==SET){//。。。要進行的操作USART_ClearITPendingBit(USART1,USART_IT_RXNE);//若讀出收到的數據,不用手動清零}
}
讀出數據用函數USART_ReceiveData,手冊里說讀DR硬件會自動清零標志位。
方法二:
在主函數里不斷判斷RXNE標志位,如果置1了,就說明收到數據了,那再調用ReceiveData,讀取DR寄存器就行了。
int main(void)
{OLED Init();serial Init();'while(1){if(USART GetFlagstatus (USART1 USART FLAG RXNE)==SET){RxData=USART ReceiveData(USART1);OLED ShowHexNum(l,1,RxData,2);}}
???????}
(2) 發送一個數據
發送數據用函數USART_SendData,發送完判斷一下TXE標志位即可
關于TXE標志位
- TXE:發送數據寄存器空(Transmit data register empty)當TDR寄存器中的數據被硬件轉移到移位寄存器的時候,該位被硬件置位。如果USARTCR1寄存器中的TXEIE為1,則產生中斷。對USARTDR的寫操作,將該位清零。
- 0:數據還沒有被轉移到移位寄存器
- 1:數據已經被轉移到移位寄存器。
為1時標志可以繼續發了,和RXNE對應,為1時表示接收到了數據,可以讀了,以免繼續發數據被覆蓋了。?
發送數據代碼示例
//發送一個數據
void Serial_SendByte(uint8_t Byte)
{USART_SendData(USART1,Byte);while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);//TXE發送數據寄存器空標志位,為1即空//硬件會將標志位清零
}
見手冊描述,我們對DR進行讀操作,硬件會將標志位清零,所以這里不需要我們像收數據一樣手動清除標志位。?