一种基于IO口的模拟串口(LOG)实现方法

news2025/8/17 2:26:36

一、使用背景

当MCU的串口不够用时,可以通过IO模拟的方式将任意一个具有输出功能的管脚配置为串口输出,从而方便开发和调试。

二、实现原理

通过IO口模拟串口发送波形,配置对应的波特率等信息,然后映射printf函数,从而实现打印功能。

三、实验环境

硬件平台: CCM4202S

软件平台:MDK

四、软件实现

1.编写串口发送函数

//模拟UART
inline static void Uart_Log_Send(uint16_t ch)
{
    for(int i=0; i<11; i++)
    {
        if(ch & 0x1)
        {
            EPORT3->EPDR |= 0x10;//(Bit_SET<<(4));
        }
        else
        {
            EPORT3->EPDR &= 0xEF;//~(Bit_SET<<(4));
        }
        ch >>= 1;
        Uart_Log_Delay();
    }
}


//重定义fputc函数 (模拟串口)
int fputc(int ch, FILE *f)
{      

    /* 初始化IO */
    static uint8_t init_flag = 1;
    if (init_flag)
    {
        init_flag = 0;
        EPORT_ConfigGpio(EPORT_PIN28, GPIO_OUTPUT);
    }

    /* 组一个UART帧 */
    uint16_t value = ch & 0xFF;
    value |= 0X100; //stop  bit
    value <<= 2;    //start bit: "01"
    value |= 1;     // 第一个字符乱码: 起始时额外添加一个'1', 让指令cache稳定,否则起始位bit延时偶尔略宽  

    /* 数据输出 */
//    Device_EnterCritical();
	Uart_Log_Send(value);
//    Device_ExitCritical();

	return ch;

}

2.调整延时函数,去控制不同波特率

通过计算,我们可以得出不同波特率对应传输一个Bit所需的时间

9600 ------------------104.16666 us

115200 --------------8.68055 uS

921600 -------------------1.085 us

我们通过调整 bound_cnt的数值,从而实现我们想要的波特率

#define bound_9600 		1400 
#define bound_115200   112
#define bound_921600   11
inline static void Uart_Log_Delay(void)
{
	volatile uint16_t bound_cnt = bound_9600;//波特率根据延时在设置 921600波特率
    while(bound_cnt--)
		{
			__nop();
		}
}

五、现象验证

下图是以9600为例,我们可以看出波形和打印均符合我们的预期

六、注意事项

1.此方法波特率是通过硬件延时去实现,为防止数据出错,建议在字节传输函数Uart_Log_Send前后加关中断和开中断

2.延时时间很大程度受限于MCU主频,为保证延时准确,最好通过逻辑分析仪抓波形确认

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

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

相关文章

基于粒子群优化算法的冷热电联供型综合能源系统运行优化(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

redis 支持的数据类型

Redis 数据库支持五种数据类型。 字符串&#xff08;string&#xff09; 哈希&#xff08;hash&#xff09; 列表&#xff08;list&#xff09; 集合&#xff08;set&#xff09; 有序集合&#xff08;sorted set&#xff09; 位图 ( Bitmaps ) 基数统计 ( HyperLogLogs ) 字…

Vue3.2 + Element-Plus 二次封装 el-table(Pro版)

前言 &#x1f4d6; ProTable 组件目前已是 2.0版本&#x1f308;&#xff0c;在 1.0版本 中大家提出的问题与功能优化&#xff0c;目前已经得到优化和解决。 &#x1f600; 欢迎大家在使用过程中发现任何问题或更好的想法&#xff0c;都可以在下方评论区留言&#xff0c;或者我…

【计算机网络】局域网体系结构、以太网Ethernet详解

注&#xff1a;最后有面试挑战&#xff0c;看看自己掌握了吗 文章目录局域网LAN决定局域网的要素网络拓扑传输介质局域网的分类以太网令牌环网FDDI网----Fiber Distributed Data InterfaceATM网---Asynchronous Transfer Mode无线局域网WLAN----Wireless Local Area NetworkMAC…

Red Hat Enterprise Linux (RHEL) 9 更新了哪些新特性?

文章目录1. 前言2. 软件3. 支持的硬件架构4. GNOME更新到40版5. 安全和身份6. 构建容器的通用基础镜像7. 改进了用于管理 RHEL 9 的 Cockpit Web 控制台1. 前言 体验一下最新的rhel 9.0 是什么感觉。它会飞吗&#xff1f; Red Hat Enterprise Linux (RHEL) 9现已普遍可用 (GA…

吃柿子的禁忌靠谱吗?

图片来源&#xff1a;pixabay 秋冬是柿子上市的季节&#xff0c;虽然柿子并不是苹果、香蕉这样的大宗水果&#xff0c;但是秋天不吃个柿子&#xff0c;冬天不吃个柿饼&#xff0c;总觉得少了点什么。 关于吃柿子有很多禁忌&#xff0c;比如说柿子不能与螃蟹同时吃&#xff0c;柿…

​怎么保留硬盘数据合并分区 ,如何才能合并且不丢失数据

硬盘分区合并是比较常见的操作&#xff0c;​怎么保留硬盘数据合并分区&#xff0c;还是具有一定的难度。因为在Windows操作系统中&#xff0c;用户可以通过磁盘管理来实现硬盘分区合并&#xff0c;但是要删除该磁盘分区右侧的相邻分区&#xff0c;但是对于部分不懂计算机的用户…

Tailscale的子网路由和出口节点

2 年前&#xff0c;老苏写了 『 外网访问群晖的新方案Tailscale 』&#xff0c;第一次隆重的给大家推荐了 Tailscale&#xff0c;但当时还有很多功能并不具备&#xff0c;比如今天要介绍的 Subnet Router 和 Exit Node 【特别说明】&#xff1a;老苏使用的是DSM6 &#xff0c;所…

RabbitMQ初步到精通-第一章-消息中间件介绍

第一章 消息中间件介绍 1.MQ概述 MQ全称是Message Queue&#xff0c;消息的队列&#xff0c;因为是队列&#xff0c;所以遵循FIFO 先进先出的原则&#xff0c;它是一种跨进程的通信机制&#xff0c;用于上下游传递消息。 在互联网架构中&#xff0c;MQ是一种非常常见的上下游“…

论文阅读笔记 | 三维目标检测——VeloFCN算法

如有错误&#xff0c;恳请指出。 文章目录paper&#xff1a;《Vehicle Detection from 3D Lidar Using Fully Convolutional Network》 对于64线激光雷达全范围扫描出来的点云进行特征图的构建。对于具体的点&#xff08;xyz坐标&#xff09;&#xff0c;其在水平方向上可以通…

一个是证书服务和web安全访问配置,一个是PGP的使用

一个是证书服务和web安全访问配置&#xff0c;一个是PGP的使用 IIS介绍 IIS是本机自带的服务&#xff0c;用于上线web网页&#xff1b;虽然是自带但因为非开发人员用不到&#xff0c;所以属于预安装&#xff1b;在本机搜索下载即可&#xff0c; 打开后 证书服务&#xff0c;认…

LeetCode[105]从前序与中序遍历序列构造二叉树

难度&#xff1a;中等 题目&#xff1a; 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 示例 1: 输入: preorder [3,9,20,15,7], inorder [9,3,1…

Vue基础4

Vue基础4计算属性姓名案例 - 第一种用click.keyup的方法姓名案例 - 第二种用v-model双向绑定的方法姓名案例 - 第三种使用methods方法姓名案例 - 第四种使用计算属性的方法计算属性的简写—只考虑读取&#xff0c;不考虑修改时候使用监视属性第一种普通写法第二种用计算属性的写…

【信号处理】卡尔曼(Kalman)滤波(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

Java内部类分类

文章目录内部类分类局部内部类的使用匿名内部类成员内部类静态内部类一个类的内部又完整的嵌套了另一个类结构。被嵌套的类称为内部类(inner class),嵌套其他类的类称为外部类(outer class)。是我们类的第五大成员 思考:类的五大成员是哪些? - 属性、方法、构造器、代码块、内…

Windows安装Git教程(2022.11.18 Git2.38.1)

&#xff08;1&#xff09;首先前往Git官网&#xff0c;下载安装文件&#xff1a; &#xff08;2&#xff09;打开安装程序&#xff0c;把Only show new options的勾去掉&#xff0c;点击Next&#xff1a; &#xff08;3&#xff09;此处可以选用默认设置&#xff0c;也可以勾…

ProCAST一键导出有限元模型的几何拓扑和属性信息

第一次将ProCast有限元后处理中的数据导出&#xff0c;当时没有经验&#xff0c;方法比较粗暴&#xff0c;详情见文章&#xff1a;ProCast导出节点应力数据并格式化。 最近发现了一种更高效的数据导出“新姿势”&#xff0c;能够快速得到有限元模型的几何拓扑和节点属性数据&a…

电科大离散数学-2-命题逻辑-2

目录 2.7 范式 2.7.1 范式的定义 2.7.2 范式存在定理 2.8 主析取范式和主合取范式 2.8.1 极小项和极大项的定义和编码 2.8.2 极小项和极大项的性质 2.8.3 主析取范式和主合取范式的定义 2.8.4 主范式求解定理 2.8.5 真值表技术 2.8.6 范式的相互转化 2.8.7 主范式的…

[附源码]Python计算机毕业设计jspm计算机学院党员积分管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

Markdown 教程之如何在 Markdown 文档中添加流程图、方程式和交互式图形

您是否遇到过想要在 Markdown 文档中包含一些简单图表或方程式的场景?如果这是一次性的事情,你可以做的是使用 Power Point 或在线生成器,将图表保存为图像并将其放在你的文章中。这种方法的缺点是背景颜色可能与您的文章不匹配,并且进行更改非常耗时。 Markdown 扩展是第…