datasheet

STM32学习笔记——5个串口的使用方法

2019-07-12来源: eefocus关键字:STM32  串口  使用方法

串口是我们常用的一个数据传输接口,STM32F103系列单片机共有5个串口,其中1-3是通用同步/异步串行接口USART(Universal Synchronous/Asynchronous Receiver/Transmitter),4,、5是通用异步串行接口UART(Universal Asynchronous Receiver/Transmitter)。


配置串口包括三部分内容: 

1. I/O口配置:TXD配置为复用推挽输出(GPIO_Mode_AF_PP),RXD配置为浮空输入(GPIO_Mode_IN_FLOATING); 

2. 串口配置:波特率等; 

3. 中断向量配置:一般用中断方式接收数据。


注意事项: 

1. USART1是挂在APB2,使能时钟命令为: 

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE ); 

其他几个则挂在APB1上,如2口: 

RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE );


配置4口和5口的时候,中断名为UART4、UART5,中断入口分别为 

UART4_IRQn、UART5_IRQn 

对应的中断服务函数为 

void UART4_IRQHandler(void) 

和 

void UART5_IRQHandler(void)。

下面是5个串口的配置函数和收发数据函数代码:


#include "stm32f10x.h"

#include "misc.h"

#include "stm32f10x_gpio.h"

#include "stm32f10x_usart.h" 


void USART1_Configuration(void)

{

    GPIO_InitTypeDef GPIO_InitStructure;

    USART_InitTypeDef USART_InitStructure;

    NVIC_InitTypeDef NVIC_InitStructure;        


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE );


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //USART1 TX;

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

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOA, &GPIO_InitStructure); //端口A;


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //USART1 RX;

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

    GPIO_Init(GPIOA, &GPIO_InitStructure); //端口A;


    USART_InitStructure.USART_BaudRate = 9600; //波特率;

    USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位8位;

    USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位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);//配置串口参数;


    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断组,4位抢占优先级,4位响应优先级;


    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //中断号;

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

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应优先级;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);


    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

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

}


void USART1_Send_Byte(u8 Data) //发送一个字节;

{

    USART_SendData(USART1,Data);

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

}


void USART1_Send_String(u8 *Data) //发送字符串;

{

    while(*Data)

    USART1_Send_Byte(*Data++);

}


void USART1_IRQHandler(void) //中断处理函数;

{

    u8 res;    

    if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET) //判断是否发生中断;

    {

        USART_ClearFlag(USART1, USART_IT_RXNE); //清除标志位;

        res=USART_ReceiveData(USART1); //接收数据;

        USART1_Send_Byte(res); //用户自定义;

    }  




void USART2_Configuration(void)

{

    GPIO_InitTypeDef GPIO_InitStructure;

    USART_InitTypeDef USART_InitStructure;

    NVIC_InitTypeDef NVIC_InitStructure;        


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE );


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //USART2 TX;

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

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOA, &GPIO_InitStructure); //端口A;


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //USART2 RX;

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

    GPIO_Init(GPIOA, &GPIO_InitStructure); //端口A;


    USART_InitStructure.USART_BaudRate = 9600; //波特率;

    USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位8位;

    USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位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(USART2, &USART_InitStructure);//配置串口参数;


    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断组,4位抢占优先级,4位响应优先级;


    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; //中断号;

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

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应优先级;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);


    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);

    USART_Cmd(USART2, ENABLE); //使能串口;

}


void USART2_Send_Byte(u8 Data) //发送一个字节;

{

    USART_SendData(USART2,Data);

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

}


void USART2_Send_String(u8 *Data) //发送字符串;

{

    while(*Data)

    USART2_Send_Byte(*Data++);

}


void USART2_IRQHandler(void) //中断处理函数;

{

u8 res;    

    if(USART_GetITStatus(USART2, USART_IT_RXNE) == SET) //判断是否发生中断;

    {

        USART_ClearFlag(USART2, USART_IT_RXNE); //清除标志位;

        res=USART_ReceiveData(USART2); //接收数据;

        USART2_Send_Byte(res); //用户自定义;

    }  




void USART3_Configuration(void)

{

    GPIO_InitTypeDef GPIO_InitStructure;

    USART_InitTypeDef USART_InitStructure;

    NVIC_InitTypeDef NVIC_InitStructure;        


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE );

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE );


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //USART3 TX;

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

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOB, &GPIO_InitStructure); //端口B;


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; //USART3 RX;

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

    GPIO_Init(GPIOB, &GPIO_InitStructure); //端口B;


    USART_InitStructure.USART_BaudRate = 9600; //波特率;

    USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位8位;

    USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位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(USART3, &USART_InitStructure);//配置串口参数;


    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断组,4位抢占优先级,4位响应优先级;


    NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; //中断号;

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

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应优先级;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);


    USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);

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

}


