STM32 串口通讯

news2024/10/23 2:46:16

使用STM32的串口通讯,接收串口助手的数据,并且将接收到的数据返回串口,重定义printf功能。

配置引脚信息

由于每次新建工程都需要配置信息,比较麻烦,好在STM32CubeIDE提供了导入.ioc文件的功能,可以帮我们节省时间。

1.从BEEP的项目里导入ioc文件,并命名为Serial。

将串口1的mode修改为Asynchronous同步通讯,波特率为115200,数据宽度:8位,检验:None,停止位:1位。

image-20220309173020409

2.添加DMA发送通道

image-20220309174341557

3.打开串口1中断设置。

image-20220309174427994

核心代码解释

1.在BSP中新建蜂鸣器的驱动库bsp_uart.h和bsp_uart.c文件。在bsp_uart.h中增加以下内容:

/*
 * bsp_uart.h
 *
 *  Created on: Mar 4, 2022
 *      Author: Administrator
 */

#ifndef BSP_UART_H_
#define BSP_UART_H_

#include "stdint.h"



void USART1_Init(void);
void USART1_Send_U8(uint8_t ch);
void USART1_Send_ArrayU8(uint8_t *BufferPtr, uint16_t Length);


#endif /* BSP_UART_H_ */

2.在bsp_uart.c中添加以下内容:

/*
 * bsp_uart.c
 *
 *  Created on: Mar 4, 2022
 *      Author: Administrator
 */

#include "bsp_uart.h"
#include "bsp.h"

#define ENABLE_UART_DMA    1

uint8_t RxTemp = 0;

// Initialize USART1  初始化串口1
void USART1_Init(void)
{
    HAL_UART_Receive_IT(&huart1, (uint8_t *)&RxTemp, 1);
}

// The serial port sends one byte  串口发送一个字节
void USART1_Send_U8(uint8_t ch)
{
    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
}

// The serial port sends a string of data  串口发送一串数据
void USART1_Send_ArrayU8(uint8_t *BufferPtr, uint16_t Length)
{
    #if ENABLE_UART_DMA
    HAL_UART_Transmit_DMA(&huart1, BufferPtr, Length);
    #else
    while (Length--)
    {
        USART1_Send_U8(*BufferPtr);
        BufferPtr++;
    }
    #endif
}

// The serial port receiving is interrupted. Procedure  串口接收完成中断
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    /* Prevent unused argument(s) compilation warning */
    UNUSED(huart);
    /* NOTE : This function should not be modified, when the callback is needed,
              the HAL_UART_RxCpltCallback can be implemented in the user file
     */
    // 测试发送数据,实际应用中不应该在中断中发送数据
    // Test sending data. In practice, data should not be sent during interrupts  
    USART1_Send_U8(RxTemp);

    // Continue receiving data  继续接收数据
    HAL_UART_Receive_IT(&huart1, (uint8_t *)&RxTemp, 1);
}



#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
PUTCHAR_PROTOTYPE
{
    /* Place your implementation of fputc here */
    /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
    return ch;
}

USART1_Init():初始化串口相关内容,开启串口接收1个数据。

image-20220309183608315

USART1_Send_U8(ch):串口1发送一个字节。

image-20220309183632327

USART1_Send_ArrayU8(BufferPtr,Length):串口1发送一串数据,BufferPtr是数据的首地址,Length是数据的长度。ENABLE_UART_DMA是串口1 DMA的开关。

image-20220309183656718

3.由于串口1接收中断只进行一次,所以接收数据后需要再次调用接收数据。这里为了方便测试,所以在中断调用串口发送数据,实际应用中不应该在中断中发送数据,串口发送数据比较耗时,可能导致丢包甚至串口出错等问题。

image-20220309183851258

4.重新定义printf使用串口1发送数据。

image-20220309184205569

5.在BSP初始化中,调用USART1_Init()函数,请求接收数据。

image-20220310092311388

//bsp.c
#include "bsp.h"

