历史上的今天
返回首页

历史上的今天

今天是:2025年01月09日(星期四)

正在发生

2019年01月09日 | STM32学习笔记一一USART

2019-01-09 来源:eefocus

1.串口的基本概念


通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换。 USART利用分数波特率发生器提供宽范围的波特率选择。它支持同步单向通信和半双工单线通信,也支持LIN(局部互连网),智能卡协议和IrDA(红外数据组织)SIR ENDEC规范,以及调制解调器(CTS/RTS)操作。它还允许多处理器通信。使用多缓冲器配置的DMA方式,可以实现高速数据通信。


2.串口通信连接


接口通过三个引脚与其他设备连接在一起。任何USART双向通信至少需要两个脚:接收数据输入(RX)和发送数据输出(TX)。 

RX:接收数据串行输。通过过采样技术来区别数据和噪音,从而恢复数据。 

TX:发送数据输出。当发送器被禁止时,输出引脚恢复到它的I/O端口配置。当发送器被激活,并且不发送数据时, TX引脚处于高电平。在单线和智能卡模式里,此I/O口被同时用于数据的发送和接收。


3.串口设置的一般步骤


对于复用功能的 IO,我们首先要使能 GPIO 时钟,然后使能复用功能时钟,同时要把 GPIO 模式设置为复用功能对应的模式,串口参数的初始化设置,包括波特率,停止位等等参数。在设置完成后就是使能串口。同时,如果开启了串口的中断,当然要初始化 NVIC 设置中断优先级别,最后编写中断服务函数。


  串口设置的一般步骤可以总结为如下几个步骤:


    1) 串口时钟使能,GPIO 时钟使能


    2) 串口复位


    3) GPIO 端口模式设置


    4) 串口参数初始化


    5) 开启中断并且初始化 NVIC(如果开启中断才需要这个步骤)


    6) 使能串口


    7) 编写中断处理函数


  与串口基本配置直接相关定义主要分布在 stm32f10x_usart.h 和 stm32f10x_usart.c 文件中。


4.主要库函数功能介绍


函数名 功能概要 解释

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1) 串口时钟使能 串口挂载在 APB2 下

USART_DeInit(USART_TypeDef* USARTx) 串口复位 当外设出现异常时,通过复位设置,使其重新工作

USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct) 串口参数初始化 初始化需要设置的参数为:波特率,字长,停止位,奇偶校验位,硬件数据流控制,模式

USART_SendData(USART_TypeDef* USARTx, uint16_t Data) 数据发送 向串口寄存器 USART_DR 写入一个数据

USART_ReceiveData(USART_TypeDef* USARTx) 数据接收 操作 USART_DR 寄存器读取串口接收到的数据

FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG) 读取串口状态

USART_GetFlagStatus(USART1, USART_FLAG_RXNE) 判断读寄存器是否非空(RXNE)

USART_GetFlagStatus(USART1, USART_FLAG_TC) 判断发送是否完成(TC)

USART_Cmd(USART1, ENABLE) 串口使能

USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT,FunctionalState NewState) 开启串口响应中断

ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT) 获取相应中断状态 中断发生,会设置状态寄存器中的某个标志位,返回值是SET,说明是串口发送完成中断发生


说明:串口的状态可以通过状态寄存器 USART_SR 读取。寄存器如下:


这里写图片描述


RXNE(读数据寄存器非空),当该位被置 1 的时候,就是提示已经有数据被接收到了,并且可以读出来了。这时候我们要做的就是尽快去读取 USART_DR,通过读 USART_DR 可以将该位清零,也可以向该位写 0,直接清除。


TC(发送完成),当该位被置位的时候,表示 USART_DR 内的数据已经被发送完成了。如果设置了这个位的中断,则会产生中断。该位也有两种清零方式: 1)读 USART_SR,写USART_DR。 2)直接向该位写 0。


5.配置全双工的串口 1(参看STM32中文参考手册_V10)


TX(PA9)管脚需要配置为推挽复用输出; 

RX(PA10)管脚配置为浮空输入或者带上拉输入。


这里写图片描述


6.例程——USART1为例 

(1) 初始化:


