LV.12 D13 UART实验 学习笔记

news2025/2/23 9:38:34

一、UART帧格式详解

 UART    

        Universal Asynchronous Receiver Transmitter 即     通用异步收发器,是一种通用的串行、异步通信总线     该总线有两条数据线,可以实现全双工的发送和接收,在嵌入式系统中常用于主机与辅助设备之间的通信。

通信基础 - 并行和串行

        并行通信:总线在传送数据的时候,可以一次性发送多位数据。

        

        串行通信:数据线只有一根,逐次传送各位数据

 

        在同等条件下,并行比串行的通信速度更快,但并行使用的总线数量较多,会比较浪费资源,布线难度也比较大,不同总线在传输数据时,线和线之间都会有一些信号的干扰。做项目时,使用串行通信多一点

通信基础 - 单工和双工

        单工通信:通信的双方区分为发送器和接收器,数据传输的方向是单向的

 

        双工通信: 分为半双工和全双工,它们数据的传输都是双向的。半双工通信时,A和B可以互相发数据,但不能是同时的,而全双工可以同时进行。

如果总线的数据线只有一根,一般是半双工的,如果有多根,一般是全双工。

通信基础 - 波特率 

        波特率用于描述UART通信时的通信速度,其单位为bps(bit per second)即每秒钟传送的bit的数量

UART帧格式

        起始位表示一次通信的开始,数据位就是通过串口发送的数据,校验位会校验(只能校验,不能修正)数据发送的正确性,停止位表示一次通信的结束。如果想发送多个数据,重复这个步骤就可以

注:  1、数据线在空闲时,数据线上的状态必须是高电平。       

         2、发送数据时,先发低位数据。

        3、串口每次只能发送一个字节, 是为了避免产生累计误差(发送方与接收方的时间误差)。

        串口一般为奇偶校验。奇偶校验(Parity Check)是一种校验代码传输正确性的方法。根据被传输的一组二进制代码的数位中“1”的个数是奇数或偶数来进行校验。采用奇数的称为奇校验,反之,称为偶校验。采用何种校验是事先规定好的。通常专门设置一个奇偶校验位,用它使这组代码中“1”的个数为奇数或偶数。若用奇校验,则当接收端收到这组代码时,校验“1”的个数是否为奇数,从而确定传输代码的正确性。

UART硬件连接

 两个芯片通信时,要交叉接线,一方的TXD要与另一方的RXD连接,

 

UART控制器

         一般情况下处理器中都会集成UART控制器 我们使用UART进行通信时候只需对其内部的相 关寄存器进行设置即可。

二、Exynos4412下的 UART控制器

引脚功能设置 

 注:设置引脚功能的实质是让引脚在芯片内部连接到某一个对应的控制器上

 

        串口的高低电平信号较弱,极有可能收到干扰,通信距离较短。为了增强串口的信号,在中间加了一个U3芯片,把串口发出来的TTL信号转化为232信号。 

         设置引脚功能本质上就是让引脚连接对应的控制器

  

        UART在4412内部提供了四个独立的通道,每个通道都包含输入输出端口,这4和通道时Ch0-3,另外还提供了一个专用通道Ch4,用于跟GPS通信(本次使用的是ch2)。所有的端口都可以运行中断和DMA模式。在CPU和串口控制器进行数据传送时,UART既可以产生中断,也可以产生DMA的一些请求。UART支持的波特率最大是4Mbps。每个串口通道都有两个FIFO用于接收和发送数据,

        想要发送数据时,只需要将发送内容写入FIFO(队列)就会自动发送,接收时也只需要读取FIFO(队列)内容即可。

 

串口的波特率是可以编程的

支持红外传输,(无线)

1位或者两位停止位

数据位可以是5-8位,还可以有校验位

 

 波特率发生器、发送器、接收器、控制单元

 

        波特率的发生器使用SCLK_UART时钟,他的频率时100M,发送器和接收器都包含队列和移位器。要被发送的数据会先写到发送队列里,如何数据会被拷贝到发送的移位器。数据通过发送数据的引脚被移出去。接收的数据从接收数据的引脚移进来,被拷贝到接收的缓冲区里。

数据通过FIFO->移位器->引脚实现发送,通过引脚->移位器->FIFO实现接收。

 

