AG32( MCU + FPGA)实现多串口(15个UART)的应用

AG32 的引脚定义

AG32只有模拟相关的IO是固定的,其它数字IO接口可以任意分配。

QFN-32Pin nameAG32VFxxxKAGRV2KQ32
1PIN_1IO/RTCIO_GB
2PIN_2IO/OSC_INIO
3PIN_3IO/OSC_OUTIO
4NRSTNRSTNRST
5PIN_5IO_ADC_IN12IO
6VDDA33VDDA33VDDA33
7PIN_7IO_WKUP_ADC_IN0_CMP_PA0IO
8PIN_8IO_ADC_IN1_CMP_PA1IO
9PIN_9IO_ADC_IN2_CMP_PA2IO
10PIN_10IO_ADC_IN3_CMP_PA3IO
11PIN_11IO_ADC_IN4_CMP_PA4_DAC0IO
12PIN_12IO_ADC_IN5_CMP_PA5_DAC1IO
13PIN_13IO_ADC_IN6IO
14PIN_14IO_ADC_IN7IO
15PIN_15IO_BOOT1IO
16VDD33VDD33VDD33
17GNDGNDGND
18PIN_18IOIO
19PIN_19IOIO
20PIN_20IO_UART0_TXIO
21PIN_21IO_UART0_RXIO
22PIN_22IO_USBDMIO
23PIN_23IO_USBDPIO
24PIN_24IO_JTMSJTMS
25PIN_25IO_JTCKJTCK
26PIN_26IO_JTDIIO
27PIN_27IO_JTDOIO
28PIN_28IO_JNTRSTIO
29PIN_29IOIO
30BOOT0BOOT0GND
31PIN_31IOIO
32VDD33VDD33VDD33
 website:www.hizyuan.com 

AG32VF407VGT6  LQFP100封装,有5个UART。除了MCU本身带的5个UART,需要更多就用内部FPGA编程实现。

目前我们可以提供新的多串口参考设计,用FPGA逻辑实现了10个,MCU自带5个。总共可以实现15个串口UART通信。

Logic设计相关的参考设计:

multi_uart.v 参考代码:

uart_tx #(DATA_WIDTH, FIFO_DEPTH) u_tx[CNT-1:0](
  .clk        (apb_clock                 ),
  .rstn       (apb_resetn                ),
  .baud16     (baud16                    ),
  .tx_write   (tx_write                  ),
  .tx_data    (apb_pwdata[DATA_WIDTH-1:0]),
  .lcr_sps    (lcr_sps                   ),
  .lcr_stp2   (lcr_stp2                  ),
  .lcr_eps    (lcr_eps                   ),
  .lcr_pen    (lcr_pen                   ),
  .tx_clear   (clear_flags               ),
  .tx_full    (tx_full                   ),
  .tx_empty   (tx_empty                  ),
  .tx_busy    (tx_busy                   ),
  .tx_complete(tx_complete               ),
  .tx_dma_en  (tx_dma_en                 ),
  .tx_dma_clr (tx_dma_clr                ),
  .tx_dma_req (tx_dma_req                ),
  .uart_txd   (uart_txd                  )
);

uart_rx #(DATA_WIDTH, FIFO_DEPTH) u_rx[CNT-1:0](
  .clk          (apb_clock    ),
  .rstn         (apb_resetn   ),
  .baud16       (baud16       ),
  .lcr_sps      (lcr_sps      ),
  .lcr_stp2     (lcr_stp2     ),
  .lcr_eps      (lcr_eps      ),
  .lcr_pen      (lcr_pen      ),
  .rx_read      (rx_read      ),
  .rx_clear     (clear_flags  ),
  .rx_full      (rx_full      ),
  .rx_empty     (rx_empty     ),
  .rx_data      (rx_data      ),
  .rx_idle      (rx_idle      ),
  .framing_error(framing_error),
  .parity_error (parity_error ),
  .break_error  (break_error  ),
  .overrun_error(overrun_error),
  .rx_dma_en    (rx_dma_en    ),
  .rx_dma_clr   (rx_dma_clr   ),
  .rx_dma_req   (rx_dma_req   ),
  .uart_rxd     (uart_rxd     )
);
endmodule

