【蓝桥杯嵌入式】四、各种外设驱动(十)USART+DMA通信方式和串口通信协议的设计与使用

news2024/9/20 1:18:51

温馨提示:本文不会重复之前提到的内容,如需查看,请参考附录

【蓝桥杯嵌入式】附录

目录

重点提炼:

一、需求分析

1、需要的外设资源分析:

 2、外设具体分析:

CubeMX配置中,我们需要改动的参数:

USART1:

DMA:

二、软件配置

按照分析配置:

然后配置USART1 的 DMA Settings :

打开并设置中断优先级:

三、程序功能实现

用到的函数:

程序流程:

在MDK中编写代码:

四、运行测试


重点提炼:

用到的函数:

一、需求分析

        我们将设计一个示例项目USART_DMA_Demo,进行计算机和开发板之间的串口通信。
        本示例要使用USART1和对应的DMA,还要使用RTC的周期唤醒功能。示例的功能和操作流程如下。

  • 在RTC周期唤醒中断里,读取当前时间后在LCD上显示,将时间转换为字符串之后,通过串口发送给计算机。
  • 在计算机上使用串口监视软件查看接收的数据,并且可以向开发板发送指令数据。
  • MCU 持续以DMA方式进行串口数据接收,接收到一条指令后就解析并执行指令的任务,例如修改当前时间。

        在计算机与开发板的串口通信中,我们一般将计算机称为上位机,将开发板称为下位机。串口的硬件层实现了数据的收发,发送的数据具体是什么意义,需要规定上位机和下位机之间的通信协议。这种通信协议就是传输数据的格式规范及其意义。在本示例中,上位机向开发板发送的串口数据的格式定义如下表所示:

上位机向开发板发送数据的格式定义(xx表示两个位数的数字)
上位机发送的指令字符串指令功能
#Hxx;设置小时,将RTC时间的小时改为xx
#Mxx设置分钟,将RTC时间的分钟改为xx
#Sxx设置秒,将RTC时间的秒改为xx
#U01;或#U00;设置上传数据,或不上传数据

        上位机发送的指令数据固定为5字节,每个指令以#开始,以;结束。紧跟在#后面的一个字母表示指令类型,例如,H表示修改小时,M表示修改分钟。类型字符后面是两位数字,表示指令的参数,例如,"#H13;"表示要将RTC的当前时间的小时数修改为13。
        在计算机上,我们需要使用一个串口通信软件与开发板之间进行串口通信测试。比赛时会提供这样的工具。当波特率设置的和MCU串口的波特率相同时才可以进行通信。串口工具使用起来很简单,只需要设置好串口号和波特率就行,如图:

1、需要的外设资源分析:

  • USART1 (占用引脚PA9和PA10);
  • DMA2;
  • LCD;
  • RTC;

 2、外设具体分析:

查看原理图,和手册。

CubeMX配置中,我们需要改动的参数:
USART1:
  • Mode:工作模式。一般设置为Asynchronous(异步);
  • Baud Rate:波特率。CubeMX默认为115200bit/s,那就设置成115200bit/s即可。
  • Data Direction:数据传输方向。
DMA:

在有DMA功能的外设中都有对DMA的设置,找到USART1的DMA设置模块,点击Add即可添加一个DMA通道。

  • Channel: DMA 通道。每个DMA 请求可用的 DMA 通道会自动列出,选择一个即可。
  • Direction:传输方向。也就是DMA传输模式,会根据DMA请求的特性列出可选项。USARTI RX 是USARTI的DMA 数据输入请求,是将USART1接收的数据存入缓冲区,所以方向是Peripheral To Memory(外设到存储器);USART1 TX是USARTI的DMA 数据输出请求,是将缓冲区的数据用 USART1 输出,所以方向是Memory to Peripheral(存储器到外设)。
  • Priority:优先级别。DMA 流的软件优先级别有Low、Medium、

然后点击 Select 选择通道请求,串口有两个请求。

选择一个DMA流对象后,会弹出DMA请求设置栏:

  • Mode:DMA模式。普通模式和循环模式
  • Data Width: 数据宽度。外设和存储器需要单独设置数据宽度,数据宽度选项有Byte.
    Half Word 和 Word。串口传输数据的基本单位是字节,缓冲区的基本单位也是字节。
  • Increment Address:地址自增。这是指DMA传输个基本数据单位后,外设或存储器的地址是否自动增加,地址增量的大小就等于数据宽度。

二、软件配置

