当前位置: 首页 > news >正文

ZYNQ初识10(zynq_7010)UART通信实验

基于bi站正点原子讲解视频:

系统框图(基于串口的数据回环)如下:

        以下,是串口接收端的波形图,系统时钟和波特率时钟不同,为异步时钟,,需要先延时两拍,将时钟同步过来,取到start_flag信号,由start_flag信号结合clk_cnt、bps_cnt两个计数器取到rx_flag信号,随后在rx_flag高电平时计算clk_cnt以及bps_cnt两个信号。最后两个信号uart_done、uart_data则在串口发送模块有所体现。

        实际上,uart_done在串口发送模块中也就是uart_en信号,而uart_data也就是发送模块中的uart_din信号。

`timescale 1ns / 1ps
// Create Date: 2025/01/06 09:38:08
// Design Name: 
// Module Name: uart_recv
module uart_recv(input              sys_clk   ,    //50Mhz系统时钟input              sys_rst_n ,input              uart_rxd  ,   //接收到的数据output  reg [7:0]  uart_data  ,   //输出的并行数据output  reg        uart_done     //一帧信号接收完成);parameter  sys_freq = 50_000_000;parameter  uart_bps = 115_200;parameter  bps_cnt  = sys_freq/uart_bps - 1;//从0开始计算reg         uart_rxd_d0;reg         uart_rxd_d1;wire        start_flag;reg         rx_flag;reg  [15:0] clk_cnt;reg  [3:0]  rx_cnt;reg  [7:0]  rx_data;//中间变量存储提取到的每个位的数据来实现串口端的串并转换//由高电平向低电平的跳变(下降沿),相当于d1延时2个时钟周期;d0延时1个时钟周期//因此判断d1是否为高且d0是否为低即可。assign  start_flag = uart_rxd_d1 & (~uart_rxd_d0);//异步时钟同步化处理always@(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)beginuart_rxd_d0 <= 1'b1;uart_rxd_d1 <= 1'b1;endelse beginuart_rxd_d0 <= uart_rxd;uart_rxd_d1 <= uart_rxd_d0;endend//rx_flagalways@(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)rx_flag <= 1'b0;else if(start_flag == 1'b1)rx_flag <= 1'b1;else if((rx_cnt == 4'd9) && (clk_cnt == bps_cnt/2 - 1'b1)) //为监测到下一帧数据的起始位留半个周期的时间rx_flag <= 1'b0;else rx_flag <= 1'b1;end//clk_cntalways@(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)clk_cnt <= 16'd0;else if(rx_flag == 1'b1)
//            begin   //效果相同否?
//                if(clk_cnt == uart_bps)
//                    clk_cnt <= 16'd0; 
//                else 
//                    clk_cnt <= clk_cnt + 16'd1;
//            endbegin                               if(clk_cnt < uart_bps - 16'd1)         clk_cnt <= clk_cnt + 16'd1;           else                            clk_cnt <= 16'd0; end                                                                     else clk_cnt <= 16'd0;  end//rx_cntalways@(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)rx_cnt <= 4'd0;else if(rx_flag == 1'b1)beginif(clk_cnt == uart_bps - 16'd1)rx_cnt <= rx_cnt + 4'd1;else rx_cnt <= rx_cnt;endelserx_cnt <= 4'd0;end//rx_dataalways@(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)rx_data <= 8'd0;else if((rx_flag == 1'b1)&&(clk_cnt == uart_bps/2)) begincase(rx_cnt)//数据的串转并_uart_rxd是异步信号//所以要需要两拍之后的信号uart_rxd_d1。4'd1: rx_data[0] <= uart_rxd_d1;4'd2: rx_data[1] <= uart_rxd_d1;4'd3: rx_data[2] <= uart_rxd_d1;4'd4: rx_data[3] <= uart_rxd_d1;4'd5: rx_data[4] <= uart_rxd_d1;4'd6: rx_data[5] <= uart_rxd_d1;4'd7: rx_data[6] <= uart_rxd_d1;4'd8: rx_data[7] <= uart_rxd_d1;endcaseendendalways@(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)beginuart_data <= 8'd0;uart_done <= 1'd0;endelse if(rx_cnt == 4'd9)begin                       uart_data <= rx_data;    uart_done <= 1'd1;    end   elsebegin                 uart_data <= 8'd0;  uart_done <= 1'd0;  end                               end
endmodule

 以下:如何在程序中捕获信号的高低电平:(可实现异步时钟的同步处理以及信号的边沿检测)

d0 <= 1'b1;
d1 <= 1'b1;

d0 <= uart_rxd;
d1 <= d0; 

        也就是说,在初始状态时将d0、d1拉高,通过两次打拍将d0延时1个时钟周期,d1延时2个时钟周期,从而根据d0和d1的状态,设置wire型的标志位flag来捕获需要的高低电平。

          以下,是是串口发送端的波形图,整体过程和接收端基本类似,只需要进行某些变量名称的修改即可,但需要注意,接收到的数据实际上是串口接收端的发送的数据(uart_data);uart_done信号也在发送端检测边沿电平过程中以uart_en的形式完成了两次打拍延迟。

`timescale 1ns / 1ps
// Create Date: 2025/01/06 14:50:27
// Design Name: 
// Module Name: uart_sendmodule uart_send(input         sys_clk   ,    //50Mhz系统时钟  input         sys_rst_n ,                 output  reg   uart_txd  ,   //准备发送的数据      input         uart_en  ,       input   [7:0] uart_din     //从发送模块接收到的数据    );parameter  sys_freq = 50_000_000;parameter  uart_bps = 115_200;parameter  bps_cnt  = sys_freq/uart_bps - 1;//从0开始计算reg          uart_en_d0;reg          uart_en_d1; reg          tx_flag;reg  [15:0]  clk_cnt;reg  [3:0]   tx_cnt; reg  [7:0]   tx_data;//中间变量存储提取到的每个位的数据来实现串口端的串并转换wire         en_flag;//由高电平向低电平的跳变(下降沿),相当于d1延时2个时钟周期;d0延时1个时钟周期//因此判断d1是否为高且d0是否为低即可。assign  en_flag = (~uart_en_d1) & uart_en_d0;//边沿信号检测,检测上升沿always@(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)beginuart_en_d0 <= 1'b1;uart_en_d1 <= 1'b1;endelse beginuart_en_d0 <= uart_en;uart_en_d1 <= uart_en_d0;endend//tx_dataalways@(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)tx_data <= 8'd0;          else if(en_flag == 1'b1) tx_data <= uart_din;else tx_data <= tx_data;end//tx_flagalways@(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)tx_flag <= 1'b0;else if(en_flag == 1'b1)tx_flag <= 1'b1;else if((tx_cnt == 4'd9) && (clk_cnt == bps_cnt/2 - 1))tx_flag <= 1'b0;else //tx_flag <= tx_flag; //这两句话在这里作用相同否?tx_flag <= 1'b1;end//clk_cntalways@(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)clk_cnt <= 16'd0;else if(tx_flag == 1'b1)
//            begin 
//                if(clk_cnt == uart_bps)
//                    clk_cnt <= 16'd0; 
//                else 
//                    clk_cnt <= clk_cnt + 16'd1;
//            endbegin                               if(clk_cnt < uart_bps - 16'd1)         clk_cnt <= clk_cnt + 16'd1;           else                            clk_cnt <= 16'd0; end                                                                     else clk_cnt <= 16'd0;  end//tx_cntalways@(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)tx_cnt <= 4'd0;else if(tx_flag == 1'b1)beginif(clk_cnt == uart_bps - 16'd1)tx_cnt <= tx_cnt + 4'd1;else tx_cnt <= tx_cnt;endelserx_cnt <= 4'd0;end//uart_txdalways@(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)uart_txd <= 1'b1;else if((tx_flag == 1'b1)&&(clk_cnt == 16'd0)) begincase(tx_cnt)//数据并转串,首先判断起始位,赋值低电平;//随后将tx_data一次赋值给输出端口uart_txd;//最后注意一帧数据的停止位,赋值高电平。4'd0: uart_txd <= 1'b0;4'd1: uart_txd <= tx_data[0];4'd2: uart_txd <= tx_data[1];4'd3: uart_txd <= tx_data[2];4'd4: uart_txd <= tx_data[3];4'd5: uart_txd <= tx_data[4];4'd6: uart_txd <= tx_data[5];4'd7: uart_txd <= tx_data[6];4'd8: uart_txd <= tx_data[7];4'd9: uart_txd <= 1'b1;endcaseendendendmodule