三、UART寄存器详解 

先用tar xvf命令解压出一个新工程

 

1、将GPA1_0和GPA1_1分别设置成UART2的接收引脚和发送引脚 GPA1CON[7:0] 

 

 

2、设置UART2的帧格式 ULCON2 (8位数据位、1位停止位、无校验位、正常模式)

 

 

 回环模式就是将发送端和用户端短接,一般用于测试。

 

中断模式:有消息通知CPU

轮询模式:CPU不断的读取缓冲区,查看有没有数据

DMA:自动传送给内存,解放CPU

 AFC:自动流控制,这次实验就是普通的收发暂时不需要

3、设置UART2的接收和发送模式为轮询模式 UCON2[3:0]

 

 

 只读,[1]表示发送的队列是空的,[0]表示接收的队列有数据

把要发送的数据写到UTXHn寄存器的[7:0]位

 

接收器接收到的数据会放入URXHn寄存器的[7:0]位

 

 

  UBRDIVn寄存器的[15:0]位和UFRACVALn寄存器的[3:0]位是设置波特率的

4、设置UART2的波特率为115200 (UBRDIV2 / UFRACVAL2) 

四、UART编程

#include "exynos_4412.h"

int main()
{
	/*1.将GPA1_0和GPA1_1设置成UART2的接收引脚和发送引脚 GPA1CON[7:0]*/
	GPA1.CON = GPA1.CON & (~(0xFF << 0)) | (0x22 << 0);

	/*2.设置UART2的帧格式 ULCON2 (8位数据位、1位停止位、无校验位、正常模式)*/
	UART2.ULCON2 = UART2.ULCON2 & (~(0x7F << 0)) | (0x3 << 0);
	
	/*3.设置UART2的接收和发送模式为轮询模式 UCON2[3:2]*/
	UART2.UCON2 = UART2.UCON2 & (~(0xF << 0)) | (0x5 << 0);

	/*4.设置UART2的波特率为115200 (UBRDIV2 / UFRACVAL2)*/
	UART2.UBRDIV2 = 53;
	UART2.UFRACVAL2 = 4;

	while(1)
	{
		/*将发送的数据写入发送寄存器 UTXH2*/
		UART2.UTXH2 = 'A';
	}
	return 0;
}

 

#include "exynos_4412.h"

int main()
{
	/*1.将GPA1_0和GPA1_1设置成UART2的接收引脚和发送引脚 GPA1CON[7:0]*/
	GPA1.CON = GPA1.CON & (~(0xFF << 0)) | (0x22 << 0);

	/*2.设置UART2的帧格式 ULCON2 (8位数据位、1位停止位、无校验位、正常模式)*/
	UART2.ULCON2 = UART2.ULCON2 & (~(0x7F << 0)) | (0x3 << 0);
	
	/*3.设置UART2的接收和发送模式为轮询模式 UCON2[3:2]*/
	UART2.UCON2 = UART2.UCON2 & (~(0xF << 0)) | (0x5 << 0);

	/*4.设置UART2的波特率为115200 (UBRDIV2 / UFRACVAL2)*/
	UART2.UBRDIV2 = 53;
	UART2.UFRACVAL2 = 4;

	while(1)
	{
		/*将发送的数据写入发送寄存器 UTXH2*/
		UART2.UTXH2 = 'A';
		UART2.UTXH2 = 'B';
		UART2.UTXH2 = 'C';
		UART2.UTXH2 = 'D';
	}
	return 0;
}

 并没有输出想要的结果,因为CPU的执行速度是1GHz,而发送器的速度是115200,两者的速度不一样,所以发送的字符是随机的。

#include "exynos_4412.h"