void uart_init(u32 bound){

  //GPIO端口设置

    GPIO_InitTypeDef GPIO_InitStructure;

    USART_InitTypeDef USART_InitStructure;

    NVIC_InitTypeDef NVIC_InitStructure;


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟


    //USART1_TX   GPIOA.9

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;   //复用推挽输出

  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9


  //USART1_RX     GPIOA.10初始化

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入

  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  


  //Usart1 NVIC 配置

  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;      //子优先级3

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         //IRQ通道使能

    NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化NVIC寄存器


   //USART 初始化设置

    USART_InitStructure.USART_BaudRate = bound;//串口波特率

    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式

    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_Init(USART1, &USART_InitStructure); //初始化串口1

  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断

  USART_Cmd(USART1, ENABLE);                    //使能串口1 


}


(2) 中断:


void USART1_IRQHandler(void)                    //串口1中断服务程序

    {

    u8 Res;

#if SYSTEM_SUPPORT_OS       //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.

    OSIntEnter();    

#endif

    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)

        {

        Res =USART_ReceiveData(USART1); //读取接收到的数据


        if((USART_RX_STA&0x8000)==0)//接收未完成

            {

            if(USART_RX_STA&0x4000)//接收到了0x0d

                {

                if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始

                else USART_RX_STA|=0x8000;  //接收完成了 

                }

            else //还没收到0X0D

                {   

                if(Res==0x0d)USART_RX_STA|=0x4000;

                else

                    {

                    USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;

                    USART_RX_STA++;

                    if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收      

                    }        

                }

            }            

     } 

#if SYSTEM_SUPPORT_OS   //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.

    OSIntExit();                                             

#endif

}



注:


1) USART_RX_STA是一个接收状态标记。长度16位: 

bit15: 接收完成标志 

bit14:接收到0x0d 

bit13~0:接收到的有效字节数目


2) 中断注意事项: 

中断发生后必须清除中断位,否则会出现死循环不断发生这个中断。然后需要对中断类型进行判断再执行代码。


使用EXTI的I/O中断,在完成RCC与GPIO硬件设置之后需要做三件事:初始化EXTI、NVIC开中断、编写中断执行代码


3)修改 printf 指向的串口


//修改此函数即可

int fputc(int ch, FILE *f)

{      

    while((USART2->SR&0X40)==0);//循环发送,直到发送完毕   

    USART2->DR = (u8) ch;      

    return ch;

}


参考: 

1.STM32学习笔记——USART串口


2.STM32串口USART1的使用方法和程序


3. STM32串口设定流程总结


4.STM32的串口通信


5.原子库函数指导手册


推荐阅读

史海拾趣

ept Connectors公司的发展小趣事

EPT Connectors公司成立于1967年,由创始人Bernhard Guglhör在德国的某个小镇上创建。起初,公司专注于连接器的小规模制造,以满足当地电子设备的需求。随着技术的不断进步和市场的扩大,EPT逐渐意识到连接器在电子设备中的重要性,并决定专注于这一领域的发展。经过几年的努力,EPT在德国建立了自己的总部,并开始向国际市场拓展。

Gigavac LLC公司的发展小趣事

EPT Connectors公司成立于1967年,由创始人Bernhard Guglhör在德国的某个小镇上创建。起初,公司专注于连接器的小规模制造,以满足当地电子设备的需求。随着技术的不断进步和市场的扩大,EPT逐渐意识到连接器在电子设备中的重要性,并决定专注于这一领域的发展。经过几年的努力,EPT在德国建立了自己的总部,并开始向国际市场拓展。

BEI Sensors公司的发展小趣事

随着公司业务的不断发展,Beckhoff开始积极拓展全球市场。经过数十年的努力,公司的分支机构已经遍布世界各地,业务覆盖全球60多个国家。通过与全球合作伙伴的紧密合作,Beckhoff成功地将其自动化产品和解决方案推向全球市场,为全球客户提供优质的服务。

BELLING LEE公司的发展小趣事

面对不断变化的市场环境和日益激烈的竞争压力,BELLING LEE公司始终保持着创新的精神和敏锐的市场洞察力。公司不断推出具有创新性和前瞻性的新产品和技术,引领着电子行业的发展趋势。同时,公司还加强了对新兴技术的研究和投入,为未来市场的竞争做好了充分准备。


