历史上的今天
返回首页

历史上的今天

今天是:2025年12月20日(星期六)

2022年12月20日 | 零基础学习stm32串口给大家总结5个串口的应用及注意事项

2022-12-20 来源:zhihu

  串口是我们常用的一个数据传输接口,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 );

  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;

  //收发模式;

推荐阅读

史海拾趣

福建国光公司的发展小趣事

对于具有锁定功能的物体检测报警电路,网友可能会有多种问题,以下是一些常见问题及其回答:

一、电路工作原理相关问题

  1. 问题:具有锁定功能的物体检测报警电路是如何工作的?
    回答:该电路通常包括光电检测部分、信号处理部分和报警输出部分。当有人或物体入侵到光电检测的空间时,光被遮挡,导致光敏晶体管截止,其集电极电压上升。这一变化被信号处理部分检测并转换为控制信号,使报警电路启动,发出声音或光等报警信号。同时,电路具有锁定功能,即一旦报警触发,需要特定操作(如断开开关)才能解除报警状态。

  2. 问题:锁定功能是如何实现的?
    回答:锁定功能通常通过记忆电路或状态保持电路实现。当报警信号被触发后,这部分电路会保持一个高电平或低电平状态,使报警信号持续输出,直到接收到解除报警的外部信号(如断开开关)。这种设计可以防止短暂的遮挡或误触发导致的短暂报警,提高系统的稳定性和可靠性。

二、电路设计与实现相关问题

  1. 问题:在设计具有锁定功能的物体检测报警电路时,需要考虑哪些因素?
    回答:设计时需要考虑的因素包括检测灵敏度、报警响应时间、误报率、功耗、成本以及与其他系统的兼容性等。此外,还需要考虑电路的稳定性、可靠性和安全性,确保在各种环境条件下都能正常工作。

  2. 问题:如何降低电路的误报率?
    回答:降低误报率的方法包括优化光电检测器的布局和参数设置,以减少外界光线的干扰;采用信号处理算法对检测信号进行滤波和去噪处理;以及设置合理的报警阈值等。此外,还可以通过增加确认机制(如二次检测)来进一步降低误报率。

三、电路应用与维护相关问题

  1. 问题:这种电路在哪些领域有应用?
    回答:具有锁定功能的物体检测报警电路在多个领域都有广泛应用,如安防监控、工业自动化、智能家居等。在安防监控领域,它可以用于入侵检测、门窗防护等场景;在工业自动化领域,可以用于生产线上的物料检测、机器人避障等场景;在智能家居领域,则可以用于门窗传感器、人体存在检测等场景。

  2. 问题:如何对电路进行日常维护和故障排查?
    回答:日常维护包括定期检查电路的连接是否牢固、光电检测器是否清洁无遮挡等。故障排查时,可以使用万用表等工具检测电路各部分的电压和电流是否正常,定位故障点。同时,也可以结合报警记录和监控视频等信息进行综合分析,以快速准确地判断故障原因并采取相应的解决措施。

以上是针对具有锁定功能的物体检测报警电路可能提出的问题及其回答。需要注意的是,由于电路的具体设计和实现方式可能因应用场景和需求的不同而有所差异,因此在实际应用中还需要根据具体情况进行调整和优化。

Dongguan City Niuhang Electronics Co.LTD公司的发展小趣事

在技术创新的基础上,Dongguan City Niuhang Electronics Co.LTD开始积极拓展市场。公司先后在安徽省池州市、江苏省扬州市和宿迁市等地设立生产基地,形成了覆盖全国的销售网络。同时,公司还加强品牌建设,通过参加行业展会、举办技术研讨会等方式,提升品牌知名度和影响力。随着市场的不断扩大,公司的销售业绩也实现了快速增长。

American Micro Products Inc公司的发展小趣事

为了保持技术的领先地位,AMP高度重视研发团队的建设和人才培养。公司投入大量资源用于引进和培养高端人才,为研发团队提供了一流的工作环境和研发设备。这些人才为AMP的技术创新和产品升级提供了强有力的支持。

Enable Semiconductor Corp公司的发展小趣事