void USART3_Send_Byte(u8 Data) //发送一个字节;

{

    USART_SendData(USART3,Data);

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

}


void USART3_Send_String(u8 *Data) //发送字符串;

{

while(*Data)

USART3_Send_Byte(*Data++);

}


void USART3_IRQHandler(void) //中断处理函数;

{

    u8 res;    

    if(USART_GetITStatus(USART3, USART_IT_RXNE) == SET) //判断是否发生中断;

    {

        USART_ClearFlag(USART3, USART_IT_RXNE); //清除标志位;

        res=USART_ReceiveData(USART3); //接收数据;

        USART3_Send_Byte(res); //用户自定义;

    }  




void UART4_Configuration(void)

{

    GPIO_InitTypeDef GPIO_InitStructure;

    USART_InitTypeDef USART_InitStructure;

[1] [2]

关键字:STM32  串口  使用方法

编辑:什么鱼 引用地址:http://www.eeworld.com.cn/mcu/ic467520.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:STM32定时器和外部触发同步的应用
下一篇:STM32--同时应用三个串口的应用代码

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM32 Systick定时器在实现1us延时时的问题与解决

问题:使用systick_config()函数来实现计数,这个函数在下面代码中的 SysTick_CTRL_TICKINT_Msk 开启了中断。不论系统时钟为72Mhz或36Mhz若设置STM32每10us进入一次中断,计时是可以的;而每1us进入中断,由于中断指令较多,那么程序就会困在中断里出不来。static __INLINE uint32_t SysTick_Config(uint32_t ticks){   if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);           
发表于 2019-07-17

stm32 ADC知识总结(二)

关于STM32的ADC的一些重要特点需要记住: 1)STM32F103系列至少有2个ADC,这些ADC可以独立使用,也可以使用双重模式(提高采样率); 2)STM32的ADC是12位逐次逼近型的模数转换器,一共有18个通道,可以测量16个外部信号和2个内部信号源; 3)每个通道的ADC可以在单次、连续、扫描或者间断模式下进行; 4)前面讲过STM32的ADC是12位的,结果存储在16位的数据寄存器中,有4位用不到,所以ADC存在左对齐或右对齐的方式; 5)模拟看门狗允许应用程序检测输入电压是否超出用户定义的高低阈值; 6)STM32的ADC最大的转换速率为1MHz
发表于 2019-07-17
stm32 ADC知识总结(二)

stm32f070 stop 模式 rtc定时启动调试总结

stm32f070 stop 模式 rtc定时启动调试总结。1.在进stoop模式之前一定对gpio进行配置。/* GPIO Ports Clock Enable */__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_GPIOF_CLK_ENABLE();/Configure GPIO pins : GPIO_PIN_All/GPIO_InitStruct.Pin = GPIO_PIN_All;GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;GPIO_InitStruct.Pull = GPIO_NOPULL
发表于 2019-07-17

RTC_WakeUp中断唤醒STM32F4停止模式

RTC_WakeUp唤醒STM32F4停止模式(借鉴的是原子哥写的代码): 首先我们先初始化RTC配置://RTC初始化u8 MyRTC_Init(void){    RTC_InitTypeDef RTC_InitStructrue;    u16 retry=0x1FFF;    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);//使能PWR时钟    PWR_BackupAccessCmd(ENABLE);//使能后备寄存器    if
发表于 2019-07-17

关于stm32stop模式下,串口唤醒中的问题及解决办法

首先讲一下应用场景:STM32F1 + HAL库+ Freertos ,STOP模式下利用串口引脚唤醒。stop mode 处理内容如下:1,配置所有引脚为模拟输入(参考官方代码)2,配置串口接收引脚为外部中断3,进入stop mode4,初始化串口等外设现象:第一次从stop模式唤醒时串口能正常通信,判断一段时间后无数据则再一次进入stop mode,然后再一次唤醒,此时串口无法输出。最后发现原因是串口重新初始化时HAL_UART_Init()函数中会判断if(huart->State == HAL_UART_STATE_RESET),此时才会执行HAL_UART_MspInit(huart),配置串口IO口。解决办法
发表于 2019-07-17

STM32开发笔记1: STM32F407时钟配置

单片机型号:STM32F407    本文讲解STMF407时钟的使用及其配置方法。        1、STM32F407的分类        a、LSI是低速内部时钟,RC震荡器,频率为32KHz左右。供独立看门狗和自动唤醒单元使用。        b、LSE是低速外部时钟,接频率为32.768KHz的石英晶体。这个主要是RTC的时钟源。        c、HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围
发表于 2019-07-17
STM32开发笔记1: STM32F407时钟配置

小广播

何立民专栏

单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved