历史上的今天
返回首页

历史上的今天

今天是:2025年08月13日(星期三)

正在发生

2018年08月13日 | STM32F407串口的基本使用

2018-08-13 来源:eefocus

串口
串口在嵌入式系统中是一个非常重要的外设,它通信方式简单在软件开发阶段常用作调试工具。本示例中我们只实现串口的输出功能,同时还 会实现一个具有printf功能输出接口。这样咱们以后的例程中就有了一个简单的调试工具。

1. STM32串口简介
STM32的串口功能非常丰富,它可以支持双全工异步通信、LIN、IrDA、智能卡协议、单线半双工通信、支持调制解调器操作。
接下来我们将对使用STM32的串口应该进行的哪些设置给予简单说明,并对需要设置的寄存器给予简单介绍。要使用串口除了应对串口的波特率等进行配置外还需要对串口用到I/O进行设置,下面将分步进行介绍:

1) 串口时钟使能
STM32可以对每个外设进行单独的时钟控制,因此配置串口前需要打开串口的时钟。开启时钟前查看一下具体外设在哪个总线上是非常有必要的,通过查看STM32的参考手册第一章的1.2节得知串口1和6(USART1和6)在APB2上其它串口都在APB1上。

2) 设置波特率
串口波特率的设置是在USART_BRR中配置的,寄存器描述如下:

波特率配置寄存器各位描述
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
保留
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
DIV_Mantissa DIV_Fraction
STM32的波特率发生器可以使用分数作为分频值,DIV_Fraction表示小数部分DIV_Mantissa表示整数部分。分频值USARTDIV = DIV_Mantissa + DIV_Fraction /(8 * (2 - OVER8))。波特率Baud = APBxCLK / (8 * (2 – OVER8) * USARTDIV)。其中OVER8是USART_CR1中的一位取值0或1(当OVER8为1时只有DIV_Fraction[2:0]有效,DIV_Fraction[3]应设置为0)。举例说明一下这个分频值的计算:假设OVER8为0,USART_BRR为0x1BC则Mantissa = 27,Fraction = 12。分频值为27+12/16 = 27.75。
3) 串口控制

串口控制寄存器1各位描述
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
保留
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
OVER8 - UE M WAKE PCE PS PEIE TXEIE TCIE RXNEIE TCIE TE RE RWU SBK
STM32共有三个控制寄存器在这里我们仅对控制寄存器1中要用到的位给予说明。OVER8是设置过采样,1表示8倍过采样0表示16倍过采样。UE为串口使能。M为字长选择,0表示8位数据位1表示9位数据位。PCE为校验控制使能,1表示开启校验0表示无需校验。PS为校验选择,0表示偶校验1表示奇校验。PEIE为校验中断使能。TE为发送使能,1表示允许发送。

4) 数据传输
STM32的数据发送与接收都是通过寄存器USART_DR来实现的。它是一个包含发送(TDR)和接收(RDR)的32位双功能寄存器,但只有9位有效位。

5) 串口状态
串口状态寄存器各位描述
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
保留
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
保留 CTS LBD TXE TC RXNE IDLE ORE NF FE PE
在这里我们只需关注TXE、TC这两个位。串口发送数据时是先把数据放在发送缓冲区,然后再放到移位寄存器中一位一位的将数据发送出去。TXE为1时就表示发送缓冲区TDR为空,TC为1则表示传输完成即移位寄存器中也没有数据。只有当TXE为1时我们才能将下一个数据写到USART_DR中。

2.本例程所用硬件资源介绍
本示例使用了串口3(在扩展板上标有UART字样),PB10对应发送引脚,PB11对应接收引脚但本例程只使用了发送引脚。

3. 例程
代码1 初始化串口

  • 代码: 全选

  • /* uart.h */
     
    void uart_init(void)
    {
        USART_InitTypeDef USART_InitStructure;
        GPIO_InitTypeDef GPIO_InitStructure;

        /* 开启GPIO_B的时钟 */
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
        /* 开启串口3的时钟 */
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);

        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
        GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_10;

        GPIO_Init(GPIOB, &GPIO_InitStructure);

        /* 将PB10作为复用功能中的USART3通信引脚使用 */
        GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_USART3);

        
        USART_InitStructure.USART_BaudRate   = 115200;
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
        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_Tx;
        
            USART_Init(USART3, &USART_InitStructure);

        /* 使能串口3 */
        USART_Cmd(USART3, ENABLE);
    }

     

这里要注意的就是引脚配置为复用功能模式后,还需要选择具体使用哪个复用功能,其余的初始化比较简单就没什么说的了。

代码2 发送数据

  • 代码: 全选

  •  /* uart.c */

    static void _send(const char *str, unsigned int size)
    {
        int pos = 0;

        while(size)
        {
            if (str[pos] == '\0')
                break;
            
        /* 等待缓冲区空 */
            while(!(USART3->SR & 0x80));
            /* 发送数据 */
            USART3->DR = str[pos];

            pos ++;
            size --;
        }
    }

    void debug(const char* fmt,...)
    {
        va_list ap;
        char string[65];

        string[64]='\0';
        va_start(ap,fmt);
        vsprintf(string,fmt,ap);
        va_end(ap);
        _send(string,64);
    }
     


