STM32 串口詳解

0一、USART的特色

USART是通用異步收發傳輸器(UniversalAsynchronousReceiver/Transmitter),一般稱做UART,是一種異步收發傳輸器,是設備間進行異步通訊的關鍵模塊。UART負責處理數據總線和串行口之間的串/並、並/串轉換,並規定了幀格式;通訊雙方只要採用相同的幀格式和波特率,就能在未共享時鐘信號的狀況下,僅用兩根信號線(Rx和Tx)就能夠完成通訊過程,所以也稱爲異步串行通訊。git

全雙工異步通訊。github

小數波特率發生器系統,提供精確的波特率。編程

可配置的16倍過採樣或8倍過採樣,於是爲速度容差與時鐘容差的靈活配置提供了可能。app

可編程的數據字長度(8位或者9位);異步

可配置的中止位(支持1或者2位中止位);函數

可配置的使用DMA多緩衝器通訊。測試

單獨的發送器和接收器使能位。spa

檢測標誌:① 接受緩衝器  ②發送緩衝器空 ③傳輸結束標誌3d

多個帶標誌的中斷源。觸發中斷。code

其餘:校驗控制,四個錯誤檢測標誌。

通訊結構

 

 

 

 0二、USART簡介

2.一、數據傳輸模型

 

 

 2.二、幀結構

串口異步通訊須要定義的參數

① 起始位

② 數據位(8位或者9位)

③ 奇偶校驗位(第9位)

④ 中止位(1,15,2位)

⑤ 波特率設置

帶奇偶校驗的數據爲就是9位

 

 

 

 1.數據包

串口通信的數據包由發送設備經過自身的TXD接口傳輸到接收設備得RXD接口,在協議層中規定了數據包的內容,具體包括起始位、主體數據(8位或9位)、校驗位以及中止位,通信的雙方必須將數據包的格式約定一致才能正常收發數據。

2.波特率

因爲異步通訊中沒有時鐘信號,因此接收雙方要約定好波特率,即每秒傳輸的碼元個數,以便對信號進行解碼,常見的波特率有4800、9600、115200等。STM32中波特率的設置經過串口初始化結構體來實現。

3.起始和中止信號

數據包的首尾分別是起始位和中止位,數據包的起始信號由一個邏輯0的數據位表示,中止位信號可由0.五、一、1.五、2個邏輯1的數據位表示,雙方需約定一致。STM32中起始和中止信號的設置也是經過串口初始化結構體來實現。

4.有效數據

有效數據規定了主題數據的長度,通常爲8或9位,其在STM32中也是經過串口初始化結構體來實現的。

5.數據校驗

在有效數據以後,有一個可選的數據校驗位。因爲數據通訊相對更容易受到外部干擾致使傳輸數據出現誤差,能夠在傳輸過程加上校驗位來解決這個問題。校驗方法有奇校驗(odd)、偶校驗(even)、0 校驗(space)、1 校驗(mark)以及無(noparity)。這些也均可以在串口初始化結構體中實現的。

2.三、波特率

 

 

 OVER8,用於配置過採樣,一般狀況下,OVER8設置爲0。

 

 

 若是時鐘時84M

USARTDIV = 84000000/(115200*16) = 45.572

那麼獲得:

DIV_Fraction = 16*0.572 = 0x09;

DIV_Mantissa = 45 = 0x2D;

0三、STM32的USART

根據STM32F207數據手冊,STM32F207一共6個串口

 

 

 

 下文咱們以USART1爲例講解

從STM32F207數據手冊的Table10. Alternate functionmapping圖中看到USART1的對應管腳,下文咱們選擇PA9和PA10做爲USART1的管腳。

 

 

 

 0四、代碼配置

配置中斷優先級。

  /* Enable the USARTx Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

打開串口與相應的GPIO引腳,配置好相應串口信息與GPIO引腳的工做模式。

  /* Enable GPIO clock */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
  /* Enable UART1 clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
  /* Connect PXx to USARTx_Tx*/
  GPIO_PinAFConfig(GPIOA, 9, GPIO_AF_USART1);
  
  /* Connect PXx to USARTx_Rx*/
  GPIO_PinAFConfig(GPIOA, 10, GPIO_AF_USART1);
  
  /* Configure USART Tx as alternate function  */
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  
  /* Configure USART Rx as alternate function  */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

配置USART1。

  USART_InitStructure.USART_BaudRate = 115200;//配置波特率
  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 configuration */
  USART_Init(USART1, &USART_InitStructure);// 完成串口的初始化配置

使能中斷配置。

  USART_ITConfig(USART1, USART_IT_TC, ENABLE);
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE)

咱們配置了發送傳輸完成中斷和接收數據寄存器非空中斷。咱們能夠配置不少類型中斷,在ST提供的標準庫函數中看到。

/**
  * @brief  Enables or disables the specified USART interrupts.
  * @param  USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or 
  *         UART peripheral.
  * @param  USART_IT: specifies the USART interrupt sources to be enabled or disabled.
  *          This parameter can be one of the following values:
  *            @arg USART_IT_CTS:  CTS change interrupt
  *            @arg USART_IT_LBD:  LIN Break detection interrupt
  *            @arg USART_IT_TXE:  Transmit Data Register empty interrupt
  *            @arg USART_IT_TC:   Transmission complete interrupt
  *            @arg USART_IT_RXNE: Receive Data register not empty interrupt
  *            @arg USART_IT_IDLE: Idle line detection interrupt
  *            @arg USART_IT_PE:   Parity Error interrupt
  *            @arg USART_IT_ERR:  Error interrupt(Frame error, noise error, overrun error)
  * @param  NewState: new state of the specified USARTx interrupts.
  *          This parameter can be: ENABLE or DISABLE.
  * @retval None
  */

最後使能串口。

  /* Enable USART */
  USART_Cmd(USART1, ENABLE);

main主函數,功能是LCD顯示串口接收的10個字符(若是不是ascii碼則不顯示),串口倒序返回接收到的10個字節。

int main(void)
{
/*省略初始化部分代碼*/
  while (1)
  {
    if(LCD_refresh_flg){
      LCD_refresh_flg = 0;
      LCD_ShowString(0,16,receive_data);
      receive_num--;
      USART_SendData(USART1, receive_data[receive_num--]);
      send_flg = 1;
    }
  }
}

由於使能了中斷,咱們還須要編寫中斷函數。

void USART1_IRQHandler(void)
{
  if(USART_GetFlagStatus(USART1, USART_FLAG_TC))
  {
    if(send_flg == 1){
      if(receive_num==0){
        USART_SendData(USART1, receive_data[receive_num]);
        send_flg = 0;
        receive_flg = 1;
      }else{
        USART_SendData(USART1, receive_data[receive_num--]);
      }
    }
    USART_ClearFlag(USART1, USART_FLAG_TC);
  }
  if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE))
  {
    if((receive_flg)&&(send_flg == 0)){
      receive_data[receive_num++] = USART_ReceiveData(USART1);
      if(receive_num==10){
        receive_flg = 0;
        LCD_refresh_flg = 1;
      }
    }
    USART_ClearFlag(USART1, USART_FLAG_RXNE);
  }
}

下載驗證

LCD顯示屏能夠顯示接收的10個字符,且PC以100ms爲間隔發送數據,發送977包收到977包回覆,測試demo就夠健壯,沒有出現丟包。

 

 

 

 

keil和IAR工程代碼和硬件PCB開源地址:

https://github.com/strongercjd/STM32F207VCT6

 

點擊查看本文所在的專輯,STM32F207教程

相關文章
相關標籤/搜索