int main()
{
	/*1.将GPA1_0和GPA1_1设置成UART2的接收引脚和发送引脚 GPA1CON[7:0]*/
	GPA1.CON = GPA1.CON & (~(0xFF << 0)) | (0x22 << 0);

	/*2.设置UART2的帧格式 ULCON2 (8位数据位、1位停止位、无校验位、正常模式)*/
	UART2.ULCON2 = UART2.ULCON2 & (~(0x7F << 0)) | (0x3 << 0);
	
	/*3.设置UART2的接收和发送模式为轮询模式 UCON2[3:2]*/
	UART2.UCON2 = UART2.UCON2 & (~(0xF << 0)) | (0x5 << 0);

	/*4.设置UART2的波特率为115200 (UBRDIV2 / UFRACVAL2)*/
	UART2.UBRDIV2 = 53;
	UART2.UFRACVAL2 = 4;

	while(1)
	{
		/*将发送的数据写入发送寄存器 UTXH2*/
		while(!(UART2.UTRSTAT2 & (1 << 1)));
		UART2.UTXH2 = 'A';
		while(!(UART2.UTRSTAT2 & (1 << 1)));
		UART2.UTXH2 = 'B';
		while(!(UART2.UTRSTAT2 & (1 << 1)));
		UART2.UTXH2 = 'C';
		while(!(UART2.UTRSTAT2 & (1 << 1)));
		UART2.UTXH2 = 'D';
	}
	return 0;
}

#include "exynos_4412.h"

void UART_Init(void)
{
	/*1.将GPA1_0和GPA1_1设置成UART2的接收引脚和发送引脚 GPA1CON[7:0]*/
	GPA1.CON = GPA1.CON & (~(0xFF << 0)) | (0x22 << 0);

	/*2.设置UART2的帧格式 ULCON2 (8位数据位、1位停止位、无校验位、正常模式)*/
	UART2.ULCON2 = UART2.ULCON2 & (~(0x7F << 0)) | (0x3 << 0);
	
	/*3.设置UART2的接收和发送模式为轮询模式 UCON2[3:2]*/
	UART2.UCON2 = UART2.UCON2 & (~(0xF << 0)) | (0x5 << 0);

	/*4.设置UART2的波特率为115200 (UBRDIV2 / UFRACVAL2)*/
	UART2.UBRDIV2 = 53;
	UART2.UFRACVAL2 = 4;
}

void UART_Send_Byte(char Dat)
{
		/*等待发送寄存器寄存器为空*/
		while(!(UART2.UTRSTAT2 & (1 << 1)));
		/*将发送的数据写入发送寄存器 UTXH2*/
		UART2.UTXH2 = Dat;
}

char UART_Rec_Byte(void)
{
	char Dat;
	/*判断接收寄存器是否接收到了数据*/
	if(UART2.UTRSTAT2 & 1)
	{
		Dat = UART2.URXH2;
		return Dat;
	}
	else
	{
		return 0;
	}
}

int main()
{
	char RecDat = 0;
	UART_Init();
	while(1)
	{
		RecDat = UART_Rec_Byte();
		if(RecDat == 0)
		{

		}
		else
		{
			RecDat = RecDat + 1;
			UART_Send_Byte(RecDat);
		}
	}
	return 0;
}

 输入什么返回什么加一(以ASCII计算)

 

 五、输入输出重定向

#include "exynos_4412.h"

void UART_Init(void)
{
	/*1.将GPA1_0和GPA1_1设置成UART2的接收引脚和发送引脚 GPA1CON[7:0]*/
	GPA1.CON = GPA1.CON & (~(0xFF << 0)) | (0x22 << 0);

	/*2.设置UART2的帧格式 ULCON2 (8位数据位、1位停止位、无校验位、正常模式)*/
	UART2.ULCON2 = UART2.ULCON2 & (~(0x7F << 0)) | (0x3 << 0);
	
	/*3.设置UART2的接收和发送模式为轮询模式 UCON2[3:2]*/
	UART2.UCON2 = UART2.UCON2 & (~(0xF << 0)) | (0x5 << 0);

	/*4.设置UART2的波特率为115200 (UBRDIV2 / UFRACVAL2)*/
	UART2.UBRDIV2 = 53;
	UART2.UFRACVAL2 = 4;
}

void UART_Send_Byte(char Dat)
{
		/*等待发送寄存器寄存器为空*/
		while(!(UART2.UTRSTAT2 & (1 << 1)));
		/*将发送的数据写入发送寄存器 UTXH2*/
		UART2.UTXH2 = Dat;
}

char UART_Rec_Byte(void)
{
	char Dat;
	/*判断接收寄存器是否接收到了数据*/
	if(UART2.UTRSTAT2 & 1)
	{
		Dat = UART2.URXH2;
		return Dat;
	}
	else
	{
		return 0;
	}
}