// LED显示当前运行状态,每10毫秒调用一次,LED灯每200毫秒闪烁一次。
// The LED displays the current operating status, which is invoked every 10 milliseconds, and the LED blinks every 200 milliseconds.  
static void Bsp_Led_Show_State_Handle(void)
{
	static uint8_t led_count = 0;
	led_count++;
	if (led_count > 20)
	{
		led_count = 0;
		LED_TOGGLE();
	}
}


// The peripheral device is initialized  外设设备初始化
void Bsp_Init(void)
{
	Beep_On_Time(50);
	USART1_Init();
}


// main.c中循环调用此函数,避免多次修改main.c文件。
// This function is called in a loop in main.c to avoid multiple modifications to the main.c file
void Bsp_Loop(void)
{
	// Detect button down events   检测按键按下事件
	if (Key1_State(KEY_MODE_ONE_TIME))
	{
		Beep_On_Time(50);
		static int press = 0;
		press++;
		printf("press:%d\n", press);
	}

	Bsp_Led_Show_State_Handle();
	// The buzzer automatically shuts down when times out   蜂鸣器超时自动关闭
	Beep_Timeout_Close_Handle();
	HAL_Delay(10);
}

 

6.在按键按下后,增加printf()函数,通过串口1打印信息。

image-20220310092529061

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "dma.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "bsp.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  Bsp_Init();
  /* USER CODE END 2 */

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

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

实验效果

烧录程序后,LED灯每隔200毫秒闪一次,将扩展板通过micro-USB数据线与电脑连接后并打开串口助手(具体参数如下图所示),每按一次按键,蜂鸣器都会响50毫秒,可以看到串口助手会显示press:xx,每按一次按键xx自动加1。串口助手发送字符a,扩展板会自动将字符a返回。由于上面使用在中断中发送数据,所以不能一次发送太多个字符,否则会出现字符丢失甚至串口错误。

image-20220310094043392

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1844266.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

达梦8 兼容MySQL语法支持非分组项作为查询列

MySQL 数据库迁移到达梦后,部分GROUP BY语句执行失败,报错如下: 问题原因: 对于Oracle数据库,使用GROUP BY时,SELECT中的非聚合列必须出现在GROUP BY后面,否则就会报上面的错误,达梦…

基于python+tkinter(Gui)的学生信息管理系统

博主介绍: 大家好,本人精通Java、Python、C#、C、C编程语言,同时也熟练掌握微信小程序、Php和Android等技术,能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验,能够为学生提供各类…

[创业之路-119] :制造业企业的必备管理神器-ERP-主要功能模块说明与系统架构

目录 一、ERP功能的标准化 二、常见的ERP标准化功能 2.1 基础档案 2.2 供应链 2.3 人力资源管理 2.4 资产管理 2.5 生产制造 2.6 财务会计 2.7 管理会计 2.8 CRM客户管理管理 2.9 商业智能分析 三、常见的ERP软件供应商 国内ERP软件供应商 国外ERP软件供应商 四…

2024考古之还在用原始JDBC开发 手搓 案例 实现一个模块的增删改

