[STM32F1] stm32f1串口发送与接收

[复制链接]
1637|56
 楼主| 9dome猫 发表于 2023-3-28 17:36 | 显示全部楼层 |阅读模式
串口配置

首先对串口进行初始化

包括使能串口时钟,这里我使用的是usart2,使能GPIO时钟,这里我用的是A口,以及GPIO口的配置,这里我的串口输出是PA2,输入是PA3

然后初始化usart2,再使能usart2,具体代码如下:


  1. /* 串口初始化 */

  2. void STM_EVAL_COMInit(USART_InitTypeDef* USART_InitStruct)
  3. {
  4.   GPIO_InitTypeDef GPIO_InitStructure;

  5.   /* Enable GPIO clock */
  6.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//GPIOA使能

  7.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);USART2时钟使能

  8.   /* Configure USART Tx as alternate function push-pull */
  9.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//输出PA2
  10.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  11.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  12.   GPIO_Init(GPIOA, &GPIO_InitStructure);

  13.   /* Configure USART Rx as input floating */
  14.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//输入PA3
  15.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
  16.   GPIO_Init(GPIOA, &GPIO_InitStructure);

  17.   /* USART configuration */
  18.   USART_Init(USART2, USART_InitStruct);//USART2初始化
  19.    
  20.   /* Enable USART */
  21.   USART_Cmd(USART2, ENABLE);//使能USART2
  22. }


 楼主| 9dome猫 发表于 2023-3-28 17:36 | 显示全部楼层
之后需要配置串口的参数

参数包括波特率,数据位个数,是否有校验位等
  1. void USART2_Init (void)
  2. {
  3.         USART_InitTypeDef USART_InitStructure;
  4.         NVIC_InitTypeDef NVIC_InitStructure;
  5.        
  6.         USART_InitStructure.USART_BaudRate = 115200;                  //波特率
  7.   USART_InitStructure.USART_WordLength = USART_WordLength_8b;   //数据位个数=8
  8.   USART_InitStructure.USART_StopBits = USART_StopBits_1;        //1个停止位
  9.   USART_InitStructure.USART_Parity = USART_Parity_No;           //没有校验位
  10.   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  11.   USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

  12.   STM_EVAL_COMInit(&USART_InitStructure);
  13.        
  14.        
  15. //数据接收的使能中断
  16.   /* Enable the USARTz Interrupt */
  17.   NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;//为USART2
  18.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  19.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  20.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  21.   NVIC_Init(&NVIC_InitStructure);
  22.        
  23.   /* Enable the USARTz Receive Interrupt */
  24.   USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//
  25. }

评论

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/weixin_46188211/article/details/123355402 ———————————————— 版权声明:本文为CSDN博主「朴实妲己」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/weixin_46188211/article  发表于 2023-3-29 01:21
 楼主| 9dome猫 发表于 2023-3-28 17:36 | 显示全部楼层
为了保证串口随时都能接收数据,需要开启中断

串口发送
串口发送是指,将stm32的数据发送给上位机(串口助手)
 楼主| 9dome猫 发表于 2023-3-29 01:15 | 显示全部楼层
1使用SendString函数发送
在.c文件里面定义SendString函数

对应USART数据发送有两个标志, 一个是TXE=发送数据寄存器空,另一个是TC=发送结束
 楼主| 9dome猫 发表于 2023-3-29 01:16 | 显示全部楼层
  1. void SendString (char *s)
  2. {
  3.         while(*s)
  4.         {
  5.                 USART_SendData(USART2, *s++);//依次发送

  6.   /* Loop until the end of transmission */
  7.   while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET)//TC标志位为reset发送结束
  8.   {}
  9.         }
  10. }
 楼主| 9dome猫 发表于 2023-3-29 01:17 | 显示全部楼层
在发送数据时出现第一个字符打印不出来的情况,例如发送“hello”,串口助手只接收到了“ello”,没有h

这是因为stm32的usart的sr寄存器的TC初始为1,导致第一次while时第一个数据被覆盖

这种情况,将TC修改为TXE即可

  1. void SendString (char *s)
  2. {
  3.         while(*s)
  4.         {
  5.                 USART_SendData(USART2, *s++);

  6.   /* Loop until the end of transmission */
  7.   while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)
  8.   {}
  9.         }
  10. }
 楼主| 9dome猫 发表于 2023-3-29 01:18 | 显示全部楼层
