stm32f407之USART(操作寄存器)

七、USART

         STM32F407xx內嵌四個通用同步/異步接收器​​(USART1,USART2,USART3和USART6)和兩個通用異步收發器(UART4和UART5)。這6個接口提供異步通信的IrDASIR ENDEC支持,多機通信模式,單線半雙工通信模式LIN主/從功能。 USART1和USART6接口能夠速度高達10.5 Mbit / s的通信其他可用的接口通信高達5.25bit/s。USART1,USART2,USART3和USART6還提供硬件管理的CTS,RTS信號,智能卡的模式(ISO7816兼容)和類似的SPI通信能力。所有接口都可以通過DMA控制器。

USART name

Standard features

Modem (RTS/CTS)

LIN

SPI master

irDA

Smartcard (ISO 7816)

Max. baud rate in Mbit/s (oversampling by 16)

Max. baud rate in Mbit/s (oversampling by 8)

APB mapping

USART1

X

X

X

X

X

X

5.25

10.5

APB2 (max. 84 MHz)

USART2

X

X

X

X

X

X

2.62

5.25

APB1 (max. 42 MHz)

USART3

X

X

X

X

X

X

2.62

5.25

APB1 (max. 42 MHz)

UART4

X

-

X

-

X

-

2.62

5.25

APB1 (max. 42 MHz)

UART5

X

-

X

-

X

-

2.62

5.25

APB1 (max. 42 MHz)

USART6

X

X

X

X

X

X

5.25

10.5

APB2 (max. 84 MHz)

 

這裏只介紹兩根線的最簡單串口設置。

 

 波特率的計算:

         USART用的波特率是由APB時鐘線和波特率寄存器USART_BRR確定的,USART_BRR爲32位寄存器,其中高16位保留,低十六位確定波特率,低16位又分爲[15:4]和[3:0]或[15:4]和[2:0],具體分法由OVER8決定,[15:4]存放USARTDIV的整數部分,小數部分由[3:0]或[2:0]存放。



小數部分USARTDIV的小數部分乘以16或8,結果保留整數存於USART_BRR[3:0]或[2:0]中

 

比如:要求波特率爲115200


 

設置OVER8=0

解得:USARTDIV=22.768

USART_BRR[15:4]=22=0x16

USART_BRR[3:0]=0.768*16=13=0xC

USART_BRR=0x0000016C

 

 

 

 

設置步驟:

1.     設置中斷優先級分組(如果之前沒有設置),這個最好一個程序裏只在開頭設置一次。

2.     使能相關時鐘。

3.     設置波特率。

4.     設置控制寄存器CR。

5.     選擇相關GPIO引腳的複用功能。

6.     設置相關GPIO引腳爲複用模式。

7.     設置相關GPIO引腳的速度,方式。

8.     如果要用到中斷,設置USART中斷優先級。

9.     如果要用到中斷,使能USART中斷。

10.  如果要用中斷,編寫中斷服務函數(函數名是固定的)。

11.  中斷服務函數裏檢查是哪個中斷。

12.  編寫相應服務程序。

 

 

電路參見本博客:小工具之——max232電平轉換


程序:

/*********************************************
    標題:操作USART的練習
    軟件平臺:IAR for ARM6.21
    硬件平臺:stm32f4-discovery
    主頻:168M
    
    描述:從其他設備接收數據,再把數據發送出去

    author:小船
    data:2012-02-01
**********************************************/

#include <stm32f4xx.h> 

u32 Gb_TimingDelay;

u8 suffer[100];
u8 ok_to_send;
u8 Rx_data_counter;

void Delay(uint32_t nTime);

void main ()
{ 
  
  char Tx_data_counter;
  
  SCB->AIRCR = 0x05FA0000 | 0x400;  //中斷優先級分組 搶佔:響應=3:1
  SysTick_Config(SystemCoreClock / 1000); //設置systemtick一毫秒中斷
  
  RCC->AHB1ENR |= 0x00000008; //使能GPIOD時鐘
  RCC->APB1ENR |= (1<<18);  //使能usart3時鐘
  
  USART3->BRR = 0x0000016C;   //波特率115200
 
  /*
  使能usart3
  usart3發送使能
  usart3接收使能
  接收緩衝區非空中斷使能
  8bit
  一位停止位
  無校驗
  */
  USART3->CR1 |= (( 1<<13 ) | ( 1<<3 ) | ( 1<<2 ) | ( 1<<5 )); 
  
  GPIOD->AFR[1] |= 0x00000077;//選擇PD8,9複用功能 
  
  GPIOD->MODER &= 0xFFF0FFFF; //設置PD8,9,複用模式
  GPIOD->MODER |= 0x000A0000; 
  
//  GPIOD->OTYPER &= 0xFFFFDFFF; //設置PD9推輓輸出
  
  GPIOD->OSPEEDR &= 0xFFFCFFFF; //PD8速度50m
  GPIOD->OSPEEDR |= 0x00020000;
  
  GPIOD->PUPDR &= 0xFFFCFFFF; //PD8
  GPIOD->PUPDR |= 0x00010000;
  
  NVIC->IP[39] = 0xf0; //最低搶佔優先級,最低響應優先級1111
  NVIC->ISER[1] |= (1<<(39-32)); //使能中斷線39,也就是usart3中斷
  
  while(1)
  {  
    if(ok_to_send)  //接收到數據,可以將數據發送
    {
      if((USART3->SR & (1<<7))) //發送數據寄存器空
      {
        USART3->DR = suffer[Tx_data_counter];
        Tx_data_counter++;
        if( suffer[Tx_data_counter] == '\r' )
        {
          Tx_data_counter = 0;
          USART3->CR1 |= 1<<5;  //使能接收中斷
          ok_to_send = 0;
        } 
      } 
    }
  }
}


void Delay(uint32_t nTime)
{ 
  Gb_TimingDelay = nTime;

  while(Gb_TimingDelay != 0);
}

void SysTick_Handler(void)
{
  if (Gb_TimingDelay != 0x00)
  { 
    Gb_TimingDelay--;
  }
}

void USART3_IRQHandler(void)
{
  if(USART3->SR & (1<<5)) //接收數據寄存器非空
  {
    suffer[Rx_data_counter] = USART3->DR;
    Rx_data_counter++;
    if(suffer[Rx_data_counter - 1] == '\r')
    {
      Rx_data_counter = 0;
      USART3->CR1 &= ~(1<<5); //除能接收中斷
      ok_to_send = 1;
    }
   } 
}

運行結果:






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章