推荐阅读

史海拾趣

FCI / Amphenol公司的发展小趣事

1997年,Amphenol公司经历了一次重要的转折点。当时,公司被KKR(一家具有传奇色彩的美国纽约的私人股权投资公司)以杠杆收购的方式收购。KKR的收购为Amphenol公司注入了新的活力,公司开始进行一系列的战略调整和业务转型。在KKR的助力下,Amphenol公司不仅保留了大部分现有的管理团队,还引入了更大的财务杠杆,使得公司能够更加灵活地应对市场变化和挑战。这一收购和转型不仅为Amphenol公司带来了新的发展机遇,也为其在全球连接器市场上的地位奠定了更加坚实的基础。

Dionics Inc公司的发展小趣事

为了进一步拓展国际市场,Dionics Inc开始寻求与国际知名企业的战略合作。经过多次洽谈,公司最终与一家国际知名电子企业达成战略合作协议,共同开发新一代智能穿戴设备。通过这一合作,Dionics Inc不仅获得了宝贵的技术支持和市场资源,还成功将其产品推向了国际市场。

晨晶电子(Chenjing Electronics)公司的发展小趣事

晨晶电子始终将品质放在首位,坚持以客户为中心的服务理念。公司建立了严格的质量管理体系,从原材料采购到生产过程控制,再到产品出厂检验,每一个环节都严格把关,确保产品的品质稳定可靠。正是凭借这种对品质的执着追求,晨晶电子赢得了客户的广泛认可和好评,也为企业赢得了良好的口碑。

Bedford Opto公司的发展小趣事

Bedford Opto公司在追求经济效益的同时,也积极履行社会责任。公司注重环保和可持续发展,致力于减少生产过程中的污染和能耗。同时,公司还积极参与公益事业,为社会做出积极贡献。

FILTRAN公司的发展小趣事

近年来,电子行业经历了深刻的变革,新兴技术的不断涌现给Bedford Opto公司带来了前所未有的挑战。然而,公司凭借敏锐的市场洞察力和灵活的战略调整,成功应对了这些变革。通过加大研发投入,积极引进新技术,公司不断推出新产品,保持了市场竞争优势。

HP(Keysight)公司的发展小趣事

Bedford Opto公司深知人才是企业发展的核心。因此,公司高度重视人才培养和团队建设。通过提供良好的工作环境和福利待遇,吸引和留住了一批优秀的人才。同时,公司还注重员工的培训和发展,不断提升员工的专业素质和综合能力。

这些故事虽然基于虚构,但它们反映了电子行业中许多企业可能经历的发展过程和面临的挑战。当然,Bedford Opto公司的真实发展历程可能有所不同,具体的故事需要参考公司的官方资料和相关报道。

问答坊 | AI 解惑

google和百度分别搜索没前途

大家自己看结果去吧,呵呵。…

查看全部问答>

时序分析的一般概念与方法

时序分析的一般概念与方法…

查看全部问答>

如何能提高 DSP 底层驱动能力, 在使用TI OMAP5912 做开发MCBSP,SPI和GPIO等时感觉只能调试例程,可自己却些不出来?

   TI提供了支持包CSL,所以现在只会用CSL的API。     比如: 在写SPI驱动时,只要完成几个简单API调用,最后进行读写就OK了;可对驱动的思路却很欠缺,很多时候思维一片空白,恐怖啊?     交流吧,兄弟。…

查看全部问答>

有关IE和ACTIVEX控件传参问题?(急!!!!)

在PC下用PX_String(pPx,_T(\"name\"),m_name);能得到所设的name的值.在CE的模拟器中为什么PX_String(pPx,_T(\"name\"),m_name)的返回值总是零.m_name的值为空. …

查看全部问答>

学ARM9好还是ARM11好?

请教前辈:我想学嵌入式,是不是有必要买一块开发板?哪个开发板便宜又适合学习?…

查看全部问答>

最近有些迷茫

本帖最后由 paulhyde 于 2014-9-15 09:43 编辑 老实说不应该发在竞赛区的 但是我觉得这里学生比较多我现在大2,学电气的,对电子很感兴趣,现在也一直在学,但是有些力不从心的感觉,我也不知道为什么可能是这学期课比较多,时间也没那么多我就特 ...…

查看全部问答>

请问如何区分工业以太网和普通以太网

一直搞不清这个概念,只知道工业以太网实时性强一些。但具体应用时还是不知道如何构建所谓的工业以太网。我们常用的DM9000A是否属于工业以太网? STM32F107呢?是属于工业以太网芯片么?…

查看全部问答>

103VE的FSMC使用咨询

                                 希望103VE系统的FSMC工作在非复用方式扩展2片DAC芯片,如果使用NE1信号来选择器件就得增加逻辑电路,能否直接使用A ...…

查看全部问答>

大学堂之IO的使用

发一篇小总结,介绍IO的使用,讲得都是比较基础的东西: 文中所涉及的例程,将提供CCS v4.2以及IAR for MSP430 v5.2的完整工程文件。 有关CCS的Grace开发入门,请参考如下帖子:基于CCS:手把手教你使用Grace开发LaunchPadhttps://bbs.eeworld.co ...…

查看全部问答>