历史上的今天
返回首页

历史上的今天

今天是:2025年08月12日(星期二)

正在发生

2018年08月12日 | STM32 USART串口初始化

2018-08-12 来源:eefocus

1、初始化串口时钟以及串口IO端口时钟:


使用RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); 

备注:为什么要使能IO口时钟? 

参照用户手册 P165-P166



使用串口这个外设的时候需要将串口的IO属性配置为图示; 

使用串口是否需要打开复用时钟,请见http://blog.csdn.net/u012411027/article/details/44217313,看到这位的解释才恍然大悟的。


2、串口参数设置(波特率、数据长度、停止位、校验位、发送接收模式、硬件控制流)


具体初始化及初始化方式如图: 



3、使能串口:


使用USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); 

参数说明: 



4、配置NVIC及打开串口中断,编写中断服务函数(如果不使用中断,使用轮询的方法的话,直接跳过该步骤即可)




中断服务函数 



5、调用串口函数使用串口功能。


以下粘贴一下测试使用的代码,实现的功能为接受一个或多个字符然后转发到上位机,不使用中断。


#include "stm32f10x.h"

#include "stm32f10x_rcc.h"

#include "delay.h"


int main(void)

{

    GPIO_InitTypeDef GPIO_InitStruct;

    USART_InitTypeDef USART_InitStruct;

    delay_init();


    /*LED指示灯初始化,用来标志全部初始化完成*/

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD;

    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5;

    GPIO_Init(GPIOB,&GPIO_InitStruct);

    GPIO_SetBits(GPIOB,GPIO_Pin_5);


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);

    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD;

    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;

    GPIO_Init(GPIOD,&GPIO_InitStruct);


    GPIO_SetBits(GPIOB,GPIO_Pin_5);

    GPIO_SetBits(GPIOD,GPIO_Pin_12);


    /*串口端口初始化*/

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);           //串口1时钟使能

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


    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;

    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;

    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOA,&GPIO_InitStruct);


    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;

    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;

    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOA,&GPIO_InitStruct);


    /*串口参数初始化*/

    USART_InitStruct.USART_BaudRate = 115200;

    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_Cmd(USART1,ENABLE);


    /*初始化完成*/

    GPIO_ResetBits(GPIOB,GPIO_Pin_5);

    GPIO_ResetBits(GPIOD,GPIO_Pin_12);

    while(1)

    {

        unsigned char dat = 0;

        if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == SET)

        {

            dat = USART_ReceiveData(USART1);

            USART_SendData(USART1,dat);

            if(GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_5))

            {

                GPIO_ResetBits(GPIOB,GPIO_Pin_5);

                GPIO_ResetBits(GPIOD,GPIO_Pin_12);

            }

            else

            {

                GPIO_SetBits(GPIOB,GPIO_Pin_5);

                GPIO_SetBits(GPIOD,GPIO_Pin_12);

            }

        }

    }

}


使用中断


#include "stm32f10x.h"

#include "stm32f10x_rcc.h"

#include "delay.h"


void USART1_IRQHandler(void)

{

    unsigned char dat = 0;


    if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == SET)              //等待接受完成

    {

        //USART_ClearITPendingBit(USART1,USART_FLAG_PE);

        dat = USART_ReceiveData(USART1);

        USART_SendData(USART1,dat);

        //while(!USART_GetFlagStatus(USART1,USART_FLAG_TC));

        //USART_ClearFlag(USART1,USART_FLAG_TC);

        if(GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_5))

        {

            GPIO_ResetBits(GPIOB,GPIO_Pin_5);

            GPIO_ResetBits(GPIOD,GPIO_Pin_12);

            GPIO_SetBits(GPIOD,GPIO_Pin_6);

        }

        else

        {

            GPIO_SetBits(GPIOB,GPIO_Pin_5);

            GPIO_SetBits(GPIOD,GPIO_Pin_12);

            GPIO_ResetBits(GPIOD,GPIO_Pin_6);

        }

    }

}


int main(void)

{

    GPIO_InitTypeDef GPIO_InitStruct;

    USART_InitTypeDef USART_InitStruct;

    NVIC_InitTypeDef NVIC_InitStruct;


    delay_init();


    /*LED指示灯初始化,用来标志全部初始化完成*/

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD;

    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5;

    GPIO_Init(GPIOB,&GPIO_InitStruct);

    GPIO_SetBits(GPIOB,GPIO_Pin_5);


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);

    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD;

    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;

    GPIO_Init(GPIOD,&GPIO_InitStruct);


    GPIO_SetBits(GPIOB,GPIO_Pin_5);

    GPIO_SetBits(GPIOD,GPIO_Pin_12);


    /*蜂鸣器初始化*/

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;

    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;

    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOD,&GPIO_InitStruct);


    GPIO_SetBits(GPIOD,GPIO_Pin_6);

    delay_ms(1000);

    GPIO_ResetBits(GPIOD,GPIO_Pin_6);


    /*串口端口初始化*/

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);           //串口1时钟使能

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


    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;

    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;

    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOA,&GPIO_InitStruct);


    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;

    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;

    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOA,&GPIO_InitStruct);


    /*串口参数初始化*/

    USART_InitStruct.USART_BaudRate = 115200;

    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_Cmd(USART1,ENABLE);


    /*开中断*/

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);                 //设置中断分组,2位抢占,2位优先


    NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;

    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;

    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;

    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;

    NVIC_Init(&NVIC_InitStruct);


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


    /*初始化完成*/

    GPIO_ResetBits(GPIOB,GPIO_Pin_5);

    GPIO_ResetBits(GPIOD,GPIO_Pin_12);


    while(1)

    {


    }

}


