通信协议(一)——UART协议

article/2025/9/17 12:15:06

1、知识点

基础部分参考:UART串口发送模块设计Verilog_发光中请勿扰的博客-CSDN博客_uart设计verilog

 (1)什么是串口(UART)?

        串口作为常用的三大低速总线(UART、SPI、IIC)之一,在设计众多通信接口和调试时占有重要地位。串口(UART)全称通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),主要用于数据间的串行传递,是一种全双工传输模式。它在发送数据时将并行数据转换成串行数据来传输,在接收数据时将接收到的串行数据转换成并行数据。

        “异步”两个字即意味着在数据传递的两个模块之间使用的不是同步时钟。实际上在异步串口的传输中是不需要时钟的,而是通过特定的时序来标志传输的开始(起始位--由高到低)和结束(结束位,拉高)。

(2)串口的组成

        UART 通信只有两根信号线,一根是发送数据端口线叫 tx(Transmitter),一根是接收数据端口线叫 rx(Receiver),如图所示,对于 PC 来说它的 tx 要和对于 FPGA来说的 rx 连接,同样 PC 的 rx 要和 FPGA 的 tx 连接,如果是两个 tx 或者两个 rx 连接那数据就不能正常被发送出去和接收到。 

        信号的传输由外部驱动电路实现。电信号的传输过程有着不同的电平标准和接口规范,针对异步串行通信的接口标准有RS232、RS422、RS485等,它们定义了接口不同的电气特性,如RS-232是单端输入输 出,而RS-422/485为差分输入输出等。传输距离较短时(不超过15m),RS232是串行通信最常用的接口标准。RS-232标准的串口最常见的接口类型为DB9,样式如图所示,工业控制领域中用到的工控机一般都配备多个串口,很多老式台式机也都配有串口。但是笔记本电脑以及较新一点 的台式机都没有串口,它们一般通过USB转串口线来实现与外部设备的串口通信。

(3)RS232

 帧结构(10bit):

 空闲状态保持高电平

        UART 在发送或接收过程中的一帧数据由4部分组成,起始位、数据位、奇偶校验位和停止位,如图所示。其中,起始位标志着一帧数据的开始,停止位标志着一帧数据的结束,数据位是一帧数据中的有效数据。

        校验位分为奇校验和偶校验,用于检验数据在传输过程中是否出错。 奇校验时,发送方应使数据位中1的个数与校验位中1的个数之和为奇数;接收方在接收数据时, 对1的个数进行检查,若不为奇数,则说明数据在传输过程中出了差错。同样,偶校验则检查 1的个数是否为偶数。

 

        UART通信过程中的数据格式及传输速率是可设置的,为了正确的通信,收发双方应约定并遵循同样的设置。数据位可选择为5、6、7、8位,其中8位数据位是最常用的,在实际应用中 一般都选择8位数据位;校验位可选择奇校验、偶校验或者无校验位;停止位可选择1位(默认), 1.5或2位。

        串口通信的速率用波特率表示,它表示每秒传输二进制数据的位数,单位是bps(位 /秒),常用的波特率有9600、19200、38400、57600以及115200等。如波特率9600则代表每秒传输9600bit数据,以串口发送1个字节10bit算(起始位1bit+数据8bit+停止位1bit+NO校验位),则传输1个字节需要的时间是1*10/9600秒。 

2、设计

(1)模块框图

顶层模块:

 子功能模块

串口数据接收模块:

 串口数据发送模块:

整体框图:


( 2)功能实现

① 串口数据接收模块:

需要对rx数据进行打一拍,与系统时钟同步,但仍无法直接传送,因为该信号属于异步信号,会引出亚稳态。

亚稳态问题参考:亚稳态问题_发光中请勿扰的博客-CSDN博客

解决方法:对打拍后的数据再次打两拍

波形图:

波形:

 data输入

 打拍信号

使能信号 

 计数最大值

