极海APM32F107V6 gpio模拟串口

一、原理部分

之前用外设都是直接用的硬件自带的库,虽然以前有学过原理和时序,但是因为工作其实也很少会有需要gpio模拟串口的情况,但总会有串口用完,但是需要一个类似打印串口的情况。今天也是开整,然后用硬件的库对比一下。

1、协议要点

①、异步通讯:

        通信双方没有共享时钟信号。依靠预先约定好的波特率 (Baud Rate) 来同步。

②、数据帧格式 (常见):

        起始位 (Start Bit): 1位,低电平 (逻辑0)。标志着数据帧的开始,用于同步接收方。

        数据位 (Data Bits): 5-9位(通常8位)。从最低有效位 (LSB) 开始发送/接收。

        校验位 (Parity Bit): 可选,1位(奇校验、偶校验或无校验)。用于简单的错误检测。

        停止位 (Stop Bit): 1位、1.5位或2位,高电平 (逻辑1)。标志数据帧的结束,并为下一帧提供缓冲空间。

        空闲状态 (Idle State): 当没有数据传输时,数据线保持高电平。

        波特率: 定义了每秒传输的符号(位)数。例如,9600 bps 表示每秒传输9600位数据。位周期 (Bit Time) 是波特率的倒数:T_bit = 1 / BaudRate。这是软件模拟时最关键的参数。

③、时间计算

例如现在波特率为9600,T_bit = 1 / 9600 ≈ 0.0001041667 秒 = 104.1667 微秒 (μs)

用我们最常见的格式,8为数据位,1位起始位,1位停止位,即10位

计算传输一个字节 (10位) 所需的总时间 (T_frame):
T_frame = 10 位 * T_bit = 10 * 104.1667 μs ≈ 1041.667 μs ≈ 1.042 ms

可以理解为 大约 1 毫秒 发送一个字节。

发送端要求:需要在 104.17 μs 的整数倍时间点精确切换GPIO电平。

接收端要求:需要在起始位下降沿后等待1.5*T_bit ≈156.25us进行第一次采样(定位到数据位中间),之后每隔104.17us 采样一次后续位

波特率115200的话即速度是 9600 波特率的 12 倍,这里就不再写那么长

2、GPIO 模拟发送 (TX) 

①、配置:

将选定的GPIO引脚配置为推挽输出模式,初始状态设置为高电平(空闲状态)。

②、发送一个字节的流程:

a. 起始位:

将GPIO引脚拉低,并保持1个完整的位周期 (T_bit)。这告诉接收方数据开始传输。

b. 数据位 (LSB First):

从要发送字节的最低位 (bit 0) 开始。

根据该位的值是0还是1,将GPIO引脚设置为低电平或高电平。

保持这个电平状态1个完整的位周期 (T_bit)。

接着发送下一位 (bit 1),重复上述电平设置和延时过程。

依此类推,直到发送完指定的数据位数 (通常是8位)。

c. 校验位 (如果启用):

计算已发送数据位的奇偶性 (奇校验或偶校验)。

根据计算结果,将GPIO引脚设置为相应的电平 (0或1)。

保持这个电平状态1个完整的位周期 (T_bit)。

d. 停止位:

将GPIO引脚拉高。

保持高电平状态1个 (或1.5/2个) 完整的位周期 (T_bit)。这标志着一帧数据的结束,并使线路恢复到空闲状态。

需要注意的点为:

精确的时序: 每个位(起始位、数据位、校验位、停止位)的电平持续时间必须严格等于位周期 (T_bit)。这是模拟成功的最核心要求。任何累积的时序误差都会导致通信失败。

位顺序: 严格遵守协议约定的位顺序(通常是LSB first)。

中断的影响这里我就先不考虑了,因为我只是回顾下原理,不是真的要用模拟gpio来实现项目需求

3、GPIO 模拟接收 (RX) 

①、配置:

将选定的GPIO引脚配置为浮空输入或上拉输入模式(确保空闲时为高电平)。