参考附录的内容,建立名为“USART_DMA_Demo”的项目。

按照分析配置:

LCD的设置参见附录。

RTC的配置参见上一篇文章的按照分析配置:

除了不打开闹钟外,其他配置类似。

这里只需要设置USART1 的模式为Asynchronous即可,其余保持。

然后配置USART1 的 DMA Settings :

Add两个DMA通道,会自动设置通道号和传输方向;将RX的优先级设置为中优先级,模式设置为循环模式;TX保持默认。如图所示:

打开并设置中断优先级:

        为DMA请求配置DMA 流之后,用到的DMA 流的中断会自动打开。要对DMA流的中断进行响应和处理,就必须开启USART1的全局中断。在NVIC组件里设置中断的优先级,如图所示:

        将USART1和两个DMA 流的中断抢占优先级都设置为1,因为在它们的中断处理函数里会用到函数HAL_Delay()。

生成项目文件后,打开MDK;

导入LCD驱动程序文件。

三、程序功能实现

用到的函数:

中断服务函数:

RX对应的通道的中断服务函数:

DMA1_Channel1_IRQHandler(void)

拓展:DMA模式的中断回调函数其实映射了对应外设的中断回调函数,这里使用中断回调函数更加合理。但由于比赛涉及的中断不多,不会引发冲突,所以这种直接在中断服务函数里实现代码的方式也是可行的。

USART函数:

 	HAL_UART_Transmit_DMA(设备句柄地址,数据指针,数据大小);
	HAL_UART_Receive_DMA(设备句柄地址,缓冲区指针,数据大小);

自定义函数:

解析指令函数

程序流程:

  1. 在初始化HAL库后初始化LCD,之前实验发现中断可能会影响LCD初始化。
  2. 在main.c中定义一些全局变量
  3. 用DMA方式发送一个“hello”,表示串口正常。
  4. 开启DMA循环接收。
  5. 写RTC中断服务函数(见附录)
  6. 写指令处理函数,为了方便管理,所有的私有函数都预定义在main.h中
  7. 写RX对应的通道的中断服务函数
    1. 复制数据缓冲区并返回给上位机。
    2. 指令解析处理,改变时间值。
    3. 在LCD上显示

在MDK中编写代码:

 在main.h中 对应代码段进行引入、函数预定义、引用外部变量。

/* USER CODE BEGIN Includes */
#include "lcd.h"
#include <stdio.h>
/* USER CODE END Includes */
/* USER CODE BEGIN EFP */
void updataRTCTime(void);
/* USER CODE END EFP */
/* USER CODE BEGIN Private defines */
extern uint16_t cmdLen;
extern uint8_t proBuffer[10];
extern uint8_t rxBuffer[10];
extern uint8_t isUploadTime;
/* USER CODE END Private defines */