bit标志位

        该模块支持任意波特率(理论上)的接收,但需要在使用该模块时使用参数将其例化,数据位8位,起始位和停止位各1位,无奇偶校验
        串口的传输是以起始位开始的,而起始位是将数据线拉低 ,所以我们需要捕捉数据线的下降沿,将接收数据线打拍两次,捕捉其下降沿。当捕捉到接收数据线的下降沿,拉高接收标志信号,标志模块进入接收过程;当接收完10个bit后,拉低接收标志信号,标志接收过程结束
        假设波特率为9600,则传输一个bit的时间为1s/9600,一个数据的传输共10bit(数据位8位,起始位和停止位各1位),则共需要1s/960;假设系统时钟为50MHz(参数化以便适应不同的系统频率),则其周期为20ns,那么传输一个bit所需要的系统周期数为(1s/960)/ 20ns ≈ 5208(个)。在接收过程中使用一个计数器计数,计数区间为(0,5208-1),这样的区间一共10个(一个字节需要传输10个bit);此外还需一个计数器对接收的bit数计数(每当上一个计数器计数到5207则表示接收完了一个bit),计数区间(0,9)。
        在接收过程,根据计数器的值(接收bit计数器),在每个bit计数器的中间接收数据,将其移位寄存(在电平中间数据最稳定)
        若接收bit计数器 = 0,则代表是起始位,不需要接收
        若接收bit计数器 = 1,则代表此时接收到数据的最低位LSB(数据的传输总是低位在前,高位在后),将其赋值给寄存数据的最低位;
        ······
        若接收bit计数器 = 8,则代表此时接收到数据的最高位MSB,将其赋值给寄存数据的最高位;
        若接收bit计数器 = 9,则代表是停止位,不需要接收

 代码:

module uart_rx
#(parameter uart_bps = 'd9600,//波特率parameter clk_fre  = 'd50_000_000//频率
)
(input sys_clk   ,input sys_rst_n		,input rx		,output reg [7:0]po_data	,output reg po_flag
);parameter baud_cnt_max = clk_fre/uart_bps; //频率除以波特率reg rx_reg1										;
reg rx_reg2										;
reg rx_reg3										;
reg start_flag									;
reg work_en										;
reg [15:0]baud_cnt								;
reg bit_flag									;
reg [3:0]bit_cnt								;
reg [7:0]rx_data								;
reg rx_flag										;//打一拍,同步到系统时钟下
always @(posedge sys_clk or negedge sys_rst_n)if(!sys_rst_n)rx_reg1 <= 1'b1;else rx_reg1 <= rx;//打两拍,消除亚稳态		
always @(posedge sys_clk or negedge sys_rst_n)if(!sys_rst_n)rx_reg2 <= 1'b1;else rx_reg2 <= rx_reg1 ;always @(posedge sys_clk or negedge sys_rst_n)if(!sys_rst_n)rx_reg3 <= 1'b1;else rx_reg3 <= rx_reg2 ;//开始标志信号		
always @(posedge sys_clk or negedge sys_rst_n)if(!sys_rst_n)start_flag <= 1'b0;else if (rx_reg2 == 1'b0 && rx_reg3 == 1'b1 && work_en == 1'b0)//引入使能信号是为了避免在数据传输时遇到1变为0,从而检验到下降沿start_flag <= 1'b1;elsestart_flag <= 1'b0;//使能信号		
always @(posedge sys_clk or negedge sys_rst_n)if(!sys_rst_n)work_en <= 1'b0;else if(start_flag == 1'b1)work_en <= 1'b1;else if(bit_cnt == 4'd8 && bit_flag == 1'b1)work_en <= 1'b0;//bit计数器和bit标志信号elsework_en <= work_en;//波特率计数器		
always @(posedge sys_clk or negedge sys_rst_n)if(!sys_rst_n)baud_cnt <= 16'd0;else if((baud_cnt == baud_cnt_max - 1 )  || (work_en == 1'b0))baud_cnt <= 16'd0;elsebaud_cnt <= baud_cnt + 1'b1;//bit标志信号	
always @(posedge sys_clk or negedge sys_rst_n)if(!sys_rst_n)bit_flag <= 1'b0;else if(baud_cnt == baud_cnt_max / 2 - 1)bit_flag <= 1'b1;elsebit_flag <= 1'b0;
//bit计数器
always @(posedge sys_clk or negedge sys_rst_n)if(!sys_rst_n)bit_cnt <= 4'd0;else if(bit_cnt == 4'd8 && bit_flag == 1'b1)bit_cnt <= 4'd0;else if(bit_flag == 1'b1)bit_cnt <= bit_cnt + 1'b1;//数据拼接	
always @(posedge sys_clk or negedge sys_rst_n)if(!sys_rst_n)rx_data <= 8'b0;else if(bit_cnt >= 4'd1 && bit_cnt <= 4'd8 && bit_flag == 1'b1)rx_data <= {rx_reg3,rx_data[7:1]};always @(posedge sys_clk or negedge sys_rst_n)if(!sys_rst_n)rx_flag <= 1'b0;else if(bit_cnt == 4'd8 && bit_flag == 1'b1)rx_flag <= 1'b1;elserx_flag <= 1'b0;
//输出并行信号		
always @(posedge sys_clk or negedge sys_rst_n)if(!sys_rst_n)po_data <= 8'b0;else if(rx_flag == 1'b1)po_data <= rx_data;
//对rx_flag进行打拍,保持与输出数据同步
always @(posedge sys_clk or negedge sys_rst_n)if(!sys_rst_n)po_flag <= 1'b0;else po_flag <= rx_flag;endmodule
`timescale 1ns/1ns	//定义时间刻度
//模块、接口定义
module uart_rx_tb();reg 			sys_clk			;			
reg 			sys_rst_n		;
reg				rx				;			
wire	[7:0]	po_data			;
wire            po_flag			;initial begin	sys_clk <= 1'b0;	sys_rst_n <= 1'b0;rx <= 1'b1;#20sys_rst_n <= 1'b1;end
always #10 sys_clk <= ~sys_clk;initial begin #200rx_bit(8'd0);rx_bit(8'd1);rx_bit(8'd2);rx_bit(8'd3);rx_bit(8'd4);rx_bit(8'd5);rx_bit(8'd6);rx_bit(8'd7);end//例化发送模块
uart_rx 
#(.uart_bps (9600),.clk_fre  (50_000_000)
)
uart_rx_inst
(.sys_clk(sys_clk)   ,.sys_rst_n(sys_rst_n),.rx(rx)		,.po_data(po_data)	,.po_flag(po_flag)
);task rx_bit (input [7:0] data
);integer i; //定义一个常量//用 for 循环产生一帧数据,for 括号中最后执行的内容只能写 i=i+1for(i=0; i<10; i=i+1) begincase(i)0: rx <= 1'b0;		//起始位1: rx <= data[0];		//LSB2: rx <= data[1];3: rx <= data[2];4: rx <= data[3];5: rx <= data[4];6: rx <= data[5];7: rx <= data[6];8: rx <= data[7];		//MSB9: rx <= 1'b1;		//停止位endcase#(5208*20); 		//每发送 1 位数据延时end		
endtask 							//任务结束endmodule 

 ②串口数据接收模块

波形图:

 波形:

模拟产生输入

 输入标志信号

 中间变量

 输出

module uart_tx
#(parameter uart_bps = 'd9600,parameter clk_fre  = 'd50_000_000
)
(input sys_clk			,input sys_rst_n				,input [7:0]pi_data		,input pi_flag			,output reg tx				
);localparam baud_cnt_max = clk_fre/uart_bps;reg         work_en				;
reg  [15:0] baud_cnt			;
reg  		bit_flag			;
reg  [3:0]	bit_cnt				;//使能信号
always @(posedge sys_clk or negedge sys_rst_n)if(!sys_rst_n)work_en <= 1'b0;else if(pi_flag == 1'b1)work_en <= 1'b1;else if(bit_cnt == 4'd09 &&  bit_flag == 1'b1)	work_en <= 1'b0;
//波特计数器
always @(posedge sys_clk or negedge sys_rst_n)if(!sys_rst_n)baud_cnt <= 16'd0;else if(work_en == 1'b0 || baud_cnt == baud_cnt_max - 1)baud_cnt <= 16'd0;else if(work_en == 1'b1)baud_cnt <= baud_cnt + 1'b1;
//bit标志位		
always @(posedge sys_clk or negedge sys_rst_n)if(!sys_rst_n)bit_flag <= 1'b0;else if(baud_cnt == 16'd1)bit_flag <= 1'b1;elsebit_flag <= 1'b0;
//bit计数器		
always @(posedge sys_clk or negedge sys_rst_n)if(!sys_rst_n)bit_cnt <= 4'd0;else if(bit_cnt == 4'd09 && bit_flag == 1'b1)bit_cnt <= 4'd0;else if(work_en == 1'b1 && bit_flag == 1'b1)bit_cnt <= bit_cnt + 1'b1;always @(posedge sys_clk or negedge sys_rst_n)if(!sys_rst_n)tx <= 1'b1;else if(bit_flag == 1'b1)case(bit_cnt)0:tx <= 1'b0;1:tx <= pi_data[0];2:tx <= pi_data[1];3:tx <= pi_data[2];4:tx <= pi_data[3];5:tx <= pi_data[4];6:tx <= pi_data[5];7:tx <= pi_data[6];8:tx <= pi_data[7];9:tx <= 1'b1;default : tx <= 1'b1;endcaseendmodule	
`timescale 1ns/1ns	//定义时间刻度
//模块、接口定义
module uart_tx_tb();reg 			sys_clk			;			
reg 			sys_rst_n		;			
reg [7:0]		pi_data			;
reg 			pi_flag			;wire 	 		tx		;initial begin	sys_clk <=1'b0;	sys_rst_n <=1'b0;					#20 										sys_rst_n <=1'b1;endalways #10 sys_clk = ~sys_clk;initial beginpi_data <= 8'd0;pi_flag <= 1'b0;#200//数据0pi_data <= 8'd0;pi_flag <= 1'b1;#20pi_flag <= 1'b0;#(5208*10*20)//数据1pi_data <= 8'd1;pi_flag <= 1'b1;#20pi_flag <= 1'b0;#(5208*10*20)//数据2pi_data <= 8'd2;pi_flag <= 1'b1;#20pi_flag <= 1'b0;#(5208*10*20)//数据3pi_data <= 8'd3;pi_flag <= 1'b1;#20pi_flag <= 1'b0;#(5208*10*20)//数据4pi_data <= 8'd4;pi_flag <= 1'b1;#20pi_flag <= 1'b0;#(5208*10*20)//数据5pi_data <= 8'd5;pi_flag <= 1'b1;#20pi_flag <= 1'b0;#(5208*10*20)//数据6pi_data <= 8'd6;pi_flag <= 1'b1;#20pi_flag <= 1'b0;#(5208*10*20)//数据7pi_data <= 8'd7;pi_flag <= 1'b1;#20pi_flag <= 1'b0;end//例化发送模块uart_tx
#(.uart_bps (9600),.clk_fre  (50_000_000)
)
uart_tx_inst
(.sys_clk	(sys_clk)		,.sys_rst_n	(sys_rst_n)		,.pi_data	(pi_data)		,.pi_flag	(pi_flag)		,.tx			(tx)	
);endmodule 