以下是顶层文件,分别将串口发送端和接收端两部分程序例化。

`timescale 1ns / 1ps
// Create Date: 2025/01/06 15:49:15
// Design Name: 
// Module Name: top_uartmodule top_uart(input    sys_clk   ,    //50Mhz系统input    sys_rst_n ,             input    uart_rxd  ,   //接收到的数据output   uart_txd      //准备发送的数据 );wire  [7:0]  uart_data;wire         uart_done;//串口接收模块的例化:uart_recv  uart_recv_u(.sys_clk    (sys_clk   )  ,    //50Mhz系统时钟.sys_rst_n  (sys_rst_n )  ,.uart_rxd   (uart_rxd  )  ,   //接收到的数据.uart_data  (uart_data )  ,   //输出的并行数据.uart_done  (uart_done )     //一帧信号接收完成);//     wire         uart_en ;
//     wire  [7:0]  uart_din;//串口发送模块的例化;uart_send  uart_send_u(.sys_clk   (sys_clk  )   ,    //50Mhz系统时钟  .sys_rst_n (sys_rst_n)   ,                 .uart_txd  (uart_txd )   ,   //准备发送的数据      .uart_en   (uart_done )  ,       .uart_din  (uart_data )      //从发送模块接收到的数据    );endmodule

以下是对应程序的RTL视图:

另注意1:

 打两拍的异步时钟的同步处理,打一拍是为了将异步时钟转为同步时钟,如上本例子是将波特率时钟(115200bps)转换为系统时钟50Mhz,打两拍则是为了消除亚稳态(0 1之间的状态)。

参考连接:【Chips】跨时钟域的亚稳态处理、为什么要打两拍不是打一拍、为什么打两拍能有效?_跨时钟域为什么打两拍-CSDN博客

另注意2:

为什么在程序中最后1位的停止位需要延时半个周期而不是一个完整的周期?也就是发送模块的如下程序:

always@(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)tx_flag <= 1'b0;else if(en_flag == 1'b1)tx_flag <= 1'b1;else if((tx_cnt == 4'd9) && (clk_cnt == bps_cnt/2 - 1))//停止位只有半个波特率周期tx_flag <= 1'b0;else //tx_flag <= tx_flag; //tx_flag <= 1'b1;end

         首先延时半个周期是为了给下一帧数据接收时检测起始位留够时间,在数据回环过程中不会出现太大问题,但是如果单独调用串口的发送模块(或者接收模块)时就会出现问题,在单独调用发送模块时,因为停止位只有半个周期,所以发送1帧数据过程总会先于上位机正常接收而提前结束,造成错误。

        所以选择将停止位周期设置为1个时钟周期,但是实际上位机的波特率和实际计算的波特率仍有微小误差,在将停止位设置为1个时钟周期时,上位机(串口助手)的波特率实际会和自己设置的波特率(如9600,115200等)存在或多或少的误差,因此需要将停止位周期设置为1/2--1之间,和上位机什么时候检测到1帧数据的停止位有关。

另附加上视频中给出得数据环回模块的程序:

`timescale 1ns / 1ps
// Create Date: 2025/01/07 10:50:37
// Intrduction:  将串口接收到的数据进行缓存,消除上位机和串口模块之间的时间误差;
// Module Name: uart_loopmodule uart_loop(input              sys_clk    ,    //50Mhz系统时input              sys_rst_n  , input              recv_done  ,   //接收完成信号  input        [7:0] recv_data  ,   //接收到的数据                                             input              tx_busy    ,output  reg        send_en    ,   output  reg  [7:0] send_data     //待发送数据);reg    recv_done_d0  ;reg    recv_done_d1  ;reg    tx_ready      ;wire   recv_done_flag;  //捕获上升沿assign  recv_done_flag =  (~recv_done_d0) & recv_done_d1;//打两拍实现边沿检测always@(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)beginrecv_done_d0 <= 1'b0;recv_done_d1 <= 1'b0;endelse begin                    recv_done_d0 <= recv_done;recv_done_d1 <= recv_done_d0;end                                                    end//判断接收完成信号,并在串口发送模块空闲时发送是使能信号always@(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)begintx_ready  <= 1'b0;send_en   <= 1'b0;  send_data <= 8'd0;endelsebeginif(recv_done_flag)   begintx_ready  <= 1'b1;     send_en <= 1'b0;       send_data <= recv_data;                      end     else if(tx_ready&&(~tx_busy))begintx_ready <= 1'b0;send_en  <= 1'b1;endendend   endmodule

