stm32f407之USART(操作寄存器)

时间:2020-12-25 23:31:32

七、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]存放。


stm32f407之USART(操作寄存器)

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

 

比如:要求波特率为115200

stm32f407之USART(操作寄存器)

 

设置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;
    }
   }
}

运行结果:

stm32f407之USART(操作寄存器)