③顶层模块:

 波形:

rx数据接收(第一个拉高为数据得停止位)

 task验证

数据传递

//顶层
module rs232	
(	
//系统接口input 				sys_clk			,			//50M系统时钟input 				sys_rst_n		,			//系统复位
//UART	input 				rx,			//接收数据线output  			tx					//UART发送数据线
);//wire define				
wire	[7:0]	rx_data	;						//接收到的一个BYTE数据
wire			rx_flag	;						//接收有效信号,可用作发送的使能信号//例化发送模块
uart_tx
#(.uart_bps (9600),.clk_fre  (50_000_000)
)
uart_tx_inst
(.sys_clk	(sys_clk)		,.sys_rst_n	(sys_rst_n)		,.pi_data	(rx_data)		,.pi_flag	(rx_flag)		,.tx			(tx)	
);
//例化接收模块
uart_rx 
#(.uart_bps (9600),.clk_fre  (50_000_000)
)
uart_rx_inst
(.sys_clk(sys_clk)  	 	,.sys_rst_n(sys_rst_n)	,.rx(rx)					,.po_data(rx_data)		,.po_flag(rx_flag)
);
endmodule 
`timescale 1ns/1ns	//定义时间刻度
module rs232_tb();reg 			sys_clk			;			
reg 			sys_rst_n		;
reg				rx				;
wire			tx				;initialbeginsys_clk <= 1'b0;	sys_rst_n <= 1'b0;rx <= 1'b1;#20sys_rst_n <= 1'b1;end
always #10 sys_clk <= ~sys_clk;initial begin#200rx_byte();	endtask rx_byte();integer j; //定义一个常量for(j=0; j<8; j = j +1) rx_bit(j);
endtasktask rx_bit (input [7:0] data
);integer i; //定义一个常量//用 for 循环产生一帧数据,for 括号中最后执行的内容只能写 i=i+1for(i=0; i<10; i=i+1) begincase(i)0: rx <= 1'b0;		//起始位1: rx <= data[0];		//LSB2: rx <= data[1];3: rx <= data[2];4: rx <= data[3];5: rx <= data[4];6: rx <= data[5];7: rx <= data[6];8: rx <= data[7];		//MSB9: rx <= 1'b1;		//停止位endcase#(5208*20); 		//每发送 1 位数据延时end		
endtask 							//任务结束rs232	rs232_inst
(	
//系统接口.sys_clk(sys_clk)			,			//50M系统时钟.sys_rst_n(sys_rst_n)		,			//系统复位
//UART	.rx(rx)				,			//接收数据线.tx(tx)					//UART发送数据线
);endmodule

http://chatgpt.dhexx.cn/article/U88pgjx4.shtml

相关文章

uart协议学习,从了解到入门,看这篇文章

uart协议从了解到入门 背景知识介绍&#xff1a;1、并行和串行的意思&#xff1a;2、串转并和并转串传输&#xff1a;3、单工、半双工、全双工区别&#xff1a; uart协议介绍1、uart简介2、uart通信3、uart工作原理 uart的优缺点 背景知识介绍&#xff1a; 1、并行和串行的意思…

FPGA实现uart协议

简介 使用verilog实现uart协议&#xff0c;能够和pc进行通信&#xff0c;实现串口回环功能&#xff0c;各参数设置如下&#xff1a; 波特率&#xff1a;115200数据位&#xff1a;8停止位&#xff1a;任意校验位&#xff1a;无 系统时钟为50M&#xff0c;115200波特率下&…

协议篇之UART协议

协议篇之UART协议 一、写在前面二、UART协议简介三、UART协议数据帧结构3.1 UART发送过程3.2 UART接收过程3.3 UART传输速率 四、UART收发模块设计4.1 UART接收模块设计4.2 UART发送模块设计4.3 UART回环顶层模块4.4 UART回环上板验证 五、写在最后 一、写在前面 由于设计需要&…

UART通信协议

UART通信协议 UART ( universal asynchronous receiver-transmitter&#xff09;是一种采用异步串行通信方式的通用异步收发传输器;它在发送数据时将并行数据转换成串行数据来传输&#xff0c;在接收数据时将接收到的串行数据转换成并行数据。UART串口通信需要两根信号线来实现…

UART协议讲解

UART协议讲解 一、什么是UART协议二、通信方式的分类1、串行通信&#xff08;一&#xff09;、同步通信和异步通信&#xff08;二&#xff09;、单工和半双工以及全双工 2、并行通信 三、UART协议具体介绍1、UART数据传输的格式2、UART电平标准 三、UART的优缺点四、参考 一、什…

【数字IC】深入浅出理解UART协议

深入浅出理解UART协议 一、什么是UART&#xff1f;二、UART的帧格式2.1 为什么UART的传输需要起始位&#xff1f;2.2 UART基本的数据形式2.3 为什么UART的数据位可变&#xff1f; 三、UART的波特率3.1 什么是波特率3.2 如何换算波特率3.3 波特率和采样频率是一样的吗&#xff1…

最详细的 UART协议 分析在这里!

1. 协议基础 1.1. 协议简介 UART是“Universal Asynchronous Receiver/Transmitter”&#xff0c;通用异步收发器的缩写。在19世纪60年代&#xff0c;为了解决计算机和电传打字机通信&#xff0c;Bell发明了UART协议&#xff0c;将并行输入信号转换成串行输出信号。因为U…

UART协议

UART协议 简介 UART是通用异步收发传输器&#xff08;Universal Asynchronous Receiver/Transmitter)&#xff0c;通常称作UART&#xff0c;是一种异步收发传输器,是设备间进行异步通信的关键模块。UART负责处理数据总线和串行口之间的串/并、并/串转换&#xff0c;并规定了帧…

【云域网络社区】云域网络社区APP

【软件名称】云域社区 【功能介绍】资源分享&#xff0c;游戏交流交友 【下载地址】http://sss.shmmec.com/apk.apk 图片

怎么划分领域、子域、核心域、通用域和支撑域

怎么划分领域、子域、核心域、通用域和支撑域 如何理解领域和子域&#xff1f;什么是领域什么是子域怎么划分领域和子域如何理解核心域、通用域和支撑域&#xff1f;为什么要划分核心域、通用域和支撑域 总结 DDD 的知识体系提出了很多的名词&#xff0c;像&#xff1a;领域、子…

网络安全-域服务器(二)

域服务器&#xff1a; 域服务器&#xff08;一&#xff09;&#xff1a;网络安全-域&#xff08;一&#xff09;_IT之一小佬的博客-CSDN博客域服务器&#xff08;二&#xff09;&#xff1a;网络安全-域服务器&#xff08;二&#xff09;_IT之一小佬的博客-CSDN博客 域 11.O…

网课管理系统

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a; 3. 功能简介 用户中心 1.1用户注册&#xff1a;用户需要注册才能登陆进入web 1.2用户登录&#xff1a;通过判断匹配来进…

如何搭建域服务器

实验名称&#xff1a;如何搭建域服务器 实验环境&#xff1a;wind2003*2 实验过程&#xff1a; 由于Windows Server 2003在默认的安装过程中DNS是不被安装的&#xff0c;所以我们需要手动去添加&#xff0c; 添加方法如下:“开始—设置—控制面板—添加删除程序”&#xff…

搭建域环境(win)

目录 常见域环境是用&#xff1a;win2012 win7 win2003 本blog环境&#xff1a;Windows Server 2012 R2 and Win2008 1.Window Server 2012 R2 服务器配置 1&#xff09;变更计算机名DC&#xff08;用于存储活动目录数据库的计算机&#xff09; 2&#xff09;设置服务器…

网络教学管理系统

1、项目介绍 网络教学管理系统拥有三种角色 管理员&#xff1a;专业管理、班级管理、学生教师管理、公告管理、留言板管理、学习资料管理、教学视频管理、试题管理等 教师&#xff1a;系统留言、发布作业等 学生&#xff1a;可以查看作业视频、登录注册、下载作业资料等 2、…

域控-笔记二(域权限,域组,域管理,Kerberso 协议)

文章目录 一. 域环境搭建1.1 添加AD功能1.2 安装1.3 部署 二. 如何加入域2.1 加入域2.2 域中主机登录2.3 退出域2.4 添加域用户 三. 域权限3.1 A-G-DL-P策略3.2 组几个比较重要的域本地组几个比较重要的全局组、通用组的权限 四. 域管理4.1 域用户账户的管理4.2 组的管理4.3 组…

中职网络搭建 域用户密码设置

中职网络搭建 密码设置 域密码策略&#xff1a; 进入域控制器组策略&#xff08;组策略管理&#xff09; 计算机配置–Windows设置–安全设置–账户策略–密码策略 “密码必须符合复杂性要求”&#xff1a;密码设置必须要有数字、大写字母、小写字母、字符&#xff0c;四种中…

第一讲 数域

1. 引入 数是数学的一个最基本概念, 回顾一下我们曾经学习过的数的发展过程: (1) 代数性质: 关于数的加, 减, 乘 , 除等运算的性质称为数的代数性质. (2) 数集: 数的集合简称数集. 常见的数集: 复试C; 实数R;有理数Q等等. 它们有一个共同的性质就是对加减乘除运算封闭. 2. 数…

域控知识与安全02:初始访问

初始访问 前言信息收集1.Nmap命令参数使用方法 2.Metasploit命令参数使用方法 3.地址解析协议命令参数使用方法 4.ICMP5.Nbtscan命令参数使用方法 6.telnet使用方法 暴力破解1.Hydra命令参数使用方法 2.Hashcat常用参数使用方法 总结系列相关内容 前言 攻击者首先通过初始访问入…

1. 跨域学习

1. 跨域学习 1.1 什么是跨域 出于浏览器的同源策略限制。同源策略&#xff08;Sameoriginpolicy&#xff09;是一种约定&#xff0c;它是浏览器最核心也最基本的安全功能&#xff0c;如果缺少了同源策略&#xff0c;则浏览器的正常功能可能都会受到影响。可以说Web是构建在同…