②、检测起始位:

持续轮询(或在中断中检测)GPIO引脚状态。

当检测到引脚从高电平变为低电平(下降沿)时,可能是一个起始位开始。

③、同步与采样:

检测到下降沿后,不能立即采样数据。需要避开信号边沿可能不稳定的区域。

关键延时: 等待 1.5个位周期 (1.5 * T_bit)。这个延时将采样点定位到第一个数据位 (LSB) 的中间位置。这是提高抗噪性和采样稳定性的常用技巧。

④、读取数据位:

在预期的采样点(每个数据位的中间位置),读取GPIO引脚的电平状态。

将读取到的电平值 (0或1) 存入接收字节的对应位(从LSB开始)。

每读取完一位,等待1个位周期 (T_bit) 到达下一位的采样点。

重复这个过程,读取完所有数据位 (如8位)。

⑤、读取校验位 (如果启用):

在下一个采样点(等待1个位周期后),读取GPIO引脚的电平作为校验位。

根据协议(奇/偶校验)和收到的数据位计算期望的校验位,与实际收到的校验位比较,进行错误检查(可选)。

⑥、检测停止位:

在下一个采样点(等待1个位周期后),读取GPIO引脚的电平。期望是高电平 (1)。

如果检测到高电平,说明停止位有效,一帧数据接收基本完成(可考虑校验结果)。

如果检测到低电平,说明发生了帧错误(Frame Error)

需要注意的点为:1.5 * T_bit 和后续的 1 * T_bit 延时必须非常准确。采样点定位在位的中间是最佳实践。

二、配置工程

我的板子是APM32F107VC EVAL_V1.0

因为之前看是pin to pin,我以为是完全兼容,所以用cubemx生成了工程,后来程序一直跑不了,查了一下要用极海官方的sdk才行。

在官方下载sdk和pack即可

之前都是用IAR,现在公司用keil,就用回keil

我用的是他串口中断的例程做base

APM32F107_EVAL_SDK_v1.0\Examples\USART\USART_Interrupt\Project\MDK

如上图复制到自己工程的文件夹

再将路径改一下

然后这里每个都要重新添加一下

编译成功,跑了一下程序OK

三、修改程序

1、定义的结构体和宏

用PD13做TX,PD14做RX

我这里做的波特率9600,没有做太高的

tx rx初始化,其中rx配置为中断

2、初始化

其中rx配置为外部中断

两个定时器,定时器5做帧间隔的计时,定时器6为判断数据是否结束(跟之前stm32接收不定长数据差不多STM32+Cubemx+Esp8266(一)串口接收不定长数据_stm32cubemx esp8266-CSDN博客)

2、发送部分

单个字符

字符串

发送数组

这里我是直接延时硬等,可以再加一个定时器用作发送。

3、接收部分

在接收首个低电平的时候,即为起始帧,然后打开定时器5处理后边的数据

定时器5的中断就是数据处理

这里我是1为起始位,8位数据位,1位停止位,无校验,依次处理就好,用UART_TEST_Handle.rxBitCount作判断当前在第几位。数据保存到UART_TEST_Handle.rxBuffer这个buff,

然后每收到一个字节都打开定时器6,定时器6做了11位的时间,若是定时器6中断溢出则说明这帧数据结束,标志位置1

4、主函数

检测标志位是否置1,置1则发送rx的buffer,相当于回显

实际上我这里虽然做了发送队列,但我接收buff没做,所以也是只能发一条而已。这个是之前打印其他比较多的时候做的队列

四、验证程序:

成功

然后发0x55,用逻辑分析仪看看

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

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

相关文章

【数据可视化-94】2025 亚洲杯总决赛数据可视化分析:澳大利亚队 vs 中国队

🧑 博主简介:曾任某智慧城市类企业算法总监,目前在美国市场的物流公司从事高级算法工程师一职,深耕人工智能领域,精通python数据挖掘、可视化、机器学习等,发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…