再者,vivado中串口默认波特率115200bps,在调试过程需要注意,如哦需要修改可参考下链接:

 https://zhuanlan.zhihu.com/p/633150036

相关文章:

ZYNQ初识10(zynq_7010)UART通信实验

基于bi站正点原子讲解视频&#xff1a; 系统框图&#xff08;基于串口的数据回环&#xff09;如下&#xff1a; 以下&#xff0c;是串口接收端的波形图&#xff0c;系统时钟和波特率时钟不同&#xff0c;为异步时钟&#xff0c;&#xff0c;需要先延时两拍&#xff0c;将时钟同…...

专题 - STM32

基础 基础知识 STM所有产品线&#xff08;列举型号&#xff09;&#xff1a; STM产品的3内核架构&#xff08;列举ARM芯片架构&#xff09;&#xff1a; STM32的3开发方式&#xff1a; STM32的5开发工具和套件&#xff1a; 若要在电脑上直接硬件级调试STM32设备&#xff0c;则…...

2 XDMA IP中断

三种中断 1. Legacy 定义&#xff1a;Legacy 中断是传统的中断处理方式&#xff0c;使用物理中断线&#xff08;例如 IRQ&#xff09;来传递中断信号。缺点&#xff1a; 中断线数量有限&#xff0c;通常为 16 条&#xff0c;限制了可连接设备的数量。中断处理可能会导致中断风…...