JDBC案例 将来如果完成的话 就代表对JDBC里面的知识点全部融会贯通了 其实就是对数据的增删改查 我们入门做不出来前端的内容 很正常 准备环境 建表 use mybatis;create table tbl_brand (id int primary key auto_increment,brand_name varchar(20),company_name varcha…

在hue中使用ooize调度ssh任务无法执行成功,无法查看错误

ssh执行失败,但是hue没有给出明确的错误原因: 经过经验分析,原来是服务器上的sh文件用的是doc/window格式,需要使用notepad将格式改为unix之后就可以正常执行。 特此记录,避免遗忘知识点

图标设计新手手册:应用图标尺寸比例全解析

通常我们在App Store中寻找新的应用程序时,首先会快速扫描搜索栏中的一些关键词,然后选择感兴趣的应用程序,在选定的应用页面中查看具体信息,最后决定是否下载。在这一系列操作中,APP图标的大小比例是影响用户体验的关…

大腾智能,基于云原生的国产工业协同平台

大腾智能是一家基于云原生的国产工业软件与数字化协同平台,专注于推动企业数字化转型与升级,为企业提供一系列专业、高效的云原生数字化软件及方案,推动产品设计、生产及营销展示的革新,实现可持续发展。 大腾智能旗下产品 3D模型…

前端构建工具用得好,构建速度提升 10 倍

今天来盘点一下前端构建工具。 Turbopack Turbopack,由Vercel开源,是下一代高性能的JavaScript应用构建工具,目前用于 Next.js 中。Turbopack旨在通过革新JavaScript应用的打包流程来显著提升应用性能,它专注于缩短加载时间&…

小阿轩yx-Tomcat 部署及优化

小阿轩yx-Tomcat 部署及优化 Tomcat 概述 免费的、开放源代码的Web应用服务器Apache软件基金会(Apache Software Foundation)Jakarta项目中的一个核心项目由Apache、Sun和一些公司及个人共同开发而成深受Java爱好者的喜爱,并得到部分软件开发商的认可目前比较流行的Web应用服…

强化学习——基本概念

何为强化学习 机器学习的一大分支 强化学习(Reinforcement Learning)是机器学习的一种,它通过与环境不断地交互,借助环境的反馈来调整自己的行为,使得累计回报最大。强化学习要解决的是决策问题——求取当前状态下最…

sql资料库

1、distinct(关键词distinct用于返回唯一不同的值):查询结果中去除重复行的关键字 select distinct(university) from user_profile select distinct university from user_profile distinct是紧跟在select后面的,不能在其他位置,不然就…

充电学习— 9、Typec Pd

GND:线缆接地 TX RX:数据流data传输,支持2.0 3.0 speed兼容 VBUS:线缆cable电源,bus power CC:电缆cable的连接、方向、角色检测和当前模式的配置通道; 有emark时, 一个成为VCONN&am…

Flutter【组件】按钮

简介 flutter 按钮组件。提供一种封装按钮组件的思路,并不支持过多的自定义属性。根据使用场景及设计规范进行封装,使用起来比较方便。 github地址:https://github.com/ThinkerJack/jac_uikit pub地址:https://pub.dev/package…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 密码解密(100分) - 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 &#x1f…

【多模态论文】CLIP(Contrastive Language-Image Pre-training)

论文:Learning Transferable Visual Models From Natural Language Supervision 链接:https://arxiv.org/abs/2103.00020 摘要 问题: 对预定的类别进行预测,这种有监督的训练形式受限于额外标记数据 。如何利用图像的原始文本来获…

MEME使用-motif分析(生物信息学工具-24)

01 背景 Motif分析是一种在生物信息学和计算生物学中广泛应用的技术,用于识别DNA、RNA或蛋白质序列中具有生物学功能的短保守序列模式(motif)。这些motif通常与特定的生物学功能相关,如DNA中的转录因子结合位点、RNA中的剪接位点…

VSCode调试python没有反应

原因&#xff1a;python的版本太低了&#xff0c;我的项目的python是3.5的&#xff0c;VSCode python debugger不支持低版本的python。 解决方法&#xff1a; debugging - debug python versions < 3.5 with vscode new debugger - Stack Overflow 安装支持低版本的Debug…

项目八 OpenStack存储管理

任务一 理解OpenStack块存储服务 1.1 •Cinder的主要功能 • 提供 持久性块存储资源&#xff0c;供 Nova 计算服务的虚拟机实例使用 。 • 为 管理块存储设备提供一套方法&#xff0c;对卷实现从创建到删除的整个生命周期 管理。 • 将 不同的后端存储进行封装&#xff0c;对外…

ScheduledExecutorService引起的线上问题(抛出异常后不继续执行)

线上有一个服务&#xff0c;采用ScheduledExecutorService定时任务刷新数据库数据到本地缓存作为路由信息 private ScheduledExecutorService scheduledExecutorService Executors.newScheduledThreadPool(1);scheduledExecutorService.scheduleWithFixedDelay(new Runnable()…

electron下载失败(electron如何切换镜像源)

打开&#xff1a; 或者&#xff1a; C:\Users\用户名\.npmrc 添加&#xff1a; electron_mirrorhttps://npmmirror.com/mirrors/electron/ 到文件中&#xff0c;保存 方法二&#xff1a; npm config set ELECTRON_MIRROR https://npmmirror.com/mirrors/electron/ ELECTR…