uart_rx.v 参考代码:

module uart_rx #(parameter DATA_WIDTH = 8, FIFO_DEPTH = 4) (
  input                       clk,
  input                       rstn,
  input                       baud16,
  input                       uart_rxd,
  input                       lcr_sps,
  input                       lcr_stp2,
  input                       lcr_eps,
  input                       lcr_pen,
  input                       rx_read,
  input                       rx_clear,
  output                      rx_full,
  output                      rx_empty,
  output     [DATA_WIDTH-1:0] rx_data,
  output reg                  rx_idle,
  input                       rx_dma_en,
  input                       rx_dma_clr,
  output reg                  rx_dma_req,
  output reg                  framing_error,
  output reg                  parity_error,
  output reg                  break_error,
  output reg                  overrun_error
);
parameter UART_IDLE   = 3'h0;
parameter UART_START  = 3'h1;
parameter UART_DATA   = 3'h2;
parameter UART_PARITY = 3'h3;
parameter UART_STOP   = 3'h4;

parameter BAUD_CNT = 16;
parameter SAMPLE_CNT = 3;

reg [2:0] rx_state;

reg [SAMPLE_CNT+1:0] rx_in; // 2 extra bits for synchronization
reg [1:0] rx_val;
reg [3:0] rx_baud_cnt;
reg rx_bit;
reg rx_parity;
reg [$clog2(DATA_WIDTH):0] rx_data_cnt;
reg [DATA_WIDTH-1:0] rx_shift_reg;
reg rx_idle_en;

wire rx_lo = rx_val <= 1;
wire rx_hi = !rx_lo;
wire rx_sample = baud16 && rx_baud_cnt == BAUD_CNT / 2 + 1; // Where to sample rx input

wire fifo_wren = rx_state == UART_STOP && rx_sample;

sync_fifo #(.WIDTH(DATA_WIDTH), .DEPTH(FIFO_DEPTH), .SHOWAEAD(1)) rx_fifo(
  .clk  (clk         ),
  .rstn (rstn        ),
  .wren (fifo_wren   ),
  .rden (rx_read     ),
  .din  (rx_shift_reg),
  .dout (rx_data     ),
  .full (rx_full     ),
  .empty(rx_empty    )
);

