单片机IO口模拟串口实现原理

参考链接

1、使用GPIO来模拟UART
2、STM32之IO模拟串口篇

1、工作原理

单片机IO口模拟串口的实现原理通常是通过软件来模拟串行通信的传输和接收。下面说明了单片机IO口模拟串口的实现原理:

  1. 配置IO口:选择两个IO口作为模拟串口的发送和接收引脚。通常使用的是GPIO引脚。

  2. 设置通信参数:设置波特率、数据位、停止位和校验位等串口通信参数。

  3. 发送数据:通过控制发送引脚的电平变化来模拟串口数据的传输。根据通信参数,将要发送的数据进行位的切换操作,逐位通过发送引脚发送出去。

  4. 接收数据:通过读取接收引脚的电平变化来模拟串口数据的接收。根据通信参数,读取接收引脚的电平状态,逐位组装接收到的数据。

  5. 确保同步:为了确保发送和接收的同步性,可以在发送和接收的开头和结尾添加起始位和停止位。发送时在数据的起始位置输出一个低电平的起始位,接收时检测到低电平的起始位后开始接收数据,接收完毕后检测到高电平的停止位表示接收完成。

单片机IO口模拟串口的实现原理相对简单,但通信速率可能受到单片机性能和IO口速度的限制,因此在高速通信或实时性要求较高的场景下,可能需要选择硬件串口或其他更高级的通信方式。

2、UART协议:

空闲位:当uart处于空闲状态(线路没有数据传输)时,TX、RX线都处于高电平状态(逻辑“1”),一般需要把相应IO口配置为上拉。

起始位:由高电平跳变为低电平,且持续一个位宽度,表示触发起始信号。

数据位:数据位可以5、6、7或8位,从最低位开始一位接着一位的传送。

校验位:有奇、偶或无校验。

	 奇校验:数据位+校验位的“1”的位数总和为奇数;偶校验:数据位+校验位的“1”的位数总和为偶数;

例如:奇校验中,数据位“1”的位数为偶数个,则此时校验位为“1”。

无校验:顾名思义就是没有校验位,数据位后面接停止位。(通常配置为无校验。)

停止位:将数据线拉为高电平,可以设置停止位宽度为1位、1.5位或者2位。

波特率:在串口中波特率为每秒传送的bit数;通信双方必须设置相同的波特率,否则接收的数据为乱码。波特率9600时,传输1bit所需时间为(1/9600)us,大约为104us。

3、代码实现(无OS)

/***/#include "./BSP/MYPRINTF/myprintf.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include "./BSP/TIMER/btim.h"//开始接收数据标志
volatile unsigned char uartStartFlag = 0;//串口接收缓存
unsigned char uartBuf[256] = {0};
unsigned char uartBufLen = 0;
unsigned char uartHaveDat = 0;//超时错误处理
volatile unsigned int uartBufTimeout = 0;
volatile unsigned int uartBufStartTimeout = 0;void myuart_init(void)
{GPIO_InitTypeDef gpio_init_struct;TX_GPIO_CLK_ENABLE();gpio_init_struct.Pin = TX_GPIO_PIN;                   gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;            /* 推挽输出 */gpio_init_struct.Pull = GPIO_PULLUP;                    /* 上拉 */gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;         HAL_GPIO_Init(TX_GPIO_PORT, &gpio_init_struct);       RX_GPIO_CLK_ENABLE(); gpio_init_struct.Pin = RX_GPIO_PIN;   gpio_init_struct.Pull = GPIO_PULLUP;                    /* 上拉 */   gpio_init_struct.Mode = GPIO_MODE_IT_FALLING;                  HAL_GPIO_Init(RX_GPIO_PORT, &gpio_init_struct);                        HAL_NVIC_EnableIRQ(RX_INT_IRQn);Set_TX(0);                                               
}void send_byte(uint8_t data){Set_TX(0);delay_us(104);for(int i = 0; i < 8; i++){if(data & 0x01){Set_TX(1);}else{Set_TX(0);}delay_us(104);data = data >> 1;}Set_TX(1);delay_us(104);}void send_str(char *dat){for(int i = 0; i < strlen(dat); i++){send_byte(dat[i]);}
}void myprintf(char *fmt, ...){va_list ap;char string[512];va_start(ap, fmt);vsprintf(string, fmt, ap);send_str(string);va_end(ap);
}void RX_INT_IRQHandler(void){HAL_GPIO_EXTI_IRQHandler(RX_GPIO_PIN);         /* 调用中断处理公用函数 清除KEY0所在中断线 的中断标志位 */__HAL_GPIO_EXTI_CLEAR_IT(RX_GPIO_PIN);         /* HAL库默认先清中断再处理回调,退出时再清一次中断,避免按键抖动误触发 */
}void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){if(GPIO_Pin == RX_GPIO_PIN){if(uartStartFlag == 0){uartStartFlag = 1;btim_timx_int_init(52 - 1, 72 - 1, BTIM_TIM6_INT);    //52us接收数据}}    
}

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

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

相关文章

go语言:数据库sql查询保存任意数量字段的数据

1、查询任意列数的表&#xff0c;并输出 func search() {rows, _ : db.Query("select * from users") // 查询数据columns, _ : rows.Columns() // 查询到的字段名列表values : make([]any, len(columns)) // 根据字段数量&#xff0c;创建接收…

优雅的参数校验——Guava库中的Preconditions

Guava库中的Preconditions类提供了一些静态方法&#xff0c;用于在程序中执行参数的检查和验证。这些方法在编写健壮和可维护的代码时非常有用 checkArgument(boolean expression)&#xff1a; 作用&#xff1a;用于验证方法的参数是否满足某个条件。如果条件不满足&#xff0c…

rancher快照备份至S3

巧用rancher的S3快照备份功能&#xff0c;快速实现集群复制、集群转移、完全崩溃后的极限修复 1.进入集群管理&#xff0c;在对应的集群菜单后&#xff0c;点击编辑配置 2.选择ETCD&#xff0c;启用&#xff0c;Backup Snapshots to S3选项 并填入你的minio 3 配置成功后 手…

使用adb shell getprop命令获取Android设备的属性

常用属性获取&#xff1a; adb shell getprop ro.build.version.emui —查询EMUI版本 adb shell getprop ro.product.brand —查询手机品牌 adb shell getprop ro.product.name --查询设备名称 adb shell getprop ro.serialno —查询设备序列号 获取手机系统信息( CPU,厂商…

C# 信号量的使用

学习来源&#xff1a;《.net core 底层入门》 第六章第9节&#xff1a;信号量 案例&#xff1a;主线程负责添加数据&#xff0c;子线程负责获取数据 使用SemaphoreSlim&#xff08;轻信号量&#xff09;实现&#xff1a; using System; using System.Collections.Generic; us…

python中的<class ‘complex‘>

一般编程里面不怎么会讲&#xff0c;但是还是挺强大的一个类。 在 Python 中&#xff0c;<class complex> 表示复数类型。复数是一种包含实部和虚部的数学数&#xff0c;可以用 a bj 的形式表示&#xff0c;其中 a 表示实部&#xff0c;b 表示虚部&#xff0c;j 是虚数…

bat脚本暂停写法

使用 timeout 命令来实现暂停&#xff1a; timeout /t 1 /nobreak >nul/t &#xff1a;指定暂停的时间&#xff0c;单位为秒。/nobreak&#xff1a;防止用户按任意键终止暂停。

13 物理层介质及设备

物理层介质及设备 一、线缆的连接 &#xff08;一&#xff09;线序 ​ 线序&#xff1a; RJ-45连接头12345678568A绿白绿橙白蓝蓝白橙棕白棕568B橙白橙绿白蓝蓝白绿棕白棕 ​ 1、2发送&#xff0c;3、6接收 &#xff08;二&#xff09;线缆的应用 1.线缆的连接 ​ 标准…

Spring自定义标签体系和应用

我们知道&#xff0c;在使用Dubbo框架时&#xff0c;需要指定配置文件中的application、protocol、registry、provider、service等服务器端和客户端的配置项&#xff0c;典型的配置方法如下所示。通过这些配置项&#xff0c;我们可以基于Spring容器来启动Dubbo服务。 <!-- …

【2024.6.23】今日科技时事:科技前沿大事件

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

常用原语介绍

1.在Xilinx的example&#xff08;wavegen example&#xff09;中看到他们的顶层模块的输入输出管脚都手动例化原语IBUF以及OBUF——工具也会自动给我们加上不必要自己加 2.非mrcc个srcc的管脚输入的时钟信号&#xff0c;无法进入mmcm————试验过会报错 3.实际上&#xff0…

探索PHP中的函数

在PHP编程中&#xff0c;函数是一个非常重要的概念。函数可以帮助我们将代码组织成可重复使用的块&#xff0c;从而提高代码的可读性和可维护性。本文将介绍PHP中的函数&#xff0c;包括函数的定义、参数传递、返回值、内置函数和自定义函数等内容&#xff0c;帮助读者更好地理…

WPF 深入理解八、Binding 绑定

Binding 创建一个Demo 1 1.创建三个输入框&#xff0c;按钮 2.为按钮创建点击方法 3.点击按钮 三个输入框&#xff0c;分别更新了自己的内容。 上面的展示&#xff0c;是一个传统的模式&#xff0c;事件驱动程序&#xff0c;通过事件来变更UI控件元素的内容。 示例二 创建…

OS_虚拟机

2024.06.21&#xff1a;操作系统虚拟机学习笔记 第4节 虚拟机 4.1 虚拟机基本概念4.2 一型虚拟机管理程序4.3 二型虚拟机管理程序4.4 用户态与内核态 本节的主要内容就是来分辨两种不同的虚拟机管理程序 4.1 虚拟机基本概念 利用虚拟化技术&#xff0c;把一台物理机器虚拟成多…

2024年在WordPress中创建销售活动的入门级优惠券方法

2024年在WordPress中创建销售活动的入门级优惠券方法 今天我想和大家分享一些关于如何在WordPress网站上创建销售活动的经验。无论你是电商新手还是已经有一定经验的店主&#xff0c;优惠券都是吸引顾客、增加销量的有力工具。在这篇文章中&#xff0c;我将介绍三款适合初学者…

链轮简单认识一下

今天咱们聊的话题是——链轮&#xff0c;这个应用非常广泛的机械零件。 什么是链轮&#xff1f; 链轮是一种带有齿或尖刺的机械轮&#xff0c;用于与链条或皮带啮合&#xff0c;以促使“轮子”的旋转和运动。这种啮合可确保同步运动&#xff0c;使链轮和皮带能够高效地协同运行…

数据赋能(129)——体系:数据标准化——实施过程、应用特点

实施过程 数据标准化的实施过程通常涉及以下几个关键步骤&#xff1a; 需求分析与计划制定&#xff1a; 在进行数据标准化之前&#xff0c;首先要明确标准化的目标和需求。制定详细的实施计划&#xff0c;包括时间表、资源分配和预期成果。数据收集&#xff1a; 收集需要进行…

Linux-磁盘管理与文件系统

目录 一、磁盘结构 1、磁盘的物理结构 2、磁盘的数据结构 3、磁盘存储容量 4、接口类型 二、磁盘分区 1、磁盘的两种分区方式 1.1、MBR分区 1.2、GPT分区 三、查看硬盘的分区情况 1、Fdisk—查询磁盘设备 2、lsblk—以树形查看磁盘分区 3、blkid—查看磁盘的UUID …

客服系统接入coze扣子机器人 实现了知识库问答,以及文生图功能

我发布的抖音视频 https://www.douyin.com/video/7383347226967362826 【视频标题&#xff1a;】 客服系统接入coze扣子机器人 实现了知识库问答&#xff0c;以及文生图功能 #coze 【视频行业分类&#xff1a;】 3C数码 【视频文案】&#xff1a; 我们现在看一下客服系统对接了…

Elasticsearch的快照

ES的快照是什么&#xff1f; snapshot是一个ES集群或者某个指定索引的备份&#xff0c;快照一般用在 不停机的状态下对ES集群进行备份当硬件故障时恢复集群数据用于跨集群的数据迁移对冷数据或冻结数据做快照以降低存储成本&#xff0c;依赖于可搜索的快照。-收费功能 一个快…