链表基本运算详解:查找、插入、删除及特殊链表

在上一篇文章中,我们介绍了线性表的基本概念和顺序存储。本文将深入探讨单链表的基本运算,并介绍循环链表和双向链表这两种特殊的链表结构,帮助读者全面掌握链表的操作技巧。 文章目录1.单链表基本运算链表的查找操作按序号查找按值查找链表的…

8.19作业

1.聊天室1.1服务器#include <myhead.h> #define SER_PORT 8888 #define SER_IP "192.168.174.128"struct msg {char type;char usrname[20];char msgtext[1024]; };int main(int argc, const char *argv[]) {int sfd socket(AF_INET,SOCK_STREAM,0);if (sfd-1…

95、23种设计模式之建造者模式(4/23)

建造者模式&#xff08;Builder Pattern&#xff09;是23种经典设计模式中的创建型模式之一&#xff0c;其核心思想是将复杂对象的构建过程与其表示分离&#xff0c;使得同样的构建流程可以生成不同结构或配置的对象。以下从定义、结构、应用场景、优缺点及代码示例展开分析&am…

LIA-X - 一张照片生成任意表情肖像动画视频 精准操控面部动作 支持50系显卡 一键整合包下载

LIA-X 是一个可解释的潜在肖像动画生成器&#xff0c;只需要一张照片加一段驱动视频生成任意表情肖像动画&#xff0c; 旨在将驱动视频中的面部动态精细地转移到源肖像上&#xff0c;同时提供对头部、嘴巴和眼睛的精细控制。同时支持图像和视频的编辑任务&#xff0c;比如对头部…

Google 的 Opal:重新定义自动化的 AI 平台

1. 真实世界测试&#xff1a;结果出乎意料 我让 Opal 接受了三项极具挑战性的任务&#xff1a; 1.1. 博客生成器挑战 我的提示&#xff1a;“研究并撰写一篇关于 2 亿美元融资对无代码&#xff08;no-code&#xff09;影响的文章。” 发生了什么&#xff1a;Opal 不仅仅是写…

【FreeRTOS】任务通知

任务通知通知状态的三种取值taskNOT_WAITING_NOTIFICATION&#xff1a;任务没有在等待通知taskWAITING_NOTIFICATION&#xff1a;任务在等待通知taskNOTIFICATION_RECEIVED&#xff1a;任务接收到了通知&#xff0c;也被称为 pending(有数据了&#xff0c;待处理)如下面两个场景…

BEV:隐式相机视角转换-----BEVFormer

一、背景 基于imp投影的相机视角转换&#xff0c;对相机的内外参依赖较高&#xff0c;BEV 网格融合固定&#xff0c;可能对小目标不够敏感&#xff1b;考虑通过transformer的方式进行相机的视角转换&#xff0c;BEV query 可以自适应关注关键区域&#xff0c;提高小目标检测&am…

zsh 使用笔记 命令行智能提示 bash智能

目录 安装&#xff1a; 升级&#xff1a; zsh 有什么用&#xff1f; zsh 安装&#xff1a; sudo apt update sudo apt install zsh -y 升级&#xff1a; omz update zsh 有什么用&#xff1f; 相比 bash&#xff0c;zsh 更智能、更方便&#xff0c;常见优势有&#xff…

Laya的适配模式选择

文章目录SCALE_FIXED_AUTOSCALE_SHOWALLSCALE_FULLSCALE_FIXED_HEIGHTSCALE_FIXED_WIDTHSCALE_NOSCALESCALE_EXACTFITSCALE_NOBORDERdemoSCALE_FIXED_AUTO NO.1会透&#xff0c;拉伸能解决官网解释&#xff1a;应用保持设计比例不变&#xff0c;全屏显示全部内容(类似showall&…

Android中flavor的使用

在我的开发中&#xff0c;有这样的需求&#xff0c;有一个项目&#xff0c;需要适配不同的执法仪设备&#xff0c;这些执法仪都是Android系统的&#xff0c;而且有的有系统签名&#xff0c;有的没有&#xff0c;比如我共有四款型号&#xff0c;有三款有系统签名&#xff0c;每款…