自然语言转 SQL:通过 One API 将 llama3 模型部署在 Bytebase SQL 编辑器

使用 Open AI 兼容的 API&#xff0c;可以在 Bytebase SQL 编辑器中使用自然语言查询数据库。 出于数据安全的考虑&#xff0c;私有部署大语言模型是一个较好的选择 – 本文选择功能强大的开源模型 llama3。 由于 OpenAI 默认阻止出站流量&#xff0c;为了简化网络配置&#…...

抖音矩阵是什么

抖音矩阵是指在同一品牌或个人IP下&#xff0c;通过创建多个不同定位的抖音账号&#xff08;如主号、副号、子号等&#xff09;&#xff0c;形成一个有机的整体&#xff0c;以实现多维度、多层次的内容覆盖和用户互动。以下是关于抖音矩阵的详细介绍&#xff1a; 抖音矩阵的类…...

怎么抓取ios 移动app的https请求?

怎么抓取IOS应用程序里面的https&#xff1f; 这个涉及到2个问题 1.电脑怎么抓到IOS手机流量&#xff1f; 2.HTTPS怎么解密&#xff1f; 部分app可以使用代理抓包的方式&#xff0c;但是正式点的app用代理抓包是抓不到的&#xff0c;例如pin检测&#xff0c;证书双向校验等…...

pyqt鸟瞰

QApplication‌是Qt框架中的一个类&#xff0c;专门用于管理基于QWidget的图形用户界面&#xff08;GUI&#xff09;应用程序的控制流和主要设置。QApplication类继承自QGuiApplication&#xff0c;提供了许多与GUI相关的功能&#xff0c;如窗口系统集成、事件处理等。 QAppli…...

【Docker】入门教程

目录 一、Docker的安装 二、Docker的命令 Docker命令实验 1.下载镜像 2.启动容器 3.修改页面 4.保存镜像 5.分享社区 三、Docker存储 1.目录挂载 2.卷映射 四、Docker网络 1.容器间相互访问 2.Redis主从同步集群 3.启动MySQL 五、Docker Compose 1.命令式安装 …...

Token和JWT的关系详细讲解

Token 和 JSON Web Token (JWT) 是两个相关但概念上不同的术语&#xff0c;它们在现代 Web 应用程序的身份验证和授权中扮演着重要角色。下面将详细介绍两者之间的关系以及 JWT 的具体工作原理。 1. Token 概述 Token 是一种广义的概念&#xff0c;指的是任何可以证明用户身份…...

【Linux系列】Curl 参数详解与实践应用

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

解决 Git SSL 连接错误:OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno

问题描述 在执行 git pull 命令时遇到以下错误&#xff1a; > git pull --tags origin main fatal: unable to access github仓库: OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 0这个错误通常表示 Git 在尝试通过 HTTPS 连接到 GitHub 时遇到了 SSL 连接问题。 解决方案…...

《Vue3 八》<script setup> 语法

<script setup> 是在单文件中使用 Composition API 的编译时语法糖&#xff0c;里面的代码会被编译成组件 setup() 函数的内容。 <script setup> 中的代码在每次组件实例被创建的时候都都会被执行。 定义数据&#xff1a; 在 <script setup> 语法糖的写法中…...

51单片机和STM32集成蓝牙模块实用指南

51单片机和STM32集成蓝牙模块实用指南 蓝牙模块&#xff08;如HC-05、HC-06、JDY-31等&#xff09;是嵌入式开发中常用的无线通信模块&#xff0c;广泛应用于智能家居、物联网、机器人等领域。本文将详细介绍如何将蓝牙模块集成到 51单片机 和 STM32 中&#xff0c;并提供一个…...