void UART_Send_Str(char * pstr)
{
	while(*pstr != '\0')
		UART_Send_Byte(*pstr++);
}

int main()
{
	char RecDat = 0;
	UART_Init();
	while(1)
	{  
		UART_Send_Str("Hello World\n");
	}
	return 0;
}

 

#include "exynos_4412.h"
 
void UART_Init(void)
{
	GPA1.CON = GPA1.CON & (~(0xFF)) | (0x22);
	UART2.ULCON2 = UART2.ULCON2 & (~(0x7F)) | (0x3);
	UART2.UCON2 = UART2.UCON2 & (~(0xF)) | (0x5);
	UART2.UBRDIV2 = 53;
	UART2.UFRACVAL2 = 4;
}
 
void uart_send_byte(char Dat)
{	
	while(!(UART2.UTRSTAT2 & (1 << 1)));
	UART2.UTXH2 = Dat;
}
 
char uart_recv_byte(void)
{
	char Dat = 0;
	if(UART2.UTRSTAT2 & 1)
	{
		Dat = UART2.URXH2;
		return Dat;
	}
	else
    {
		return 0;
    }
}
 
void uart_send_str(char * pstr)
{
    while(*pstr != '\0')
        uart_send_byte(*pstr++);
}
 
int main()
{
    char RecDat = 0;
	UART_Init();

    while(1)
    {
        printf("Hello World\n");
    }
	return 0;
}

 

我们也可以把printf封装一下直接调用,但是这时的输出和以前的不同,以前的是Linux为我们提供的C库,它将输出重定向到显卡,所以我们能在屏幕上看到,而这个printf是我们自己写的,它重定向到了串口,所以我们使用串口软件连接单片机时能打印出来 

作业

 1.若使用UART协议发送一个字节的数据0x63,画出信号线上的时序图

注:8位数据位、无校验位、一位停止位

 

2.编程实现电脑远程控制LED状态

注:在终端上输入‘2’,LED2点亮,再次输入‘2’,LED2熄灭... ...

#include "exynos_4412.h"

void UART_Init(void)
{
	/*1.将GPA1_0和GPA1_0_1置成ART2的接收引脚和发送引脚 GPA1CON[7:0]*/
	GPA1.CON = GPA1.CON & (~(0xFF << 0)) | (0x22 << 0);

	/*2.设置UART2的帧格式 ULCON2(8位数据位、1位停止位、无校验位、正常模式)*/
	UART2.ULCON2 = UART2.ULCON2 & (~(0x7F << 0)) | (0x3 << 0);

	/*3.设置UART2的接收和发送模式为轮询模式 UCON2[3:2]*/
	UART2.UCON2 = UART2.UCON2 & (~(0xF << 0)) | (0x5 << 0);

	/*4.设置UART2的波特率为115200 (UBRDIV2 / UFRACVAL2)*/
	UART2.UBRDIV2 = 53;
	UART2.UFRACVAL2 = 4;
}

void GPIO_Init(void)
{
	GPX2.CON = GPX2.CON & (~(0xF << 28)) | (0x1 << 28);
}

void UART_Send_Byte(char Dat)
{
	/*等待发送寄存器寄存器为空*/
	while(!(UART2.UTRSTAT2 & (1 << 1)));
	/*将发送的数据写入发送寄存器 UTXH2*/
	UART2.UTXH2 = Dat;
}

char UART_Rec_Byte(void)
{
	char Dat;
	/*判断接收寄存器是否接收了数据*/
	if(UART2.UTRSTAT2 & 1)
	{
		Dat = UART2.URXH2;
		return Dat;
	}
	else
	{
		return 0;
	}
}

void UART_Send_Str(char * pstr)
{
	while(*pstr != '\0')
		UART_Send_Byte(*pstr++);
}

void OnLED2(void)
{
	GPX2.DAT = GPX2.DAT | (1 << 7);
}

void OffLED2(void)
{
	GPX2.DAT = GPX2.DAT & (~(1 << 7));
}

int main()
{
	char RecDat = 0;
	UART_Init();
	GPIO_Init();
	while(1)
	{   
		RecDat = UART_Rec_Byte();
		if(RecDat == '2')
		{
			if(GPX2.DAT & (1 << 7))
			{
				OffLED2();
			}
			else
			{
				OnLED2();
			}
		}
		else
		{
		}
	}
	return 0;
}

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

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