在main.c文件里面调用SendString函数

  1. USART2_Init();//打开串口
  2. SendString("字符串");
 楼主| 9dome猫 发表于 2023-3-29 01:18 | 显示全部楼层
2使用printf函数发送
在使用printf函数之前需要先勾选微库

1307164232169413dd.png
 楼主| 9dome猫 发表于 2023-3-29 01:18 | 显示全部楼层
在.c文件里面定义printf函数 ,代码如下
  1. int fputc(int ch, FILE *f)
  2. {
  3.   /* Place your implementation of fputc here */
  4.   /* e.g. write a character to the USART */
  5.   USART_SendData(USART2, (uint8_t) ch);

  6.   /* Loop until the end of transmission */
  7.   while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)
  8.   {}

  9.   return ch;
  10. }
 楼主| 9dome猫 发表于 2023-3-29 01:19 | 显示全部楼层
在main.c文件里面调用printf函数

USART2_Init();
printf(" ", );
 楼主| 9dome猫 发表于 2023-3-29 01:19 | 显示全部楼层
关于printf函数的使用方法可以参考下面的表格:
96460642321a6c606e.png
52489642321ad07848.png
 楼主| 9dome猫 发表于 2023-3-29 01:19 | 显示全部楼层
串口接收
串口接收是指,将上位机(串口助手)的数据发送给stm32,由stm32进行接收

USART_IT_RXNE为接收中断标志位,一旦接收数据,USART_IT_RXNE会置位
 楼主| 9dome猫 发表于 2023-3-29 01:19 | 显示全部楼层
  1. u8 RxCounter = 0;//定义计数值
  2. u8        RxBuffer2[10];//定义缓冲区为10

  3. void USART2_IRQHandler(void)
  4. {
  5.   if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)//串口接收中断
  6.   {
  7.     USART_ClearITPendingBit(USART2, USART_IT_RXNE);//清除标志位
  8.                 /* Read one byte from the receive data register */
  9.                
  10.     RxBuffer2[RxCounter++] = USART_ReceiveData(USART2);
  11.                
  12.                
  13.                 if(RxCounter>6)//定义接收的字节个数
  14.                 {
  15.                         RxCounter=0;
  16.                 }
  17. }       
  18. }
 楼主| 9dome猫 发表于 2023-3-29 01:20 | 显示全部楼层
串口接收
串口接收是指,将上位机(串口助手)的数据发送给stm32,由stm32进行接收

USART_IT_RXNE为接收中断标志位,一旦接收数据,USART_IT_RXNE会置位

 楼主| 9dome猫 发表于 2023-3-29 01:20 | 显示全部楼层
  1. u8 RxCounter = 0;//定义计数值
  2. u8        RxBuffer2[10];//定义缓冲区为10

  3. void USART2_IRQHandler(void)
  4. {
  5.   if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)//串口接收中断
  6.   {
  7.     USART_ClearITPendingBit(USART2, USART_IT_RXNE);//清除标志位
  8.                 /* Read one byte from the receive data register */
  9.                
  10.     RxBuffer2[RxCounter++] = USART_ReceiveData(USART2);
  11.                
  12.                
  13.                 if(RxCounter>6)//定义接收的字节个数
  14.                 {
  15.                         RxCounter=0;
  16.                 }
  17. }       
  18. }
 楼主| 9dome猫 发表于 2023-3-29 01:21 | 显示全部楼层
首先构建缓冲区和计数器

串口接收中断之后,清除 USART_IT_RXNE中断接收标志位,将串口接收到的数据存入缓冲区

可以通过debug里面的watch来看缓冲区数据是否正确
jiaxw 发表于 2023-3-30 20:36 | 显示全部楼层
参数包括波特率,数据位个数,是否有校验位等
jiaxw 发表于 2023-3-30 20:40 | 显示全部楼层
为了保证串口随时都能接收数据,需要开启中断
songqian17 发表于 2023-3-30 20:56 | 显示全部楼层
第一个字符打印不出来
huanghuac 发表于 2023-3-30 21:06 | 显示全部楼层
导致第一次while时第一个数据被覆盖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

142

主题

1593

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部