Transformer:深度学习的变革力量

深度学习领域的发展日新月异&#xff0c;在自然语言处理&#xff08;NLP&#xff09;、计算机视觉等领域取得了巨大突破。然而&#xff0c;早期的循环神经网络&#xff08;RNN&#xff09;在处理长序列时面临着梯度消失、并行计算能力不足等瓶颈。而 Transformer 的横空出世&am…...

sql 函数

# 四则运算 - * / # 函数 distinct 、count、sum、max、min、avg、sum、round select concat(device_id 是,device_id ) device_id from device_id_apply_factor where device_id D6A42CE6A0; select concat_ws(|||,device_id ,factor_a ,module_type) from 、device_id_app…...

C# OpenCV机器视觉:OCR产品序列号识别

在一个看似平常却又暗藏玄机的工作日&#xff0c;阿明正坐在办公室里&#xff0c;对着堆积如山的文件唉声叹气。突然&#xff0c;电话铃声如炸雷般响起&#xff0c;吓得他差点从椅子上摔下来。原来是公司老板打来的紧急电话&#xff1a;“阿明啊&#xff0c;咱们刚生产出来的那…...

2012wtl,学习活扩

原文 WTL学习注意–活扩 在Win32下,活扩控件已是个成熟的概念了,即使对COM不太了解,使用活扩控件仍是件容易的事情.既然是控件,无非要关注两个方面,第一是如何调用它的函数,其次是如何接收它的事件. 看看在WTL中,如何使用活扩控件(基本对话框): 1.创建项目时,让对话框支持活…...

使用Deepseek搭建类Cursor编辑器

使用Deepseek搭建类Cursor编辑器 Cursor想必大家都用过了&#xff0c;一个非常强大的AI编辑器&#xff0c;在代码编写上为我们省了不少事&#xff0c;但高昂的价格让我们望而却步&#xff0c;这篇文章教你在Visual Studio Code上搭建一个类Cursor的代码编辑器。 步骤其实非常…...

mysql,PostgreSQL,Oracle数据库sql的细微差异(2) [whith as; group by; 日期引用]

sql示例(MySQL) WITHtemp1 AS (SELECT name AS resultsFROM Users uJOIN MovieRating m ON u.user_id m.user_idGROUP BY m.user_idORDER BY COUNT(*) DESC,left(name,1)LIMIT 1),temp2 AS (SELECT title AS resultsFROM Movies mJOIN MovieRating r ON m.movie_id r.movie_…...

基于改进粒子群优化的无人机最优能耗路径规划

目录 1. Introduction2. Preliminaries2.1. Particle Swarm Optimization Algorithm2.2. Deep Deterministic Policy Gradient2.3. Calculation of the Total Output Power of the Quadcopter Battery 3.OptimalEnergyConsumptionPathPlanningBasedonPSO-DDPG3.1.ProblemModell…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...

现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

现有的 Redis 分布式锁库&#xff08;如 Redisson&#xff09;相比于开发者自己基于 Redis 命令&#xff08;如 SETNX, EXPIRE, DEL&#xff09;手动实现分布式锁&#xff0c;提供了巨大的便利性和健壮性。主要体现在以下几个方面&#xff1a; 原子性保证 (Atomicity)&#xff…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

作为测试我们应该关注redis哪些方面

1、功能测试 数据结构操作&#xff1a;验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化&#xff1a;测试aof和aof持久化机制&#xff0c;确保数据在开启后正确恢复。 事务&#xff1a;检查事务的原子性和回滚机制。 发布订阅&#xff1a;确保消息正确传递。 2、性…...

API网关Kong的鉴权与限流:高并发场景下的核心实践

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中&#xff0c;API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关&#xff0c;Kong凭借其插件化架构…...

在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/v2@v2.2.0 更换为 go-ansible/@v1.1.7

在 Go 项目中降级 go-ansible 从 v2.2.0 到 v1.1.7 具体步骤&#xff1a; 第一步&#xff1a; 修改 go.mod 文件 // 原 v2 版本声明 require github.com/apenella/go-ansible/v2 v2.2.0 替换为&#xff1a; // 改为 v…...

书籍“之“字形打印矩阵(8)0609

题目 给定一个矩阵matrix&#xff0c;按照"之"字形的方式打印这个矩阵&#xff0c;例如&#xff1a; 1 2 3 4 5 6 7 8 9 10 11 12 ”之“字形打印的结果为&#xff1a;1&#xff0c;…...