在半导体产业链中,Enable Semiconductor Corp公司注重与上下游企业的合作。公司与多家芯片设计公司、封装测试企业建立了紧密的合作关系,共同开发新产品、新技术。这种合作模式不仅降低了公司的研发成本,也加快了产品上市的速度。同时,通过与合作伙伴的资源共享和优势互补,Enable Semiconductor Corp公司在市场上形成了强大的竞争力。

AC Photonics Inc公司的发展小趣事

AC Photonics Inc深知品质是企业生存和发展的关键。因此,公司始终将品质管理放在首位,从原材料采购到生产流程控制,再到产品出厂检验,都严格遵循国际标准和行业规范。同时,公司还注重品牌建设,通过参加行业展会、举办技术研讨会等方式,不断提升品牌知名度和美誉度。这些努力使得AC Photonics Inc的产品在市场上获得了广泛的认可和好评。

思瑞浦微电子科技(3PEAK INCORPORATED)公司的发展小趣事

随着电子行业的快速发展和市场竞争的加剧,AC Photonics Inc也面临着诸多挑战。然而,公司始终保持着敏锐的市场洞察力和应变能力。在面对行业变革和技术升级时,公司能够及时调整战略方向,加大研发投入,推出更具竞争力的新产品。同时,公司还积极探索新的商业模式和市场机会,为未来的发展奠定了坚实的基础。


以上五个故事均是基于一般性的电子行业发展模式虚构的,旨在展示AC Photonics Inc公司可能的发展路径和经历。实际情况可能有所不同,具体细节需要参考公司的官方资料和历史记录。

问答坊 | AI 解惑

用电阻做功率模拟

请教各位,我现在测一块散热板的散热效率,打算用铜壳线绕电阻做一个30W的发热源,电阻型号有以下几款 220Ω/5W;500Ω/8W;输入电压在60V左右,请问应该怎样排列电阻效果才好?谢谢!…

查看全部问答>

闪电击中世界最高建筑哈利法塔

上面这张令人震惊的照片展示了世界最高建筑哈利法塔遭闪电击中时的场面。 照片的拍摄者是一位23岁名叫穆罕默德·哈姆丹的学生,来自巴基斯坦,目前在阿联酋攻读建筑工程学。当时,迪拜正遭受暴风雨的袭击。雷电中,高达828米的哈利法塔在紫色的 ...…

查看全部问答>

今天参加mcu day赠送的一款开发板

参加TI mcu Day时,送的开发板,据说可以当做jtag仿真器使用,双重功能!!!…

查看全部问答>

U盘多盘符的问题

我在一个嵌入式系统中,主机在GET MAX LUN我已经返回01,但是主机并未显示2个盘符.仅仅出现了一个盘符 还需要做哪方面的工作…

查看全部问答>

关于桥式整流

这是在空闲之际模拟的几张桥式整流和接电容的图片,希望能对大家有点用处。    大家注意看波形随着电容的变化而变化。…

查看全部问答>

hmc5883的程序有人做过么?我的程序哪里出问题了?本人菜鸟,见笑了。

调了好几个小时了,就是不知道问题在哪里,请高手们指点。 测量先不说,就是怎么读寄存器都没弄清。 看了中文的pdf了,但是还是没搞懂,先看看我的程序吧。 程序部分(已近将无关部分删除): uchar code table[]=\"0123456789\"; //////////// ...…

查看全部问答>

有谁用了ADS8332,求程序!

最近用到团购买回来的ADS8332,但是调试了两天没成功,求助各位!谢谢!…

查看全部问答>

debug正常,51运算错误

已经用其他程序试验过了,不是xdata的问题,xdata里的数据能正常使用。我在用51做一个32点的fft。 部分代码如下: #include #include #define  uchar  unsigned  char #define  uint unsigned int ...…

查看全部问答>

谁用单片机驱动过PS2的数字小键盘?

我在网上买了一块PS2的数字小键盘,就是传统台式机键盘最右边的数字键部分。 学习了一下PS2及扫描编码相关内容,看懂了程序,但是,由于小键盘只有部分按键,有的键还是不能读取。 0—9数字键是可以输入的,小键盘的enter也能读取,但+、-、*、/ ...…

查看全部问答>