如何使用DeepSeek解析长pdf的文本

直接使用python工具解析pdf文件&#xff0c;可能因为格式兼容问题&#xff0c;导致解析出的文本几乎不可读。 这里尝试使用Deepseek解析pdf文件&#xff0c;这里仅考虑文本&#xff0c;不考虑其他要素。 1 解析第一步 将pdf作为附件上传到deepseekchat界面&#xff0c;输入如…

W3C CSS 活动

W3C CSS 活动 引言 CSS(层叠样式表)是现代网页设计中不可或缺的技术之一。W3C(万维网联盟)作为全球互联网标准制定的主要组织,定期举办各类CSS相关的活动,旨在促进CSS技术的发展与普及。本文将详细介绍W3C CSS活动,包括活动内容、参与方式以及活动意义。 活动内容 1…

React Native 与 UniApp 对比

React Native 优点: 由 Facebook 开发维护&#xff0c;社区生态强大 使用 JavaScript/TypeScript 开发&#xff0c;学习曲线相对平缓 真正的原生渲染&#xff0c;性能接近原生应用 支持热重载&#xff0c;开发效率高 可访问所有原生平台 API 大型应用案例丰富(如 Faceboo…

Dijkstra和多层图 0

众所周知&#xff0c;Dijkstra经常拿来解决不带负权和环的单元最短路。我们先来看一下他的实现过程 (由于朴素版用的不多&#xff0c;我们直接上堆优化) 模板 #include<bits/stdc.h> #define mf(x,y) make_pair(x,y)//x距离&#xff0c;y节点 using namespace std; …

【驱动】RK3576:桌面操作系统基本概念

1、桌面操作系统 我们常说的Ubuntu、Debian、麒麟、统信等都是总包工头; 他们把linux内核、根文件系统(遵循 Linux 标准文件系统层次结构FHS)、包管理(软件、库)、桌面环境(GNOME、Xfce等)、初始化系统(Systemd)、各种服务与守护进程、安全组件等整合成一个完整的桌面…

sfc_os!SfcQueueValidationRequest函数分析之sfc_os!IsFileInQueue

第一部分&#xff1a;1: kd> kc# 00 sfc_os!SfcQueueValidationRequest 01 sfc_os!SfcWatchProtectedDirectoriesWorkerThread 02 kernel32!BaseThreadStart1: kd> dvRegVal 0x01129164ChangeType 5vrd 0x012bfef0Status 0n1988337684vrdexisting 0x012bffdc//// if…

100202Title和Input组件_编辑器-react-仿低代码平台项目

文章目录1 开发两个问卷组件1.1 Title组件1.2 Input组件1.3 画布静态展示TItle和Input2 Ajax获取问卷数据&#xff0c;并存储到Redux store2.1 API接口2.2 组件列表存储到Redux store统一管理2.3 重构useLoadQuestionData3 在画布显示问卷列表&#xff0c;点击可选中3.1 Redux获…

设置计划任务自动备份mysql

windows系统下1.创建mysql自动备份脚本mysqlback.bat需将此脚本存放在mysql的bin文件夹下。确保此脚本执行成功了在进行第2步做计划任务。echo off REM 定义备份目录backup_dir、备份的文件名filename set "backup_dirD:\mysqlback" set "filenamemysqlback_%da…

飞机起落架轮轴深孔中间段电解扩孔内轮廓检测 - 激光频率梳 3D 轮廓检测

摘要&#xff1a;飞机起落架轮轴深孔中间段电解扩孔内轮廓检测存在精度要求高、结构复杂等挑战。本文针对电解扩孔特殊工艺特征&#xff0c;探讨激光频率梳 3D 轮廓检测技术的应用&#xff0c;分析其检测原理、技术优势及在轮轴深孔检测中的实践&#xff0c;为电解扩孔内轮廓高…