always @(posedge clk or negedge rstn) begin
  if (!rstn) begin
    rx_in <= {SAMPLE_CNT+1{1'b1}};
  end else if (baud16) begin
    rx_in <= { rx_in[SAMPLE_CNT:0], uart_rxd };
  end
end

integer i;
always @(*) begin
  rx_val = 0;
  for (i = 2; i < SAMPLE_CNT + 2; i = i + 1)
    rx_val = rx_val + rx_in[i];
end

always @(posedge clk or negedge rstn) begin
  if (!rstn) begin
    rx_bit <= 1'b0;
  end else if (baud16 && rx_baud_cnt == 15) begin
    rx_bit <= 1'b1;
  end else begin
    rx_bit <= 1'b0;
  end
end

always @(posedge clk) begin
  if (rx_state == UART_START) begin
    rx_data_cnt <= DATA_WIDTH - 1;
  end else if (rx_bit) begin
    if (rx_state == UART_DATA && rx_data_cnt == 0) begin
      rx_data_cnt <= DATA_WIDTH + 1 + lcr_pen + lcr_stp2;
    end else begin
      rx_data_cnt <= rx_data_cnt - 1;
    end
  end
end

always @(posedge clk or negedge rstn) begin
  if (!rstn) begin
    rx_shift_reg <= 0;
  end else if (rx_state == UART_DATA && rx_sample) begin
    rx_shift_reg <= { rx_hi, rx_shift_reg[DATA_WIDTH-1:1] };
  end
end

always @(posedge clk) begin
  if (rx_state == UART_START) begin
    rx_parity <= !lcr_eps;
  end else if (rx_state == UART_DATA && rx_bit && !lcr_sps) begin
    rx_parity <= rx_parity ^ rx_shift_reg[7];
  end
end

always @(posedge clk or negedge rstn) begin
  if (!rstn) begin
    rx_baud_cnt <= 0;
  end else if (rx_state == UART_IDLE && rx_lo) begin
    rx_baud_cnt <= SAMPLE_CNT - 1;
  end else if (baud16) begin
    rx_baud_cnt <= rx_baud_cnt + 1;
  end
end

always @(posedge clk or negedge rstn) begin
  if (!rstn) begin
    rx_idle_en <= 1'b0;
  end else if (!rx_empty) begin
    rx_idle_en <= 1'b1;
  end else if (rx_clear) begin
    rx_idle_en <= 1'b0;
  end
end

always @(posedge clk or negedge rstn) begin
  if (!rstn) begin
    rx_idle <= 1'b0;
  end else if (rx_state == UART_IDLE && rx_data_cnt == 0 && rx_bit && rx_idle_en) begin
    rx_idle <= 1'b1;
  end else if (rx_clear) begin
    rx_idle <= 1'b0;
  end
end

always @(posedge clk or negedge rstn) begin
  if (!rstn) begin
    framing_error <= 1'b0;
  end else if (rx_state == UART_STOP && rx_sample && rx_lo) begin
    framing_error <= 1'b1;
  end else if (rx_clear) begin
    framing_error <= 1'b0;
  end
end

always @(posedge clk or negedge rstn) begin
  if (!rstn) begin
    parity_error <= 1'b0;
  end else if (rx_state == UART_PARITY && rx_sample && rx_parity != rx_hi) begin
    parity_error <= 1'b1;
  end else if (rx_clear) begin
    parity_error <= 1'b0;
  end
end

always @(posedge clk or negedge rstn) begin
  if (!rstn) begin
    break_error <= 1'b0;
  end else if (rx_state == UART_STOP && rx_sample && rx_lo && rx_shift_reg == 0) begin
    break_error <= 1'b1;
  end else if (rx_clear) begin
    break_error <= 1'b0;
  end
end

always @(posedge clk or negedge rstn) begin
  if (!rstn) begin
    overrun_error <= 1'b0;
  end else if (fifo_wren && rx_full) begin
    overrun_error <= 1'b1;
  end else if (rx_clear) begin
    overrun_error <= 1'b0;
  end
end

always @(posedge clk or negedge rstn) begin
  if (!rstn) begin
    rx_dma_req <= 1'b0;
  end else if (!rx_dma_en || rx_dma_clr) begin
    rx_dma_req <= 1'b0;
  end else if (!rx_empty) begin
    rx_dma_req <= 1'b1;
  end
end

always @(posedge clk or negedge rstn) begin
  if (!rstn) begin
    rx_state <= UART_IDLE;
  end else begin
    case (rx_state)
      UART_IDLE:   if (rx_lo)  rx_state <= UART_START;
      UART_START:  if (rx_bit && rx_baud_cnt == 0) rx_state <= UART_DATA;
      UART_DATA:   if (rx_bit && rx_data_cnt == 0) rx_state <= lcr_pen ? UART_PARITY : UART_STOP;
      UART_PARITY: if (rx_bit) rx_state <= UART_STOP;
      UART_STOP:   if (rx_sample && rx_hi) rx_state <= UART_IDLE;
    endcase
  end
end

endmodule
 

更多参考设计,欢迎私信交流沟通。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CSS基础知识六(浮动的高度塌陷问题及解决方案)

目录 1.浮动高度塌陷概念 2.下面是几种解决高度塌陷的几种方案&#xff1a; 解决方案一&#xff1a; 解决方案二&#xff1a; 解决方案三&#xff1a; 1.浮动高度塌陷概念 在CSS中&#xff0c;高度塌陷问题指的是父元素没有正确地根据其内部的浮动元素或绝对定位元素来计…

014:无人机遥控器操作

摘要&#xff1a;本文详细介绍了无人机遥控器及其相关操作。首先&#xff0c;解释了油门、升降舵、方向舵和副翼的概念、功能及操作方式&#xff0c;这些是控制无人机飞行姿态的关键部件。其次&#xff0c;介绍了美国手、日本手和中国手三种不同的操作模式&#xff0c;阐述了遥…

GitHub | 发布到GitHub仓库并联文件夹的方式

推送到Github 推送步骤如果你只想更新单个文件&#xff0c;只需在第 4 步中指定该文件的路径即可。可能问题一 效果 推送步骤 更新 GitHub 仓库中的文件通常涉及以下步骤&#xff1a; 克隆仓库&#xff1a; 首先&#xff0c;你需要将 GitHub 上的仓库克隆到本地。使用 git …

qt QCloseEvent详解

1、概述 QCloseEvent 是 Qt 框架中用于处理窗口关闭事件的一个类。当用户尝试关闭一个窗口&#xff08;例如&#xff0c;通过点击窗口的关闭按钮&#xff0c;或者通过调用窗口的 close() 方法&#xff09;时&#xff0c;Qt 会生成一个 QCloseEvent 对象&#xff0c;并将其发送…

《JVM第5课》虚拟机栈

无痛快速学习入门JVM&#xff0c;欢迎订阅本免费专栏 Java虚拟机栈&#xff08;Java Virtual Machine Stack&#xff0c;简称JVM栈&#xff0c;又称Java方法栈&#xff09;是 JVM 运行时数据区的一部分&#xff0c;主要用于支持Java方法的执行。每当一个新线程被创建时&#xf…

数据迁移: 安全高效转移数据, 满足企业业务需求和技术改进

天津鸿萌科贸发展有限公司从事数据安全服务二十余年&#xff0c;致力于为各领域客户提供专业的数据存储、数据恢复、数据备份、数据迁移等解决方案与服务&#xff0c;并针对企业面临的数据安全风险&#xff0c;提供专业的相关数据安全培训。 鸿萌数据迁移业务为众多企业顺利高效…

w~自动驾驶~合集4

我自己的原文哦~ https://blog.51cto.com/whaosoft/12451789 #基于深度学习的端到端自动驾驶 最新的端到端自动驾驶综述刚刚出炉&#xff0c;话说论文一作卡内基梅隆大学的Apoorv Singh今年产出了七篇综述&#xff0c;都和自动驾驶相关&#xff0c;推荐给大家。就一个字&…

【解决办法】无法使用右键“通过VSCode打开文件夹”

个人博客&#xff1a;苏三有春的博客 前言 作者的编程环境为VScode&#xff0c;工作时常使用VScode打开整个工程文件夹。如果先打开VScode再从VScode中选择文件夹打开效率太慢&#xff0c;作者一般使用的方式是右键文件夹&#xff0c;直接选择"通过code打开文件夹"…

ubuntu20.04 加固方案-设置限制su命令用户组

一、编辑/etc/pam.d/su配置文件 打开终端。 使用文本编辑器&#xff08;如vim&#xff09;编辑/etc/pam.d/su文件。 vim /etc/pam.d/su 二、添加配置参数 在打开的配置文件的中&#xff0c;添加以下参数&#xff1a; auth required pam_wheel.so 创建 wheel 组 并添加用户 …

MySQL之JDBC入门详解

01-JDBC入门 一、JDBC概念 jdbc : java database connection , java数据库连接 jdbc是sun公司定义的java程序访问数据库的规范。 二、JDBC操作需要6步 三、入门程序 1、使用eclipse打开一个新的工作空间 2、切换到java视图界面 3、创建java工程&#xff1a;01-jdbc-helloworl…

Ansible常用命令(Ansible Common Commands)

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

wpf 制作丝滑Flyout浮出侧边栏Demo (Mahapps UI框架)

Flyout 属性 CloseButtonVisibility: 设置为 Collapsed&#xff0c;意味着关闭按钮不可见。TitleVisibility: 设置为 Collapsed&#xff0c;意味着标题不可见。IsPinned: 设置为 True&#xff0c;意味着这个 Flyout 会固定住&#xff0c;不会自动关闭。Opacity: 设置为 1&…

微服务系列二:跨微服务请求优化,注册中心+OpenFeign

目录 前言 一、纯 RestTemplate 方案存在的缺陷 二、注册中心模式介绍 三、注册中心技术&#xff1a;Nacos 3.1 Docker部署Nacos 3.2 服务注册 3.3 服务发现 四、代码优化&#xff1a;OpenFeign工具 4.1 OpenFeign快速入门 4.2 连接池的必要性 4.3 抽取服务、最佳实…

Android音频进阶之PCM设备创建(九十三)

简介: CSDN博客专家、《Android系统多媒体进阶实战》一书作者 新书发布:《Android系统多媒体进阶实战》🚀 优质专栏: Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏: 多媒体系统工程师系列【原创干货持续更新中……】🚀 优质视频课程:AAOS车载系统+…

自定义规则配置教程

大家在使用waf的时候&#xff0c;因为业务特殊性和waf的严格校验&#xff0c;有时会产生误报&#xff0c;阻拦合法流量。 这个时候&#xff0c;只能通过自定义规则进行补充&#xff0c;选择加白名单或者黑名单。 很多人会说配置黑白名单失效了&#xff0c;其实95%以上都是自己…

HTML 文档规范与解析模式:DOCTYPE、<html> 标签以及结构化页面

文章目录 `<!DOCTYPE html>` 文档类型声明标准模式与怪异模式HTML5 的简化声明`<html>` 标签`<head>` 标签`<body>` 标签小结<!DOCTYPE html> 文档类型声明 在 HTML 文档中,<!DOCTYPE html> 是一个重要的文档类型声明,主要用于告知浏览…

双分解+一区极光优化+Transformer!CEEMDAN-Kmeans-VMD-PLO-Transformer多元时序预测

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现CEEMDAN-Kmeans-VMD-PLO-Transformer融合K均值聚类的数据双重分解极光优化Transformer多元时间序列预测&#xff08;完整源码和数据&#xff09; 2.CEEMDAN分解&#xff0c;计算样本熵&#xff0c;根据样…

MATLAB绘图基础10:MATLAB极坐标相关图形

参考书&#xff1a;《 M A T L A B {\rm MATLAB} MATLAB与学术图表绘制》(关东升)。 10.MATLAB极坐标相关图形 10.1 极坐标图 极坐标图是在极坐标系下绘制数据的图形&#xff0c;极坐标系以中心为原点&#xff0c;使用角度和半径表示数据点的位置&#xff1b; 极坐标图适用于…

IDEA加载通义灵码插件及使用指南

安装通义灵码插件 登录通义灵码IDE插件 下载登录参考教程 https://help.aliyun.com/zh/lingma/user-guide/download-the-installation-guide 本地工程和企业知识库准备 请下载本地工程和知识库压缩包&#xff0c;并在本地解压缩&#xff0c;其中包含demoProject和知识库文件…

【VScode】VScode内的ChatGPT插件——CodeMoss全解析与实用教程

在当今快速发展的编程世界中&#xff0c;开发者们面临着越来越多的挑战。如何提高编程效率&#xff0c;如何快速获取解决方案&#xff0c;成为了每位开发者心中的疑问。今天&#xff0c;我们将深入探讨一款颠覆传统编程体验的插件——CodeMoss&#xff0c;它将ChatGPT的强大功能…