相关文章

奇淫技巧系列之第四篇:如何搜索Jar包中的xml文件

大神链接&#xff1a;作者有幸结识技术大神孙哥为好友&#xff0c;获益匪浅。现在把孙哥视频分享给大家。 孙哥链接&#xff1a;孙哥个人主页 作者简介&#xff1a;一个颜值99分&#xff0c;只比孙哥差一点的程序员 本专栏简介&#xff1a;话不多说&#xff0c;让我们一起干翻J…

索引创建的原则

索引的创建是数据库优化中非常重要的一部分&#xff0c;正确创建索引可以大大提高查询效率。以下是一些创建索引时需要考虑的原则&#xff1a; 根据查询频率创建索引&#xff1a; 频繁用于检索的列&#xff1a; 那些频繁用于查询的列或经常出现在 WHERE、JOIN、ORDER BY 和 GR…

A股风格因子看板(2023.10 第14期)

该因子看板跟踪A股风格因子&#xff0c;该因子主要解释沪深两市的市场收益、刻画市场风格趋势的系列风格因子&#xff0c;用以分析市场风格切换、组合风格暴露等。 今日为该因子跟踪第14期&#xff0c;指数组合数据截止日2023-09-30&#xff0c;要点如下 近1年A股风格因子检验统…

基于springboot实现学生就业管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现学生就业管理系统演示 摘要 随着信息化时代的到来&#xff0c;管理系统都趋向于智能化、系统化&#xff0c;学生就业管理系统也不例外&#xff0c;但目前国内仍都使用人工管理&#xff0c;市场规模越来越大&#xff0c;同时信息量也越来越庞大&#xff0c;人…

python连接clickhouse (CK)

Author: tkhywang 2810248865qq.com Date: 2023-11-01 11:28:58 LastEditors: tkhywang 2810248865qq.com LastEditTime: 2023-11-01 11:36:25 FilePath: \PythonProject02\Python读取clickhouse2 数据库数据.py Description: 这是默认设置,请设置customMade, 打开koroFileHead…

FreeRTOS_信号量之互斥信号量

目录 1. 互斥信号量 1.1 互斥信号量简介 1.2 创建互斥信号量 1.2.1 函数 xSemaphoreCreateMutex() 1.2.2 函数 xSemaphoreCreateMutexStatic() 1.2.3 互斥信号量创建过程分析 1.2.4 释放互斥信号量 1.2.5 获取互斥信号量 2. 互斥信号量操作实验 2.1 实验程序 2.1.1 …

pytorch 笔记:GRU

1 介绍 对于输入序列中的每个元素&#xff0c;每一层都计算以下函数&#xff1a; ht​ 是t时刻 的隐藏状态xt​ 是t时刻 的输入ht−1​ 是 t-1时刻 同层的隐藏状态或 0时刻 的初始隐藏状态rt​,zt​,nt​ 分别是重置门、更新门和新门。σ 是 sigmoid 函数∗ 是 Hadamard 乘积。…

kubernetes-service微服务

目录 一、service微服务 二、Ipvs模式 三、ClusterIP 1.ClusterIP 2.headless 四、NodePort 1.NodePort 2.默认端口 五、LoadBalancer 1.LoadBalancer 2.metallb 六、ExternalName 一、service微服务 Kubernetes Service微服务是一种基于Kubernetes的微服务架构&…

与云栖的浪漫邂逅:记一段寻找云端之美的旅程

云端之旅 2023 年的云栖大会如约而至&#xff0c;这次云栖大会也是阿里新任掌门蔡老板当任阿里巴巴董事局主席以来的第一次。大会与以往有很多不一样的地方&#xff0c;其中 AIGC 更是本届大会的重点议题&#xff01;你会感叹&#xff0c;阿里还是猛啊&#xff01; 我逛了下展…

十一、W5100S/W5500+RP2040树莓派Pico<ARP 地址解析>

文章目录 1 前言2 简介2 .1 什么是ARP&#xff1f;2.2 ARP的优点2.3 ARP工作原理2.4 ARP应用场景 3 WIZnet以太网芯片4 ARP网络设置示例概述以及使用4.1 流程图4.2 准备工作核心4.3 连接方式4.4 主要代码概述4.5 结果演示 5 注意事项6 相关链接 1 前言 随着网络安全越来越受到重…