推荐阅读

史海拾趣

BETA Transformer Technology Corp公司的发展小趣事

BETA Transformer Technology Corp公司在成立初期就凭借其创新性的变压器技术,在电子行业中崭露头角。公司研发团队不断突破传统变压器的设计局限,推出了一系列高效、稳定的变压器产品,赢得了客户的广泛认可。随着市场需求的不断增长,BETA公司逐渐扩大了生产规模,提高了产能,成为行业内的领军企业。

Harris公司的发展小趣事

进入20世纪30年代,Hammond迎来了其发展历程中的一个重要转折点。在1930年代初,Hammond成为加拿大第一家生产两柱式机架和窄柜系列产品的公司,这些产品迅速获得了广播和通讯行业的青睐。这一创举不仅巩固了Hammond在业内的地位,还为其后续在电气、电子行业的全面发展铺平了道路。

Hilscher Gesellschaft für Systemautomation mbH公司的发展小趣事

在快速发展的同时,HVPSI始终关注可持续发展和环保责任。公司致力于研发更加节能、环保的高压电源产品,减少能源消耗和环境污染。同时,HVPSI还积极参与公益活动,为社会贡献自己的力量。这些举措不仅提升了公司的社会形象,也为其长远发展奠定了坚实的基础。

以上五个故事展示了High Voltage Power Solutions Inc.在电子行业中的发展历程和成就,彰显了其在技术创新、市场拓展、产品线扩展、行业标准制定以及可持续发展方面的努力与贡献。

铨力(ALLPOWER)公司的发展小趣事

为了进一步提升综合竞争力,铨力公司开始着手深化产业链整合。通过收购、合作等方式,公司逐渐掌握了从原材料供应、产品生产到销售终端的完整产业链。这一举措不仅降低了生产成本,提高了生产效率,还为公司带来了更多的利润增长点。

Exclara Inc公司的发展小趣事

随着技术的不断成熟和产品的日益完善,Exclara开始将目光投向全球市场。公司积极拓展海外市场,通过参加国际展会、与当地合作伙伴建立战略合作关系等方式,不断提升品牌知名度和市场份额。同时,公司也在全球范围内建立了完善的销售网络和售后服务体系,以确保客户能够享受到优质的产品和服务。

CONTEC公司的发展小趣事

2008年,对于CONTEC公司来说是具有里程碑意义的一年。这一年,公司建成了康泰产业园(一期),并进一步加强了研发和生产能力。同时,公司技术中心被省发改委等部门确定为省认定企业技术中心,这标志着公司在技术研发和创新方面得到了官方认可和支持。随着产业园的投入使用,公司的生产规模和效率得到了显著提升。

问答坊 | AI 解惑

通讯用平面UWB天线的设计技巧

由于UWB(Ultra Wide Band)系统使用500MHz以上的宽频高速传输资料,因此UWB天线必需具备很好的频率特性,最近几OFDM(Orthogonal Frequency Division Multiplex)与Mono Pulse通讯逐渐普及化,UWB的应用更受到各界关注。美国联邦通讯委员会(FCC ...…

查看全部问答>

新手学习嵌入式从那里入手好呢??

我是学习电气自动化的应届毕业生,想在毕业后在嵌入式方向发展,但是我在学校只学过80c51单片机和c语言,请各位高手指教一下!我应该从那里入手学习嵌入式呢,谢谢…

查看全部问答>

数控直流稳压设计

本帖最后由 paulhyde 于 2014-9-15 09:19 编辑 数控直流稳压设计  …

查看全部问答>

光电检测试验资料

本帖最后由 paulhyde 于 2014-9-15 09:14 编辑 光电测量技术实验指导书  …

查看全部问答>

cc1101 + 单片机 还是cc2430

cc1101 + 单片机 的成本要低于 cc2430不少 请问,我是要在10米内隔几分钟发送一个数字 这两种方案,哪个更好?…

查看全部问答>

在today界面显示标签

我想在today界面的上面部分,就是在显示电量、信号量的地方,添加一个label控件,用于显示当前的温度,怎么才能做到? 谢谢各位的指教…

查看全部问答>

wince快捷方式

正在搞一个放在SD卡上面的AP,每次路径访问很麻烦,能否搞一个快捷方式从桌面上面直接启动? 我查了下网上写的,18#/windows/**.exe的方法,但是系统一直报SD卡的路径不对,各位有没有搞过一个快捷方式能直接启动放在SD上的程序? 多谢多谢!…

查看全部问答>

关于uc/OSII的调试?用什么编译器!

关于uc/OSII的调试?用什么编译器! ___最近在学uc/OSII,要用到BC4.52,但很难下载到,下到的不是IDE,不习惯用命令行方式,请问各位,还有其它更好的编译器可用来调试uc/OSII吗?谢谢!…

查看全部问答>

9263WINCE5.0下SD卡驱动的问题

9263板跑WINCE5,使用SD卡时,时常从串口输出: WaitForSingleObject == WAIT_TIMEOUT (1000) StatusMask = 0x20 status 0xc0c5 这串数据重复输出,并且SD卡读写速度变得非常之慢。 查程序发现是PLATFOM\\COMMON\\SRC\\ARM\\ATMEL\\AT91SAM926 ...…

查看全部问答>