历史上的今天
返回首页

历史上的今天

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

正在发生

2018年08月13日 | STM32F1的5个串口使用方法

2018-08-13 来源:eefocus

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

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


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

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 );

2.  配置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;

NVIC_InitTypeDef NVIC_InitStructure;        

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE );

RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE );

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //UART4 TX;

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

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOC, &GPIO_InitStructure); //端口C;

    

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; //UART4 RX;

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

GPIO_Init(GPIOC, &GPIO_InitStructure); //端口C;

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(UART4, &USART_InitStructure);//配置串口参数;

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

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

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

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

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);

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

}

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

{

USART_SendData(UART4,Data);

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

}

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

{

while(*Data)

UART4_Send_Byte(*Data++);

}

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

{

u8 res;    

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

{

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

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

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

}  

void UART5_Configuration(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

USART_InitTypeDef USART_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;        

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD, ENABLE );

RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE );

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; //UART5 TX;

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

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOC, &GPIO_InitStructure); //端口C;

    

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //UART5 RX;

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

GPIO_Init(GPIOD, &GPIO_InitStructure); //端口D;

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(UART5, &USART_InitStructure);//配置串口参数;

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

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

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

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

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

USART_ITConfig(UART5, USART_IT_RXNE, ENABLE);

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

}

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

{

USART_SendData(UART5,Data);

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

}

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

{

while(*Data)

UART5_Send_Byte(*Data++);

}

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

{

u8 res;    

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

{

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

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

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

}  


推荐阅读

史海拾趣

Holy Stone公司的发展小趣事

经过多年的发展,Holy Stone成为国内少数涵盖主、被动双通路并拥有制造工厂的多元化公司。公司不仅代理多家国际知名半导体零组件,还通过自主研发和生产,为客户提供完整的解决方案及多样性零组件。这一双通路战略使得Holy Stone能够在激烈的市场竞争中保持领先地位,并成功实现全球布局。公司的产品广泛应用于消费电子、汽车电子等多个领域,满足了全球客户的多样化需求。

创都(CAX)公司的发展小趣事

随着市场竞争的加剧,单一企业的力量往往难以应对复杂多变的市场环境。创都公司意识到了这一点,因此积极寻求跨界合作的机会。他们与多家知名企业建立了战略合作伙伴关系,共同研发新产品、开拓市场。这些合作不仅为创都公司带来了更多的资源和机会,还提升了公司的综合竞争力。其中,与某知名互联网公司的合作项目尤为成功,双方共同推出了一款智能家居产品,该产品凭借其便捷的功能和优秀的品质迅速在市场上走红,为双方带来了可观的收益。

Hind Rectifiers Ltd公司的发展小趣事

在电子行业的浪潮中,创都(CAX)公司凭借其卓越的技术创新能力,逐渐崭露头角。公司创始人李先生是一位热衷于新技术的电子工程师,他带领着一支由业内顶尖人才组成的研发团队,不断挑战技术极限。在一次偶然的机会中,他们成功研发出了一款具有革命性意义的高效能芯片,这款芯片不仅性能卓越,而且成本大幅降低,迅速在市场中获得了广泛认可。随着这款芯片的成功推出,创都公司的知名度迅速提升,订单量激增,公司也借此机会逐步扩大了生产规模和市场占有率。

Good-Ark公司的发展小趣事
包括放大器、滤波器等,用于对声音传感器输出的电信号进行处理,以提高信号的信噪比和识别度。
依必安派特(ebmpapst)公司的发展小趣事

1996年,依必安派特在上海外高桥保税区设立了其在中国的首个据点——依必安派特风机(上海)有限公司。最初,它仅作为销售为主的贸易公司,为中国市场提供德国制造的风机和电机产品。然而,随着中国市场的快速增长和需求的不断变化,依必安派特意识到仅仅作为贸易公司已无法满足市场需求。于是,在2000年,依必安派特电气(上海)有限公司正式成立,开始在上海本地生产风机和电机,标志着依必安派特从贸易到制造的转变。

Catalyst公司的发展小趣事

Catalyst公司深知品质是企业生存和发展的根本。因此,公司始终将品质管理放在首位,从原材料采购到生产加工、产品检验等各个环节都进行严格把控。公司还建立了完善的售后服务体系,确保客户在使用过程中能够得到及时、专业的技术支持。这些举措不仅提升了Catalyst产品的品质水平,也赢得了客户的信任和好评。

问答坊 | AI 解惑

红绿灯交流220V如何变成直流5V?

红绿灯交流220V如何变成直流5V? 有没有参考设计电路?…

查看全部问答>

STC89C52RC串口下载失败

编程器是按下面的图接的。 我是用STC-ISP软件下载的,COM口没错。 下面是下载失败的提示信息: Chinese:正在尝试与 MCU/单片机 握手连接 ... MCU Type is: STC89C52RC MCU Firmware Version: 4.3C Chinese:MCU 固件版本号: 4.3C Double s ...…

查看全部问答>

请教 我要扩充89s51 IO口 48个 选用何芯片 比较物美价廉

请教 我要扩充89s51  IO口 48个 选用何芯片 比较物美价廉…

查看全部问答>

说法太多了,HP Compaq nx6325 RD122AA#AB到底是否支持SATA,请明白的帮看看我的系统信息

http://photo1.bababian.com/upload14/20090207/651211455BCE31074A0A2B1FF588E4DE_500.jpg http://photo1.bababian.com/upload14/20090207/55CFC057F9DCF84795016970BDC17D0E_500.jpg http://photo1.bababian.com/upload14/20090207/B5D16 ...…

查看全部问答>

Camera全屏算法

wince6上开发出camera可以实现视频原始大小的播放。 可是用了几种算法扩展到全屏就播放的不流畅了。 一般嵌入式上的播放器是如何实现全屏算法的? 有什么优化方法吗?用的是ARM11的核。 谢谢。…

查看全部问答>

那位大虾有Dos 7.1的Debug,请给小弟一个,谢谢

在网上下了几个debug都提示dos版本不对,实在找不到dos 7.1下的debug,邮箱:jerk66@163.com,非常感谢…

查看全部问答>

ince的kernel start在哪?

請問wince的kernel start在哪? 有原始碼可以看嗎…

查看全部问答>

WinCE5.0不加载explorer.exe无法保存注删表

我的注册表是基于hive方式的,一切都很正常,但是修改注册表: [HKEY_LOCAL_MACHINE\\init] \"Launch50\"=\"MyApplication.exe\" \"Depend50\"=hex:14,00, 1e,00 即explorer.exe用我自己的程序代替,不加载桌面而启动我的程序,这时出现注册表 ...…

查看全部问答>

芯片复位问题

最近使用msp430f123单片机作产品,发现在上电复位时,有时程序没有运行,就是输出信号不对。怀疑是复位电路的问题,使用的是最简单的阻容复位(电阻100k,电容0.1uF)。断电后测试复位引脚上有0.25V的电压。成功复位次数很少,这个问题怎么解决?必 ...…

查看全部问答>

常用电子元器件手册

本帖最后由 paulhyde 于 2014-9-15 03:32 编辑 常用电子元器件手册    …

查看全部问答>