USART概述

一、 USART简介    

    一般使用MAX232芯片在STM32DB9接头之间进行电平转换,将STM32PA10USART1-TX)连接到DB9(公头)的第三引脚。

    串口的发送数据和接收数据都是在USART_DR中实现的,为一个双寄存器,包含了TDRRDR,当向该寄存器写入数据是,串口就会自动发送数据;当收到数据时,也是存在该寄存器中可以直接读出。

    串口的状态通过状态寄存器USART_SR读取,比较重要的几位如下:

 USART概述_第1张图片

二、USART寄存器配置(全双工、异步)

串口工作模式配置

   1. 使能USART时钟,配置GPIOA910

    查找《STM32参考手册》中系统结构图得知USART1GPIOA均挂载在APB2时钟线上,查找APB2外设时钟使能寄存器(RCC_APB2ENR),使能USARTGPIOA的时钟:

       RCC->APB2ENR |= 1<<2;   //使能GPIOA时钟

       RCC->APB2ENR |= 1<<14;  //使能USART1时钟

   参考STM32参考手册》GPIO章节配置PA9为复用推挽输出,PA10为浮空输入:

      GPIOA->CRL &= 0xFFFFF00F;     //选中PA9PA10

      GPIOA->CRL |= 0xFFFFF4B0;  //PA9复用推挽输出,PA10浮空输入

 2. 使能USART模块,配置USART模块的数据模式

     USART1->CR1 &=0x200C;    //一个起始位,8个数据位,默认一个停止位,无校检位,禁止各种中断

     //USART->CR2 |= 0x00<<12;    // 1个停止位 ,可不设置默认一个停止位

 3. 设置USART通讯波特率

    USART1->BRR =0x1D4<<4| 0xC;    //设置波特率为9600bps

   /******************参数设置说明**********************************

   查找《STM32参考手册》中“表176 设置波特率时的误差计算”,如表1-1

   若设置串口1通讯波特率为9600bps,串口1挂载在APB2时钟线上,因此,查表可得“置于波特率寄存器中的值”为468.75

   该数据的整数部分为USART->BRR的高12位,改数据的小数部分*16USART->BRR的低四位。

      Dec(468) = 0x 1D4;

      Dec0.75*16= 0xC;

   故:USART->BRR =0x1D4<<4| 0xC

********************************************************************/

USART概述_第2张图片 

1-1

 4. 复位串口

    USART1->APB2RSTR |= 1<<14;   

 5. 停止复位串口

   USART1->APB2RSTR &= ~(1<<14);       //初始化串口复位寄存器位

 6. 使能接收

   USART->CR1 |= 0xc;    //接收和发送使能

中断配置(后续单独补充说明)

  1. 中断优先级分组

     SCB->AIRCR &=0x05FAF8FF;     //优先级分组为3

     SCB->AIRCR |=0x05FA0400;

 2. 串口中断总开关使能

   查找stm32f10x.h得到USART1的中断号为37

 

   NVIC->ISER[1] = 1<<5;    //使能37 位上的串口中断

 3. 串口中断优先级配置

   NVIC->IP[37] = 0x30;

   USART->CR1 |= 1<<5;   //RXNEIE,接收完成中断使能

三、USART库配置

 /**************异步不用配置时钟*************

   USART_InitTypeDef   USART_InitStruct;

   GPIO_InitTypeDef  GPIO_InitStruct;

 

   RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, Enable);

 

   //PA9-TX,PA10-RX

   GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;

   GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;

   GPIO_Init(GPIOA, &GPIO_InitStruct);

   GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;

   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;

   GPIO_Init(GPIOA, &GPIO_InitStruct);

 

   USART_InitStruct.USART_BaudRate = 9600;

   USART_InitStruct.USART_WordLength= USART_WordLength_8b;

   USART_InitStruct.USART_StopBits =USART_StopBits_1;

   USART_InitStruct.USART_Parity =USART_Parity_No;

   USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

   USART_InitStruct.USART_HardwareFlowControl= USART_HardwareFlowControl_None;

   USART_Init(USART1,USART_InitStruct);

 

   USART_ITConfig(USART1, USART_IT_RXNE, Enable);

   USART_ITConfig(USART1, USART_IT_IDLE, Enable);

 

   USART_Cmd(USART1, Enable);

 

  优先级配置:

   NVIC_InitTypeDef   NVIC_InitStruct

   NVIC_PriorityGroupConfig( NVIC_PriorityGroup_0 );

   NVIC_InitStruct.NVIC_IRQChannel =USART1_IRQn;

   NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority =NVIC_PriorityGroup_0;

   NVIC_InitStruct.NVIC_IRQChannelSubPriority =1;

   NVIC_InitStruct.NVIC_IRQChannelCmd = Enable;

   NVIC_Init(NVIC_InitStruct);

四、USART数据接收/发送

 寄存器版

  发送数据:

     void USART1_Send_ASCII_Data(char TxData)

    {

       USART1->DR = TxData;

       Delay;   //延时

     While((USART->SR&0x00000040)==0);     //等待发送完毕,TC0x00000040

    }

  中断接收:

    User/stm32f10x_it.c

 /************中断服务函数是根据函数名来区分在.s的启动文件中说明*************/

   Void USART1_IRQHandler()

   {

       u8 data;

     if(USART1->SR&(1<<5))    //接收器非空

     {

         Data = USART1->DR;

    }

 }

库操作版:

    void USART1_Send_ASCII_Data(char TxData)

   {

       USART_SendData(USART1, TxData);

      Delay;   //延时

     While(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);     //TC:发送数据完毕;TXE发送数据寄存器为空

    }

 中断接收:

    void USART1_IRQHandler(void)

   {

      if(USART_GetITStatus(USART1, USART_FLAG_RXNE)=SET)

      BUFFER1[i] = USART_ReceiveData(USART1);

       i++;

      if(USART_GetITStatus(USART1, USART_IT_IDLE)=SET)   //一帧完毕

      i= 0;

   }

五、Printf重定向

   配置好串口后可以通过Printf重定向由串口往计算机超级终端或者串口调试软件打印信息。

   重定向是指用户可以自重写C的库函数,当连接器检查到用户编写了与C库函数相同名字的函数时,优先采用用户编写的函数,这样用户就可以实现对库的修改了。

   重定向Printf()函数,我们需要重写fputc()这个C标准库函数,因为printf()在C标准库中实质是一个红,最终是调用了fputc()这个函数。

   库操作版:

     int fputc(int ch, FILE *f)

  {

      USART_SendData(USART1, (unsighed char)ch);

      while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);

      return(ch);

  }

  寄存器版:

   int fputc(int ch, FILE *f)

   {

      USART1->DR = unsigned charch;

      While((USART->SR&0x00000040)==0)

     return(ch);

   }

    因为重定向使用到了C库,因此在main.c中需要将stdio.h这个头文件包含进来,同时还需要在编译器中选中UseMicroLIB(使用微库)

 

 

 

  

你可能感兴趣的:(STM32)