main.c 的 /* USER CODE BEGIN WHILE */ 代码段,编写以下代码

  /* USER CODE BEGIN WHILE */
	uint8_t hello[]="Hello,DMA transmit\n";
	HAL_UART_Transmit_DMA(&huart1,hello,sizeof(hello));
	HAL_UART_Receive_DMA(&huart1,rxBuffer,cmdLen);
  while (1)
  {
    /* USER CODE END WHILE */

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

stm32g4xx_it.c 中找到RTC的中断服务函数:

在如下代码段编写程序:

 代码如下,这里只显示时间,所以注释掉日期显示:

 RTC_TimeTypeDef sTime;
	RTC_DateTypeDef sData;
	
	if(HAL_RTC_GetTime(&hrtc,&sTime,RTC_FORMAT_BIN) == HAL_OK)
	{
		HAL_RTC_GetDate(&hrtc,&sData,RTC_FORMAT_BIN);
		char str[20];
		//sprintf(str,"Data:20%2d-%2d-%2d",sData.Year,sData.Month,sData.Date);
		//LCD_DisplayStringLine(Line3,str);
		sprintf(str,"Time:%2d:%2d:%2d",sTime.Hours,sTime.Minutes,sTime.Seconds);
		LCD_DisplayStringLine(Line5,str);
	}

找到RX对应的通道的中断服务函数,我设置的是通道1:

  /* USER CODE BEGIN DMA1_Channel1_IRQn 1 */
	for(uint16_t i=0;i<cmdLen ;i++)
			proBuffer[i]=rxBuffer [i];
	HAL_UART_Transmit_DMA(&huart1 ,rxBuffer ,cmdLen +1);
	HAL_Delay(10);
	updataRTCTime();
	LCD_DisplayStringLine(Line7,rxBuffer);
  /* USER CODE END DMA1_Channel1_IRQn 1 */

在 stm32g4xx_it.c 最后面编写自定义函数

/* USER CODE BEGIN 1 */
void updataRTCTime(void)
{
	if(proBuffer[0] != '#')
		return;
	uint8_t timeSection=proBuffer[1];
	uint8_t tmp10=proBuffer[2];
	uint8_t tmp1=proBuffer[3];
	uint8_t val=10*tmp10+tmp1;
	if(timeSection == 'U')
	{
		isUploadTime=val;
		return ;
	}
	RTC_TimeTypeDef sTime;
	RTC_DateTypeDef sDate;
	if(HAL_RTC_GetTime(&hrtc ,&sTime ,RTC_FORMAT_BIN)==HAL_OK )
	{
		HAL_RTC_GetDate(&hrtc ,&sDate ,RTC_FORMAT_BIN );
		if(timeSection == 'H')
			sTime.Hours = val;
		else if (timeSection == 'M')
			sTime.Minutes = val;
		else if (timeSection == 'S')
			sTime.Seconds = val;
		HAL_RTC_SetTime(&hrtc ,&sTime ,RTC_FORMAT_BIN );
	}
}
/* USER CODE END 1 */

四、运行测试

编译、下载(见附录)。

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

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

相关文章

【媒体宣传】企业活动发布会邀请媒体报道的好处与优势?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 企业活动发布会邀请媒体报道具有多种好处与优势&#xff0c;这些都有助于提升企业的知名度、形象和影响力。以下是一些主要的好处与优势&#xff1a; 提升品牌知名度&#xff1a;媒体报…

金融知识分享系列之:支撑阻力

金融知识分享系列之&#xff1a;支撑阻力 一、支撑阻力原理二、支撑阻力作用1.识别市场资金的预期2.作为入场和平仓的重要参考 三、寻找支撑阻力四、延伸思考五、支撑阻力总结 一、支撑阻力原理 支撑阻力核心要素&#xff1a; 锚定效应订单驱动 支撑阻力原理&#xff1a; 市…

Java代码基础算法练习-求给定3个数, 进行从小到大排序-2024.03.20

任务描述&#xff1a; 输入三个整数 x,y,z(0<x<1000&#xff0c;0<y<1000&#xff0c;0<z<1000)&#xff0c;请把这三个数由小到大输出。 任务要求&#xff1a; 代码示例&#xff1a; package march0317_0331;import java.util.Scanner;public class m24…

JVM第八讲:GC - Java 垃圾回收基础知识

GC - Java 垃圾回收基础知识 本文是JVM第八讲&#xff0c; Java 垃圾回收基础知识。垃圾收集主要是针对堆和方法区进行&#xff1b;程序计数器、虚拟机栈和本地方法栈这三个区域属于线程私有的&#xff0c;只存在于线程的生命周期内&#xff0c;线程结束之后也会消失&#xff0…

外包干了14天,技术退步明显。。。

先说一下自己的情况&#xff0c;本科生&#xff0c;2019年我通过校招踏入了成都一家软件公司&#xff0c;开始了我的职业生涯。那时的我&#xff0c;满怀热血和憧憬&#xff0c;期待着在这个行业中闯出一片天地。然而&#xff0c;随着时间的推移&#xff0c;我发现自己逐渐陷入…

HarmonyOS 应用开发案例

本帖下方集中了HarmonyOS Next应用开发时&#xff0c;会遇到的常见应用案例。后续会持续更新大量案例&#xff0c;帮助开发者快速学习。欢迎感兴趣的同学加入Q&#xff1a;454901491 72.手写绘制及保存图片案例&#xff08;0319更新&#xff09;&#xff08;点此查看源码实现&…

【spring】@ConditionalOnResource注解学习

ConditionalOnResource 介绍 ConditionalOnResource 是Spring框架中的一个条件化注解&#xff0c;它允许你根据类路径中是否存在指定的资源来决定是否加载特定的Bean定义或配置类。这个注解可以用于类级别或方法级别。 具体Conditional使用请看这篇文章【spring】Conditional…

在线培训考试系统的作用分析

随着互联网技术的迅猛发展&#xff0c;在线培训考试系统在提高教育培训效果方面发挥着重要的作用。该系统充分利用了信息技术的优势&#xff0c;为教育培训提供了新的方式和工具&#xff0c;促进学习者的主动参与和持续学习&#xff0c;提升培训效果。 自主学习机会 在线培训考…

前端项目,个人笔记(六)【无限滚动 + 拦截器】

目录 1、无限滚动 2、使用pinia进行用户数据持久化 3、完善个人笔记三中的拦截器 请求拦截器&#xff1a; 响应拦截器&#xff1a; 1、无限滚动 使用elementplus中提供的&#xff1a; 代码&#xff1a; <div class"body" v-infinite-scroll"load"…

8.测试教程-自动化测试selenium-3

文章目录 1.unittest框架解析2.批量执行脚本2.1构建测试套件2.2用例的执行顺序2.3忽略用例执行 3.unittest断言4.HTML报告生成5.异常捕捉与错误截图6.数据驱动 大家好&#xff0c;我是晓星航。今天为大家带来的是 自动化测试selenium第三节 相关的讲解&#xff01;&#x1f600…

[C/C++] -- 链表

C/C 中链表是一种常见的数据结构&#xff0c;用于存储和组织数据。链表由节点&#xff08;Node&#xff09;组成&#xff0c;每个节点包含数据和指向下一个节点的指针。链表相对于数组的优势在于可以动态地分配内存&#xff0c;插入和删除操作效率高&#xff0c;但访问元素的随…

Word 操作

个性化设置 打开Microsoft Office后&#xff0c;可以在账户中设置Office的主题和背景。 如图所示&#xff0c;即可完成。 导航 如图所示&#xff0c;在Microsoft Office打开的docx文档中&#xff0c;鼠标点击左下角红框所示的地方&#xff0c;就会出现导航栏目。 护眼颜色 …

中央空调的计费方式

中央空调如何计费 电费计量型中央空调计费方法 计费原理:电费计量型就是通过计量空调末端的用电量&#xff0c;再根据用电量换算为冷量&#xff0c;统计中央空调系统中各用户的总冷量&#xff0c;再根据各用户的冷量比例来分摊费用。 优点: 电量参数容易计量&#xff0c;管理…

蓝桥杯-数的潜能-求快速幂

题目 思路 --将数字拆分成加和的形式&#xff0c;并且相乘。数据范围到10的18次方&#xff0c;暴力肯定不行&#xff0c;要找规律。拆分成1肯定不行&#xff0c;对乘法没有贡献&#xff0c;2可以&#xff0c;3也可以&#xff0c;4、5、6等大于3的数字都可以用2和3来表示。所以…

【博士每天一篇文献-综述】Brain network communication_ concepts, models and applications

阅读时间&#xff1a;2023-12-1 1 介绍 年份&#xff1a;2023 作者&#xff1a;Caio Seguin&#xff0c;Olaf Sporns印第安纳大学心理与脑科学系 期刊&#xff1a; nature reviews neuroscience 引用量&#xff1a;33 中文翻译参考&#xff1a;https://swarma.org/?p44524 …

【算法】差分算法(空调)

可用于求一个数组要变为另一个数组最少要改变多少次的次数 Farmer John 的 N 头奶牛对他们牛棚的室温非常挑剔。 有些奶牛喜欢温度低一些&#xff0c;而有些奶牛则喜欢温度高一些。 Farmer John 的牛棚包含一排 N 个牛栏&#xff0c;编号为 1…N&#xff0c;每个牛栏里有一头…

Emacs之极速复制文件名、绝对路径等快捷键(一百三十三)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

使用appuploder流程

使用appuploder流程笔记 1.如何没有账号去apple官网注册一个&#xff0c;地址&#xff1a;https://developer.apple.com/account 2.下载解压appuploder&#xff0c;双击打开&#xff0c;用刚刚注册的账号登录&#xff0c;下载地址&#xff1a;http://www.applicationloader.n…

鸿蒙Harmony应用开发—ArkTS-显式动画

提供全局animateTo显式动画接口来指定由于闭包代码导致的状态变化插入过渡动效。同属性动画&#xff0c;布局类改变宽高的动画&#xff0c;内容都是直接到终点状态&#xff0c;例如文字、canvas的内容、linearGradient等&#xff0c;如果要内容跟随宽高变化&#xff0c;可以使用…

数据库运行状况和性能监控工具

数据库监控是跟踪组织中数据库的可用性、安全性和性能的过程&#xff0c;它涉及通过跟踪各种关键指标来分析数据库的性能&#xff0c;确保数据库的正常运行并具有深入的可见性&#xff0c;并在出现潜在问题时触发即时警报&#xff0c;以采取主动措施来确保数据库的高可用性。 …