这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » USART概述

共1条 1/1 1 跳转至

USART概述

高工
2022-02-16 09:04:32     打赏

一、 USART简介    

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


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


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


 image.png


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


l 串口工作模式配置


   1. 使能USART时钟,配置GPIOA9、10;


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


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


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


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


      GPIOA->CRL &= 0xFFFFF00F;     //选中PA9、PA10


      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位,改数据的小数部分*16为USART->BRR的低四位。


      Dec(468) = 0x 1D4;


      Dec(0.75*16) = 0xC;


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


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


 


image.png


 4. 复位串口


    USART1->APB2RSTR |= 1<<14;   


 5. 停止复位串口


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


 6. 使能接收


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


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


  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)


    {undefined


       USART1->DR = TxData;


       Delay;   //延时


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


    }


  中断接收:


    User/stm32f10x_it.c


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


   Void USART1_IRQHandler()


   {undefined


       u8 data;


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


     {undefined


         Data = USART1->DR;


    }


 }


库操作版:


    void USART1_Send_ASCII_Data(char TxData)


   {undefined


       USART_SendData(USART1, TxData);


      Delay;   //延时


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


    }


 中断接收:


    void USART1_IRQHandler(void)


   {undefined


      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)


  {undefined


      USART_SendData(USART1, (unsighed char)ch);


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


      return(ch);


  }


  寄存器版:


   int fputc(int ch, FILE *f)


   {undefined


      USART1->DR = (unsigned char)ch;


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


     return(ch);


   }





关键词: USART     概述    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]