×
单片机 > 单片机程序设计 > 详情

STM32 USART串口初始化

发布时间:2020-06-16 发布时间:
|

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)

    {


    }

}


关键字:STM32  USART  串口初始化 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
AVR熔丝位操作时的要点和需要注意的相关事项