基于STM32F1以及STM32CubeMx实现串口中断通讯(字符串发送与接收)

STM32CubeMx软件设置

首先选好自己的板子并打开软件设置,本实验基于STM32F103ZET6实现,打开软件后如图:
在这里插入图片描述
打开外部高速晶振,然后接着配置时钟:
在这里插入图片描述
将时钟频率修改为72MHz,接着设置接线方式为SW
在这里插入图片描述
接下来需要使用串口中断通讯,打开我们的串口设置并打开中断
在这里插入图片描述
这里波特率设置为115200,数据位为8位,无校验位,停止位为1位,通信模式设置为异步通信,以及可以接受及发送数据。
在这里插入图片描述
接着打开中断,并设置抢占优先级和响应优先级,这里设置为0,0。
至此STM32CubeMx就设置完成了。

Keil软件及代码编写

打开Keil以后生成以下文件:
在这里插入图片描述
这里的uart.c是我自己编写的,方便后续管理,我们先来看看usart.c中的初始化函数:
在这里插入图片描述
在这里插入图片描述
分别有两个函数,一个设置我们的串口相关功能,一个则是打开我们所需要功能的时钟、配置相应的IO口,以及打开中断。
接下来看中断的相关处理
在这里插入图片描述
Hal库的中断处理函数都会放在这个it.c文件中,然后函数内部会调用关于串口的中断公共处理函数,并且会在里面失能中断,所以添加一个while重新使能中断。
关于函数的快速查找可以点击左边窗口下方的functions打开对应的文件就能找到我们所需的函数:
在这里插入图片描述
接着通过跳转功能进入中断的公共处理函数,并找到对应的中断回调函数,即:

在这里插入图片描述
这里是一个弱定义,里面是空,即用户需要使用到时可以自己进行改写,所以下一步就是来编写所需要的功能:

串口的功能设计

uart.h编写

#ifndef __UART_H
#define __UART_H

#include "usart.h"

#define uart_len 200
#define hal_uart_len 1

extern uint8_t g_rx[uart_len];                  //存放字符串数组
extern uint8_t g_rx_buffer[hal_uart_len];       //HAL库用存放缓存区

/* 存放数据标志位
   以回车换行符进行判断接收完毕
   15位置1表示接收到换行符,14位置1表示接收到回车
*/

extern uint16_t  g_usart1_rx_sta;


#endif

uart.c编写

uint8_t g_rx[uart_len];                  //存放字符串数组
uint8_t g_rx_buffer[hal_uart_len];       //HAL库用存放缓存区

uint16_t  g_usart1_rx_sta = 0;

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if((g_usart1_rx_sta & 0x8000) == 0)         //判断标志位15位是否被置1,若为0则接受还没结束
    {
        if(g_usart1_rx_sta & 0x4000)            //判断标志位14位是否被置1
        {
            if(g_rx_buffer[0] != 0x0a)
            {
                g_usart1_rx_sta = 0;            //若接收到回车后下一位不为换行则接收失败
            }
            else
            {
                g_usart1_rx_sta |= 0x8000;
            }
        }
        else
        {
            if(g_rx_buffer[0] == 0x0d)          //判断缓存器中当前是否接收到回车
            {
                g_usart1_rx_sta |= 0x4000;
            }
            else
            {
                //数据转移
                g_rx[g_usart1_rx_sta & 0x3fff] = g_rx_buffer[0];
                g_usart1_rx_sta++;
                
                //超出数组存放上限
                if(g_usart1_rx_sta > (uart_len-1))
                {
                    g_usart1_rx_sta = 0;
                }
            }
            
        }
    }
}

这里通过设定一个g_usart1_rx_sta标志位来判断接收到的数据有多长,这里设定字符串加上回车就代表发送完成,即需要判断是否收到\r\n来判断接收是否终止。\r的ascii值为0x0d,\n的ascii值为0x0a。

