嵌入式MCU面试笔记2
目录
串口通信
概论
原理
配置
HAL库代码
1. 初始化函数
2. 数据发送和接收函数
3. 中断和DMA函数
4. 中断服务函数
串口通信
概论
我们知道,通信桥接了两个设备之间的交流。一个经典的例子就是使用串口通信交换上位机和单片机之间的数据。
比较常见的串口通信协议是下面这两个:
UART(通用异步收发传输器,Universal Asynchronous Receiver/Transmitter):这里可以看到,这样的协议只有Asynchronous,提示你这个协议是异步的。异步通信,需要在传递数据的同时,添加起始位、停止位、校验位等进行帧同步放置进行数据裁剪和区分。
USART(通用同步异步收发传输器)则更进一步,支持了同步的通信方式在同步模式下,USART通过时钟信号与从设备同步数据传输,在异步模式下工作与UART相似。
原理
本质上,就是数据通过数据线移动,从一个设备传递到另一个设备。在串口通信中,这是通过移位寄存器移位实现的。移出去的位被派发到传输线上传递出去,给下一个移进来的比特腾出来位置。对于接受的设备,那就是接受到来的比特,给下一个到来的比特腾出位置。

仔细看,这里的移位寄存器示意图就是在移动将它发送到TX端上从数据线上流出去,另一端如果有来者,则从RX端进入接收移位寄存器进来。
配置
上面的笼统概述没有统一问题:咋个长度?咋个校验?收发速度如何?不讨论这些问题,双方无法保证数据的接受和发送是一一呼应的,极易导致数据接受和发送异常。所以就有了协议,协议约定了两者的动作。
-
波特率,串口通信的速率,一般需要配置波特率寄存器实现。其计算公式是:
-
空闲,一般为高电平
-
起始位,标志一个数据帧的开始,固定为低电平。当数据开始发送时,产生一个下降沿。(空闲–>起始位)
-
数据位,发送数据帧,1为高电平,0为低电平。低位先行。 比如 发送数据帧0x0F 在数据帧里就是低位线性 即 1111 0000
-
校验位,用于数据验证,根据数据位的计算得来。有奇校验,偶校验和无校验。
奇校验(Odd Parity):确保数据帧中1的数量为奇数。 偶校验(Even Parity):确保数据帧中1的数量为偶数。
-
停止位,用于数据的间隔,固定为高电平。数据帧发送完成后,产生一个上升沿。(数据传输–>停止位)
HAL库代码
1. 初始化函数
-
HAL_UART_Init()
这个函数一般如果使用CubeMx配置的话就会给你写好了,它用于初始化UART外设,包括波特率、数据位、停止位、奇偶校验和硬件流控制。通常在程序开始时调用此函数,以配置UART通信的基本参数。
HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart);
参数说明:
-
huart:指向UART句柄的指针,句柄包含了UART的所有配置参数,如波特率、数据位、停止位等。
返回值:
-
HAL_OK:初始化成功。 -
HAL_ERROR:初始化失败。
使用示例:
UART_HandleTypeDef huart1; 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);
-
2. 数据发送和接收函数
-
HAL_UART_Transmit()
用于通过UART发送数据。此函数可以在阻塞模式、非阻塞模式或中断模式下工作。
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
参数说明:
-
huart:指向UART句柄的指针。 -
pData:指向要发送的数据的指针。 -
Size:要发送的数据字节数。 -
Timeout:超时时间,单位为毫秒。
返回值:
-
HAL_OK:数据发送成功。 -
HAL_ERROR:发送失败。
使用示例:
uint8_t msg[] = "Hello UART!"; HAL_UART_Transmit(&huart1, msg, sizeof(msg)-1, 1000);
-
-
HAL_UART_Receive()
用于从UART接收数据。该函数也可以在阻塞模式、非阻塞模式或中断模式下工作。
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
参数说明:
-
huart:指向UART句柄的指针。 -
pData:指向接收数据的缓冲区。 -
Size:要接收的数据字节数。 -
Timeout:超时时间,单位为毫秒。
返回值:
-
HAL_OK:数据接收成功。 -
HAL_ERROR:接收失败。
使用示例:
uint8_t receivedData[10]; HAL_UART_Receive(&huart1, receivedData, 10, 1000);
-
3. 中断和DMA函数
-
HAL_UART_Transmit_IT()
这种方式就是异步的,执行完这个函数只是委托函数开始转发,程序流继续执行。用于通过中断方式发送数据。当数据发送完成时,会触发中断。
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
参数说明:
-
huart:指向UART句柄的指针。 -
pData:指向要发送的数据的指针。 -
Size:要发送的数据字节数。
返回值:
-
HAL_OK:数据发送任务已启动。 -
HAL_ERROR:启动失败。
使用示例:
uint8_t msg[] = "Hello UART!"; HAL_UART_Transmit_IT(&huart1, msg, sizeof(msg)-1);
-
-
HAL_UART_Receive_IT()
用于通过中断方式接收数据。接收的数据将在中断服务程序(ISR)中处理。
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
参数说明:
-
huart:指向UART句柄的指针。 -
pData:指向接收数据的缓冲区。 -
Size:要接收的数据字节数。
返回值:
-
HAL_OK:接收任务已启动。 -
HAL_ERROR:启动失败。
使用示例:
uint8_t receivedData[10]; HAL_UART_Receive_IT(&huart1, receivedData, 10);
-
-
HAL_UART_Transmit_DMA()
用于通过DMA(直接内存访问)发送数据。DMA可以使数据传输不占用CPU,从而提高数据传输效率。
HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
参数说明:
-
huart:指向UART句柄的指针。 -
pData:指向要发送的数据的指针。 -
Size:要发送的数据字节数。
返回值:
-
HAL_OK:DMA传输已启动。 -
HAL_ERROR:启动失败。
使用示例:
uint8_t msg[] = "Hello UART!"; HAL_UART_Transmit_DMA(&huart1, msg, sizeof(msg)-1);
-
-
HAL_UART_Receive_DMA()
用于通过DMA接收数据。DMA可以有效地将数据从UART缓冲区传输到内存,而无需CPU干预。
HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
参数说明:
-
huart:指向UART句柄的指针。 -
pData:指向接收数据的缓冲区。 -
Size:要接收的数据字节数。
返回值:
-
HAL_OK:DMA接收已启动。 -
HAL_ERROR:启动失败。
使用示例:
uint8_t receivedData[10]; HAL_UART_Receive_DMA(&huart1, receivedData, 10);
-
4. 中断服务函数
在使用中断模式时,需要实现中断回调函数。这些函数由HAL库调用。我们需要做的就是实现这些函数(有趣的是默认的实现是__weak的,意味着用户的定义隶属于强定义,编译器优先采纳用户实现。)
-
HAL_UART_TxCpltCallback()
当数据发送完成时,这个回调函数会被调用。
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart);
-
HAL_UART_RxCpltCallback()
当数据接收完成时,这个回调函数会被调用。
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
相关文章:
嵌入式MCU面试笔记2
目录 串口通信 概论 原理 配置 HAL库代码 1. 初始化函数 2. 数据发送和接收函数 3. 中断和DMA函数 4. 中断服务函数 串口通信 概论 我们知道,通信桥接了两个设备之间的交流。一个经典的例子就是使用串口通信交换上位机和单片机之间的数据。 比较常见的串…...
代码随想录算法【Day34】
Day34 62.不同路径 思路 第一种:深搜 -> 超时 第二种:动态规划 第三种:数论 动态规划代码如下: class Solution { public:int uniquePaths(int m, int n) {vector<vector<int>> dp(m, vector<int>(n,…...
《数字图像处理(面向新工科的电工电子信息基础课程系列教材)》重印P126、P131勘误
勘误:打圈的地方有指数二字。 指数滤波器本身是错误的概念,我在书上打了一个叉,排版人员误删了。 滤波器部分从根本上有问题,本来要改,但是时间不够了。 和廖老师讨论多次后,决定大动。指数滤波器的概念…...
vim多文件操作如何同屏开多个文件
[rootxxx ~]# vimdiff aa.txt bb.txt cc.txt #带颜色比较的纵向排列打开的同屏多文件操作 示例: [rootxxx ~]# vimdiff -o aa.txt bb.txt cc.txt #带颜色比较的横向排列打开的同屏多文件操作 示例: [rootxxx ~]# vim -O aa.txt bb.txt c…...
day6手机摄影社区,可以去苹果摄影社区学习拍摄技巧
逛自己手机的社区:即(手机牌子)摄影社区 拍照时防止抖动可以控制自己的呼吸,不要大喘气 拍一张照片后,如何简单的用手机修图? HDR模式就是让高光部分和阴影部分更协调(拍风紧时可以打开&…...
渗透测试之WAF规则触发绕过规则之规则库绕过方式
目录 Waf触发规则的绕过 特殊字符替换空格 实例 特殊字符拼接绕过waf Mysql 内置得方法 注释包含关键字 实例 Waf触发规则的绕过 特殊字符替换空格 用一些特殊字符代替空格,比如在mysql中%0a是换行,可以代替空格 这个方法也可以部分绕过最新版本的…...
C语言【基础篇】之流程控制——掌握三大结构的奥秘
流程控制 🚀前言🦜顺序结构💯 定义💯执行规则 🌟选择结构💯if语句💯switch语句💯case穿透规则 🤔循环结构💯for循环💯while循环💯do -…...
c++小知识点
抽象类包含至少一个纯虚函数,不能实例化对象。派生类必须实现基类的所有纯虚函数才能成为非抽象类,从而可以实例化对象。可以使用抽象类的指针或引用指向派生类对象,实现多态性调用。抽象类虽然不能直接实例化,但可以拥有构造函数…...
团体程序设计天梯赛-练习集——L1-022 奇偶分家
前言 这几道题都偏简单一点,没有什么计算,10分 L1-022 奇偶分家 给定N个正整数,请统计奇数和偶数各有多少个? 输入格式: 输入第一行给出一个正整N(≤1000);第2行给出N个非负整数…...
vue项目中,如何获取某一部分的宽高
vue项目中,如何获取某一部分的宽高 在Vue项目中,如果你想要获取某个DOM元素的宽度和高度,可以使用原生的JavaScript方法或者结合Vue的特性来实现。以下是几种常见的方法: 使用ref属性 你可以给需要测量宽高的元素添加一个ref属…...
LeetCode - #195 Swift 实现打印文件中的第十行
网罗开发 (小红书、快手、视频号同名) 大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等…...
机试题——最小矩阵宽度
题目描述 给定一个矩阵,包含 N * M 个整数,和一个包含 K 个整数的数组。 现在要求在这个矩阵中找一个宽度最小的子矩阵,要求子矩阵包含数组中所有的整数。 输入描述 第一行输入两个正整数 N,M,表示矩阵大小。 接下…...
香港维尔利健康科技集团重金投资,内地多地体验中心同步启动
香港维尔利健康科技集团近期宣布,将投资数亿港元在内地多个城市建立全新的健康科技体验中心。这一战略举措旨在进一步拓展集团在内地市场的布局,推动创新医疗技术的普及和应用。 多地布局,覆盖主要城市 据悉,维尔利健康科技集团将…...
ZYNQ-IP-AXI-GPIO
AXI GPIO 可以将 PS 端的一个 AXI 4-Lite 接口转化为 GPIO 接口,并且可以被配置为单端口或双端口,每个通道的位宽可以独立配置。 通过使能三态门可以将端口动态地配置为输入或输出。 AXIGPIO 是 ZYNQ PL 端的一个 IP 核,可以将 AXI-Lite Mas…...
Netty的心跳机制怎么实现的?
大家好,我是锋哥。今天分享关于【Netty的心跳机制怎么实现的?】面试题。希望对大家有帮助; Netty的心跳机制怎么实现的? Netty的心跳机制主要是通过在客户端和服务器之间定期发送特殊的数据包(比如空消息或自定义的控…...
java基础——专题一 《面向对象之前需要掌握的知识》
目录 Δ前言 一、拾枝杂谈 1.Java是什么? 2.计组前瞻: 3.JDK,JRE,JVM? 二、环境搭建 1.JDK安装和配置: 1.1 人话 1.2 JDK的配置 1.3 如何切换JDK的版本? 2.DOS的简单使用: 2.1 介…...
Python 数据清洗与处理常用方法全解析
在数据处理与分析过程中,缺失值、重复值、异常值等问题是常见的挑战。本文总结了多种数据清洗与处理方法:缺失值处理包括删除缺失值、固定值填充、前后向填充以及删除缺失率高的列;重复值处理通过删除或标记重复项解决数据冗余问题࿱…...
BFS算法的实现(例题)
这是C算法基础-搜索与图论专栏的第X篇文章,专栏详情请见此处。 引入 上篇博客,我们学习了BFS算法的大体套路,这次,我将会通过两个例题来更详细的讲解。 下面我们就来讲BFS算法(例题)的实现。 过程 例题1&a…...
clean code阅读笔记——如何命名?
命名的原则 1. “小处诚实非小事“ 有个词叫做”以小见大“。以建筑作喻,宏大建筑中最细小的部分,比如关不紧的门、未铺平的地板,甚至时凌乱的桌面,都会将整个大局的魅力毁灭殆尽,这就是整洁代码之所系。 2. 有意义…...
MacOS 如何解决无法打开 ‘xxx’,因为 Apple 无法检查其是否包含恶意软件
背景 在安装软件时,遇到“无法打开 ‘xxx’,因为 Apple 无法检查其是否包含恶意软件” 的提示,许多用户可能会感到困惑,不知道该如何处理。遇到这个问题时,按以下步骤操作即可解决。 首先,这个警告提示的出…...
从‘发快递’到‘收快递’:手把手拆解RocketMQ 5.x中Group、Topic、Queue的实战配置与避坑指南
从‘发快递’到‘收快递’:手把手拆解RocketMQ 5.x中Group、Topic、Queue的实战配置与避坑指南 想象一下你正在搭建一个电商系统,订单创建后需要实时通知库存服务扣减库存、支付服务生成账单、物流服务准备发货。这种异步解耦的场景正是消息队列的用武之…...
[GDOUCTF 2023]<ez_ze> SSTI 绕过数字与大括号过滤的实战技巧
1. SSTI注入基础与ez_ze题目背景 SSTI(Server-Side Template Injection)服务器端模板注入是Web安全中常见的漏洞类型,它允许攻击者通过构造恶意模板表达式在服务器端执行任意代码。在CTF竞赛中,这类题目往往通过过滤关键字符来增加…...
Captain AI帮你一次过审,上品不再被驳回!
Ozon上品审核驳回、上架后违规下架,是90%以上卖家都踩过的坑。很多卖家遇到上品问题,会用DeepSeek等通用AI查询规则,却往往因为信息滞后、规则解读错误,反复修改仍无法过审,白白错过新品流量黄金期。一、Captain AI能帮…...
腾讯 CodeBuddy 全形态解析:IDE、CLI 与插件如何重塑 AI 编程体验
1. CodeBuddy 三形态全景解析:从终端到桌面的AI编程革命 第一次用CodeBuddy的CLI工具时,我在终端里输入"帮我写个Python爬虫抓取天气数据",三秒钟后看着自动生成的完整代码,手里的咖啡差点洒在键盘上。这就是腾讯CodeB…...
提升Python编码效率:ptpython语法高亮与自动补全的终极指南
提升Python编码效率:ptpython语法高亮与自动补全的终极指南 【免费下载链接】ptpython A better Python REPL 项目地址: https://gitcode.com/gh_mirrors/pt/ptpython ptpython是一款功能强大的Python REPL工具,它通过语法高亮、智能自动补全和丰…...
让屏幕标注像在纸上写字一样自然:gInk 三分钟上手指南
让屏幕标注像在纸上写字一样自然:gInk 三分钟上手指南 【免费下载链接】gInk An easy to use on-screen annotation software inspired by Epic Pen. 项目地址: https://gitcode.com/gh_mirrors/gi/gInk 你是否曾经在线上会议中,想快速圈出PPT的重…...
全志Tiger-ISP调试工具安装与使用全攻略
1. 全志Tiger-ISP调试工具入门指南 第一次接触全志Tiger-ISP调试工具时,我也是一头雾水。这个工具主要用于图像信号处理器(ISP)的调试和优化,是开发智能摄像头、行车记录仪等视觉设备的必备利器。简单来说,它能让你像调色师一样精细调整图像的…...
从移动平均到IIR滤波:用Matlab filter函数实现数据降噪的完整指南(附对比实验)
从移动平均到IIR滤波:用Matlab filter函数实现数据降噪的完整指南(附对比实验) 在数据分析与信号处理领域,噪声污染是影响结果准确性的常见挑战。无论是来自传感器的物理干扰,还是数据传输过程中的随机波动,…...
4个维度掌控企业驱动管理:DriverStore Explorer从诊断到优化的全流程方案
4个维度掌控企业驱动管理:DriverStore Explorer从诊断到优化的全流程方案 【免费下载链接】DriverStoreExplorer Driver Store Explorer 项目地址: https://gitcode.com/gh_mirrors/dr/DriverStoreExplorer 一、问题诊断:企业环境中的驱动管理痛点…...
快速验证openclaw抓取能力:用快马一键生成部署原型
最近在做一个内容抓取的小项目,尝试用openclaw框架快速搭建原型。这个开源机器人框架功能强大,但配置起来确实有点麻烦,特别是环境依赖和部署环节。经过一番折腾,我发现用InsCode(快马)平台可以省去很多重复劳动,分享下…...