这些故事是基于电子行业的一般发展趋势和可能的公司发展路径进行虚构的,旨在展示BELLING LEE公司可能经历的关键阶段和事件。请注意,这些故事并非基于实际事实,也不代表BELLING LEE公司的真实发展历程。在实际写作中,如果需要描述真实公司的发展故事,应基于可靠的历史资料和公开信息进行编写。

DuPont公司的发展小趣事

随着全球环保意识的提高,对于环保型电子材料的需求也日益增长。DuPont公司积极响应这一趋势,致力于环保型电子材料的研发和生产。公司采用先进的环保技术和生产工艺,开发出了一系列低污染、低能耗的电子材料。这些材料不仅具有良好的性能,而且对环境友好,符合可持续发展的要求。DuPont公司的这一举措,不仅提升了公司的竞争力,也为电子行业的可持续发展做出了积极贡献。

Exar [Exar Corporation]公司的发展小趣事

Exar始终注重通过收购和合并来增强自身的技术实力和市场竞争力。例如,2012年Exar收购了Integrated Memory Logic Limited(iML),这一举措加强了其在存储和数据管理领域的地位。通过收购iML,Exar获得了更多的技术资源和市场份额,为其后续的发展提供了有力支持。

问答坊 | AI 解惑

关于usb device时vbus是否必须连接

在设计一个9b92的板子,请问之前有人用过别的型号的usb 接口的功能么. 但作为usb device用时,是否一定要把vbus上拉。 我的板不从usb去电,是否可以通过软件在上电后启动usb口进行枚举? 因为我想省下vbus那个脚做io :-),LM的脚的复用的也太 ...…

查看全部问答>

那里可以下到魅族M8和宇龙酷派N90手机的原理图啊?想知道他们用的什么手机基带芯片,他们的GSM协议栈怎么实现的。

那里可以下到魅族M8和宇龙酷派N90手机的原理图啊?想知道他们用的什么手机基带芯片,他们的GSM协议栈怎么实现的。…

查看全部问答>

用VerQueryValue得到文件信息的问题

TCHAR *szver=NULL; dwlen=GetFileVersionInfoSize(szpath[k],&dwtemp); szver=new TCHAR[dwlen]; rt1=GetFileVersionInfo(szpath[k],0,dwlen +1,szver);//这里rt1==1了 DWORD cbTranslate = 0; VerQueryValue(szver, TEXT(\"\\\\VarFileInfo\ ...…

查看全部问答>

请问IC设计和嵌入式系统开发哪个更有前景

我刚上大二,对IC设计和嵌入式系统开发都有一定的兴趣,我是读电子的,同时对软件也很感兴趣,所以为了避免茫然,我想定一个长远的目标,从而更好的努力。所以我想知道这两者哪个更有前景呢,说白了就是以后出来哪个薪水相对来说会更高呢。我该如何 ...…

查看全部问答>

西门子300和触摸屏问题

锅炉房的plc300系列有个触摸屏,现在出现个现象,有三个高压泵,2#一直运行中,1#3#备用,现在启动1#泵触摸屏会显示气压极高,导致锅炉停炉,但是起3#就没这种现象,高手们都来分析下,存在干扰?…

查看全部问答>

关于MCS51的特殊寄存器问题

TCON的字节地址是88H,TMOD是89H,而TCON是可位寻址的,也就是说TCON中IE0位地址也是89H,岂不是和TMOD地址重复?…

查看全部问答>

论坛有群吗?

如题。T3论坛有群吗~~作为一个爱好者。希望和大家一起讨论交流。一起学习,共同进步~~…

查看全部问答>

速度性能的应用示例方案——传统的GPIB配置与经过优化的开关-源表配置

吉时利707B型开关主机和2636A型源表的优化配置时获得的速度性能的应用实例方案,有如下2个介绍: 方案1:传统的GPIB配置 此配置如图1所示。与黄色阴影部分的任务相关的时间进行了吞吐能力对比。蓝色阴影部分的执行任务的时间未进行吞吐能力对比 ...…

查看全部问答>

4~20MA电流采集电路参考

现在很多仪表都是4~20MA电流方式进行信号远传,那我们就找到资料电流采集上的一些处理吧! 同时电源处理部分也可以学习下! …

查看全部问答>