主函数的编写

  /* USER CODE BEGIN 2 */
    //接收数据使能中断
    HAL_UART_Receive_IT(&huart1, (uint8_t*)g_rx_buffer, hal_uart_len);
    uint8_t len = 0;
    uint16_t time = 0;
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
      if (g_usart1_rx_sta & 0x8000)        /* 接收到了数据? */
        {
            len = g_usart1_rx_sta & 0x3fff;  /* 得到此次接收到的数据长度 */
            printf("\r\n您发送的消息为:\r\n");

            HAL_UART_Transmit(&huart1,(uint8_t*)g_rx, len, 1000);    /* 发送接收到的数据 */
            while(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_TC) != SET);           /* 等待发送结束 */
            printf("\r\n\r\n");             /* 插入换行 */
            g_usart1_rx_sta = 0;
        }
        else
        {
            time++;

            if (time % 5000 == 0)
            {
                printf("\r\n串口实验\r\n");
            }

            if (time % 200 == 0) printf("请输入数据,以回车键结束\r\n");
            HAL_Delay(10);
        }
  }
  /* USER CODE END 3 */

这里是需要使用到串口中断接收,所以我们第一步是需要使能我们的串口中断接收,即下面这个函数:

HAL_UART_Receive_IT(&huart1, (uint8_t*)g_rx_buffer, hal_uart_len);

这个函数的第一个参数是句柄,也就是对应的初始化串口的结构体,可在usart.c中找到,第二个参数是接收的缓冲寄存器,即用户自己设定的寄存器,第三个则是接收长度。
然后接收完成后,通过len参数判断接收到的长度,在通过发送函数将数据发送回去,即下面这个函数:

HAL_UART_Transmit(&huart1,(uint8_t*)g_rx, len, 1000); 

这个函数的参数跟使能中断接收差不多,多了最后一个参数为超时时间,同时这个函数为阻塞发送,即数据没发送完就会一直发送无法处理其他事情。
同时还在这个主函数中添加了printf函数代表我们的STM32正常工作,需要用到这个printf函数我们就需要在usart.c中添加一个重定向函数:

/* USER CODE BEGIN 1 */
//串口打印重定向
int fputc(int ch, FILE *f)
{
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
  return ch;
}
/* USER CODE END 1 */

添加完成后再包含stdio.h头文件即可。

效果实现

在这里插入图片描述

  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
要在STM32F103ZE单片机中使用串口中断接收字符串,可以按照以下步骤进行: 1. 配置串口参数,包括波特率、数据位、校验位和停止位等。 2. 使能串口接收中断,使用HAL库可以通过`HAL_UART_Receive_IT()`函数实现。 3. 在串口接收中断处理函数中,判断是否接收到了完整的字符串,可以通过判断接收缓冲区中是否存在结束符(例如'\0')或者接收到一定长度的字符串来确定。 4. 如果接收到了完整的字符串,可以将其保存到一个缓冲区中,等待后续处理。 下面是一个简单的示例代码,可以接收最长为20个字符的字符串: ``` #include "stm32f1xx_hal.h" #define RX_BUFFER_SIZE 20 UART_HandleTypeDef huart1; uint8_t rx_buffer[RX_BUFFER_SIZE]; uint8_t rx_index = 0; void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart == &huart1) { if (rx_index < RX_BUFFER_SIZE - 1) { // 判断是否超出缓冲区大小 if (rx_buffer[rx_index] == '\n' || rx_buffer[rx_index] == '\r') { // 判断是否接收到结束符 rx_buffer[rx_index] = '\0'; // 添加字符串结束符 // 处理接收到的字符串 } else { rx_index++; } } else { rx_index = 0; // 超出缓冲区大小,重新开始接收 } HAL_UART_Receive_IT(&huart1, &rx_buffer[rx_index], 1); // 继续接收下一个字符 } } int main(void) { HAL_Init(); // 配置串口参数 huart1.Instance = USART1; huart1.Init.BaudRate = 9600; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; HAL_UART_Init(&huart1); // 使能串口接收中断 HAL_UART_Receive_IT(&huart1, &rx_buffer[rx_index], 1); while (1) { // 主循环 } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

葛叶灬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值