UE5——网络——RPC

RPC&#xff08;这个是官方文档的资料&#xff09; 要将一个函数声明为 RPC&#xff0c;您只需将 Server、Client 或 NetMulticast 关键字添加到 UFUNCTION 声明。 例如&#xff0c;若要将某个函数声明为一个要在服务器上调用、但需要在客户端上执行的 RPC&#xff0c;您可以…

@JsonCreator 和 @JsonValue使用说明

Fastxml.jackson提供了JsonValue和JsonCreator注解用于序列化和反序列化时使用. Jackson 是一个流行的 Java 序列化和反序列化库,它可以将 Java 对象转换为 JSON 格式,并将 JSON 格式转换为 Java 对象。在 Jackson 中,@JsonCreator 和 @JsonValue 是两个重要的注解,用于自…

Kafka保证百万级数据写入和重发问题分享

Kafka作为当下流行的高并发消息中间件&#xff0c;大量用于数据采集&#xff0c;实时处理等场景&#xff0c; 那么它如何做到百万级写入速度呢?我们在享受它带来的高并发&#xff0c;高可靠等便利时&#xff0c;同时不得不面对可能存在的问题&#xff0c;项目中最常见的就是丢…

c++之vector容器

1.简介 向量&#xff08;Vector&#xff09;是一个封装了动态大小数组的顺序容器&#xff08;Sequence Container&#xff09;。跟任意其它类型容器一样&#xff0c;它能够存放各种类型的对象。可以简单的认为&#xff0c;向量是一个能够存放任意类型的动态数组。 1.1 vector和…

HyperAI超神经 x 中国信通院 | 可信开源大模型案例汇编(第一期)案例征集计划正式启动自定义目录标题)

为进一步促进大模型的开源和合作&#xff0c;引导开源大模型产业健康规范发展&#xff0c;中国信息通信研究院现开启「可信开源大模型案例汇编&#xff08;第一期&#xff09;」的案例征集计划。 HyperAI超神经将以合作伙伴的身份&#xff0c;协助调研国产开源大模型的技术细节…

敏捷开发用户故事

产品Backlog中的需求通常使用用户故事来表达。 用户故事是从用户&#xff08;需求方&#xff09;的视角描述对用户有价值的需求 Who 这个需求为谁服务 What 具体要做什么 Why 目的是什么 一个典型的用户故事会以如下形式表达&#xff1a; 用户故事格式示例&#xff1a; 作…

基于SC-LeGO-LOAM的建图和ndt_localizer的定位

link 基于SC-LeGO-LOAM的建图和ndt_localizer的定位 链接: link. SC-LeGO-LOAM 链接: link. ndt_localizer 将建图和定位两部分分开&#xff0c;利用SC-LeGO-LOAM进行建图&#xff0c;相比于LeGO-LOAM&#xff0c;其采用了Scan Context方法&#xff0c;对点云地图进行闭环检测和…

5G智能安全帽_实时对讲/视频通话/高精度定位_智能安全帽功能介绍

5G智能安全帽是一种具有工业级高清晰度摄像头和5G/WIFI网络功能的产品。在传统安全帽的基础上&#xff0c;智能安全帽集成了摄像头、语音和通信主板等模块。它具备高清视频采集、语音通讯、对讲、本地视频存储等功能&#xff0c;通过这种佩戴式设备&#xff0c;不仅可以实现数据…

app逆向之charles配置

声明&#xff1a;本文仅限学习交流使用&#xff0c;禁止用于非法用途、商业活动等。否则后果自负。如有侵权&#xff0c;请告知删除&#xff0c;谢谢&#xff01;本教程也没有专门针对某个网站而编写&#xff0c;单纯的技术研究 目录 charles配置手机配置 charles配置 最近有点…

瑞数专题五

今日文案&#xff1a;焦虑&#xff0c;想象力过度发酵的产物。 网址&#xff1a;https://www.iyiou.com/ 专题五主要是分享瑞数6代。6代很少见&#xff0c;所以找理想哥要的&#xff0c;感谢感谢。 关于瑞数作者之前已经分享过4篇文章&#xff0c;全都收录在瑞数专栏中了&am…