AG32:MCU和CPLD如何交互?

 

本文档介绍了AG32开发中,MCU与CPLD交互的具体方式以及例子。如需了解AG32更多资料可发邮件:sales@agm-micro.com

一、MCU和CPLD直接交互

cpld工程创建及编译的操作流程,参考文档《AG32下fpga和cpld的使用入门》

在工程中,用户逻辑部分编写是从analog_ip.v的接口下开始的。

mcu和cpld之间的交互,可以分为:

1. mcu传递信号给cpld;(如mcu的gpio传递高低信号到cpld)

2. cpld传递信号给mcu;(如:对mcu产生中断信号)

3. mcu读写数据到cpld;

4. 不建议,cpld做为主设备对mcu写。

也就是说,在mcu和cpld交互中,cpld更像一个外设。

其中,前两种较为简单。后两种要使用AHB总线来操作。

下边针对四种情况分别说明:

1. mcu传递信号给cpld

这种使用较简单。步骤如下:

在ve中定义信号:

GPIO4_1
iocvt_chn:OUTPUT

表示,用mcu的gpio(gpio4_1)来输入信号到cpld。

然后,prepare LOGIC工程后,可以看到analog_ip.v接口中的信号:

input             iocvt_chn_out_data,

input             iocvt_chn_out_en,

这里的iocvt_chn_out_data,就是对接到mcu的gpio4_1的信号。

当控制mcu的gpio4_1高低切换时,cpld中的iocvt_chn_out_data,会对应来变化。

具体样例,可以参考网盘“logic样例3.mcu信号到cpld到pin”的样例,该样例中,展示了mcu控制cpld继续控制led的过程。

除了gpio信号输出到cpld,其他比如pwm输出信号等,都可以输入到cpld。

2. cpld传递信号给mcu

这种方式和1相近,只不过是反向。

可以在mcu中定义gpio4_2为输入并使能中断,则cpld中设置信号高低时,将触发 mcu的中断。

在VE中定义信号:

GPIO4_2
iocvt_chn:INPUT

表示,用mcu的gpio(gpio4_2)信号来源于cpld的iocvt_chn。

然后,prepare LOGIC工程后,可以看到analog_ip.v接口中的信号:

output             iocvt_chn_in_data,

这里的iocvt_chn_in_data,就是对接到mcu的gpio4_2的信号。

当cpld中控制iocvt_chn_in_data信号高低时,mcu中的gpio4_2对应变化。

这里不再举例。

3. mcu读写数据到cpld

在地址设计中,cpld的地址区间是:0x60000000 ~
0x7FFFFFFF

当mcu对这个区间内的地址访问时,相当于访问了cpld的“寄存器”。

mcu是全局寻址,对这个空间的访问和对ram(0x20000000起)空间的访问是一样的方式,在C代码中,可以这样写:

读cpld:int cpRdReg = *((int *)0x60000000);

写cpld:*((int *)0x60000004) = cpWtReg;

Mcu端读写cpld较为简单,直接通过上述语句就可以了。

当mcu读写动作发生时,cpld端是如何反应的?

当上述mcu读写动作发生时,AHB总线会把动作拆解为读写信号,传递到analog_ip.v的接口,用户cpld程序需要响应该信号。

以下,以写动作 *((int *)0x60000004) = cpWtReg 为例,描述cpld端会发生的事情。

回顾下analog_ip.v中的接口部分:

其中slave_ahb_开头的一组信号,是cpld作为主端时用的,暂时不用理会。

Mem_ahb_开头的一组信号,是cpld作为从端使用的。

当mcu有读写操作时,mem_ahb_这组信号将发生变化。

这部分是遵循标准的AHB总线协议的。如果对AHB总线印象不深,请自行百度。

可参考的讲解:

https://blog.csdn.net/weixin_46022434/article/details/104987905

几个信号的概述(更详细的讲解请自行百度):

Ahb_htrans: 当前传输类型(00: IDLE、01: BUSY、10: NONSEQ、11: SEQ)

Ahb_ready:mcu读时要mcu要准备好cpld才会写

Ahb_hwrite: 要读还是要写(1为写,0为读)

Ahb_haddr[32]: 要操作的地址

Ahb_hsize:transfer的大小,以字节为单位

Ahb_hburst:批量传输

Ahb_hwdata[32]:写的数据,32位

Ahb_hreadyout:输出信号,mcu写时cpld是否准备好

Ahb_hresp:输出信号,响应信号(OK、retry、error、split)

Ahb_hrdata[32]:读的数据,32位

根据AHB时序,在一次传输中,cpld(slave端)会先拿到addr地址,读或写的标记,然后交互ready信号后,开始数据传输。

大致如下图(无等待类型的图):

比如,mcu要读0x60000004的寄存器:

mcu端直接C语言这样调用:int cpRdReg = *((int
*)0x60000004);

cpld端,可以根据以上信号做如下处理:

----------------------------------------------

//mcu的读操作响应

//mcu端用C语言:int value = *((int *)0x60000004);

reg [31:0] hrdata_reg;        //定义32位的hrdata_reg

always @(posedge sys_clock) begin        //clk上升沿触发

if (mem_ahb_htrans ==
2'b10 &&           //NONSEQ
状态,第一次传输

  mem_ahb_hready &&                           //master已ready,可以给数据线写入了

  !mem_ahb_hwrite &&                 //(0 读,1 写)

  mem_ahb_haddr[23:0] == 'h04)         //读地址为0x60000004(cpld用相对偏移)

begin

hrdata_reg <=
hwdata_reg;              //
把另一准备好的数据给到hrdata_reg

end

end

assign mem_ahb_hrdata = hrdata_reg;//绑定hrdata_reg到读的数据线上

-----------------------------------------------

以上代码,加入到analog_ip.v的module下,就可以完成cpld对mcu读动作的响应。

比如,mcu要写0x60000000的寄存器:

mcu端直接C语言这样调用:*((int *)0x60000000)
= value;

cpld端,可以根据以上信号做如下处理:

----------------------------------------------

//mcu的写操作响应

//mcu端用C语言:*((int *)0x60000000) = value;

reg [31:0] hwdata_reg;       //定义32位的hwdata_reg

always @(posedge sys_clock) begin        //clk上升沿触发

if (mem_ahb_htrans ==
2'b00 &&         //IDLE
状态

  mem_ahb_hreadyout &&                    //cpld已ready状态,ahb上数据可以写过来

  mem_ahb_hwrite &&                  //(0 读,1 写)

  mem_ahb_haddr[23:0] == 'h00)         //写地址为0x60000000(cpld用相对偏移)

begin

hwdata_reg <=
mem_ahb_hwdata;         //
把收到的数据给到hwdata_reg

end

end

//这个过程,是把mcu写进来的数据收到hwdata_reg

-----------------------------------------------

这部分的实例代码,请参考网盘上cpld样例工程《5.mcu读写cpld寄存器》。

注意:这里展示的,仅仅是基于AHB总线上的数据交互。

在实际应用中,比如要实现一个串口之类的,往往是慢速设备,这些是要挂载到apb上的。慢速设备要经过ahb到apb的bridge,才能最终使用。请继续往下看。

二、mcu通过ahb转apb后的数据交互

上节讲述了mcu和cpld之间交互数据的实现方式。

但数据是在ahb层面的响应,慢速设备不能直接使用。

慢速设备需要ahb转为apb后,使用apb的信号来交互。这种情况,转变为mcu和apb之间的交互。

mcu和apb之间的交互,相比mcu和aph之间的交互,多了一层ahb到apb的转换。这个转换是借助于ahb2apb.v模块来实现的(在example/analog下找该.v文件)。

该模块:输入是ahb的一组信号,输出是apb的一组信号。使用如下图:

如果实现mcu和apb的交互,则需要操作的是转换后的这组apb信号。

关于apb总线的使用,更多信息请自行百度。

这里只是简述下apb信号列表(与ahb略有不同):

apb_psel:片选

apb_penable:表示传输进入第二周期(准备好了读/写)

apb_pwrite:传输方向(1-写;0-读)

apb_paddr[32]:地址总线,要操作的地址

apb_pwdata[32]:写的数据,32位

apb_prdata[32]:读的数据,32位

以下展示在apb下如何实现跟mcu的交互,仍以ahb的两个寄存器为例。

1. 首先需要增加ahb转apb的信号关联;

如上图。

Ahb2apb模块会把ahb信号转换为apb信号。接下来操作apb信号即可。

2. 在转换后的apb信号中,实现写和读的操作。

mcu读操作时:

比如,mcu要读0x60000004的寄存器:

mcu端直接C语言这样调用:int cpRdReg = *((int
*)0x60000004);

cpld端,可以根据以上信号做如下处理:

----------------------------------------------

//mcu的读操作响应

//mcu端用C语言:int value = *((int *)0x60000004);

reg [31:0] ardata_reg;       //定义32位的hrdata_reg

always @(posedge apb_clock) begin      //clk上升沿触发

if (!apb_pwrite
&&                             //
读 (0 读,1 写)

apb_penable
&&                                 //
是否准备好

apb_paddr[11:0]
== ‘h04)    //
读地址为0x60000004(cpld内部用相对偏移)

begin

ardata_reg <=
awdata_reg;              //
把另一准备好的数据给到hrdata_reg

end

end

assign apb_prdata = ardata_reg;//绑定hrdata_reg到读的数据线上

-----------------------------------------------

mcu写操作时:

比如,mcu要写0x60000000的寄存器:

mcu端直接C语言这样调用:*((int *)0x60000000)
= value;

cpld端,可以根据以上信号做如下处理:

----------------------------------------------

//mcu的写操作响应

//mcu端用C语言:*((int *)0x60000000) = value;

reg [31:0] awdata_reg;       //定义32位的hwdata_reg

always @(posedge apb_clock) begin      //clk上升沿触发

if (apb_pwrite
&&                              //
写 (0 读,1 写)

apb_penable
&&                                 //
是否准备好

apb_paddr[11:0]
== ‘h00)  //
写地址为0x60000000(cpld内部用相对偏移)

begin

awdata_reg <=
apb_pwdata;           //
把收到的数据给到hwdata_reg

end

end

//这个过程,是把mcu写进来的数据收到hwdata_reg

-----------------------------------------------

这个功能实现后,其实是个简单的“空外设”。可以用它做为实现复杂功能外设的基础。

这部分的实例代码,请参考网盘上cpld样例工程《5.mcu读写cpld寄存器》。

样例展示到这里,mcu和cpld的交互上:交互信号、跟ahb交互数据、跟apb交互数据,基本的交互通路已经建立。

接下来,用户根据自己的需求,在cpld中交互到数据后,编写自己需要的功能即可。

三、DMA在CPLD中的使用

cpld中实现DMA的逻辑:

1. MCU为master,cpld为slave,mcu对cpld的交互方式为存取寄存器的方式;

2. mcu中配置好DMA(读取cpld中准备好的数据);

3. cpld中准备好数据后,触发dma信号,dma自动搬运到mcu指定的ram;

4. 搬运一次后,dma给cpld一个clear信号,完成一次dma搬运;

5. 等到cpld中再次准备好数据,将再次触发dma信号,重复3和4;

对于cpld来说,mcu来读取数据和dma来读取数据,是一致的。

dma来读取时,只是每次读完后会多给cpld一个clear信号。

更多细节,请参考网盘上《7.cpld中配合实现mcu的dma读取》部分的样例。

在这个样例中,展示了两部分代码:

1. mcu中,配置dma读取;为了测试,mcu会在另一地址给cpld写数据;

2. cpld中,会对mcu写进来的数据缓存,缓存后触发dma的信号,让dma来读取数据。而dma从cpld里读取数据后会给cpld一个clear信号,标志一次dma交互完成。

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

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

相关文章

机器人轨迹跟踪控制——CLF-CBF-QP

本次使用MATLAB复现CLF-CBF-QP算法,以实现机器人轨迹跟踪同时保证安全性能 模型 使用自行车模型来进行模拟机器人的移动动态,具体的模型推导参考车辆运动学模型-自行车模型 采用偏差变量 p ~ = p − p r e f u ~ = u − u r e f \tilde{p} = p - p_{ref} \\ \tilde{u} = …

009_抽象类和接口

抽象类和接口 final关键字常量 单例模式&#xff08;设计模式&#xff09;枚举类抽象类抽象类的注意事项、特点使用抽象类的好处模版方法设计模式 接口接口的好处接口的注意事项 final关键字 final关键字是最终的意思&#xff0c;可以修饰类、方法、变量。 修饰类&#xff1a;…

新潮透明液体水珠水滴失真故障扭曲折射特效海报字体标题设计ps样机动作素材 Bubble Photoshop Templates

只需单击几下即可创建引人注目的视觉效果&#xff01;您需要做的就是将您的文本或图像放入智能对象中并应用作。 包中包含&#xff1a; 15 个静态 Photoshop 模板&#xff08;PS 2019 及更高版本&#xff09; 01-05 垂直布局 &#xff08;22504000&#xff09;06-10 水平布局…

Android DiaLog全屏设置,带有叉号的弹窗,这个弹窗分为两个部分,一个是主体,另一个是关闭部分。自定义布局弹窗

1.先上图。要实现的效果图。 2.这是我自己实现的效果图&#xff0c;是不是跟效果图一摸一样 来看看整体效果 3.我把自己实现的效果图的代码写出来。如下就是我的代码 3.1首先是MainActivity类 import androidx.appcompat.app.AppCompatActivity;import android.app.Alert…

NVR接入录像回放平台用EasyCVR打造地下车库安防:大型商居安全优选方案

一、背景分析 随着居民生活品质的提升&#xff0c;大型商业建筑和住宅小区纷纷配套建设地下停车库。但是地下车库盗窃、失火、恶意毁坏车辆、外部人员随意进出等事件频发&#xff0c;部署视频监控系统成为保障地下车库的安全关键举措。 目前&#xff0c;很多商业和住宅都会在…

阶段测试 【过程wp】

分享总结: 回顾起来,真的感慨很多呀。看着并不难啊,但难的是解题思维:如何判断该页面的关键点,快速地确定问题的核心,找到对应的解决方法。达到便捷、高效的得到结果。我们做了整整近七个半小时。在这个过程中,我发现自己的思维钝化,不太能自主高效地划分判断漏洞类型,…

【C++】<STL部分>:STL标准模板库概要

STL(standard template libaray-标准模板库)&#xff0c;是C标准库的重要组成部分&#xff0c;包含了很多常用的数据结构和算法。 在我们学习了模板的之后&#xff0c;再来看STL&#xff0c;就能知道它是C标准库中的模板类和模板函数的集合&#xff0c;作为可复用的库大大提高…

从传递函数到PID控制器

在过程控制中&#xff0c;按偏差的比例&#xff08;P&#xff0c;Proportional&#xff09;、积分&#xff08;I&#xff0c;Integral&#xff09;和微分&#xff08;D&#xff0c;Differential&#xff09;进行控制的PID控制器&#xff08;亦称PID调节器&#xff09;是应用最为…

【PVR Review】《A Review of Palmar Vein Recognition》

[1]张秀峰,牛选兵,王伟,等.掌静脉识别研究综述[J].大连民族大学学报,2020,22(01):33-37.DOI:10.13744/j.cnki.cn21-1431/g4.2020.01.007. 文章目录 1、背景2、手掌静脉识别方法2.1、传统手掌静脉图像识别方法2.2、基于深度学习的掌静脉图像识别 3、手掌静脉识别难点 1、背景 目…

vector复制耗时

CPP中的vector对象在传参给子函数时&#xff0c;如果直接传参&#xff0c;会造成复制给形参的额外耗时 如何解决这个问题呢&#xff1f; 这样定义局部函数 const vector <int>&vec可以保证传递vector对象时使用地址传递&#xff0c;并且使用const保证vector不被改变…

算法思想之双指针

文章目录 双指针字符串序列判定字符串所有整数最小和服务交换接口失败率分析分披萨最多团队 双指针 双指针是指在解决问题时使用两个指针&#xff0c;通常分别指向数组或字符串中的不同位置&#xff0c;通过移动这两个指针来解决问题的一种技巧。双指针技巧常用于解决数组、链…

学透Spring Boot — 018. 优雅支持多种响应格式

这是我的专栏《学透Spring Boot》的第18篇文章&#xff0c;想要更系统的学习Spring Boot&#xff0c;请访问我的专栏&#xff1a;学透 Spring Boot_postnull咖啡的博客-CSDN博客。 目录 返回不同格式的响应 Spring Boot的内容协商 控制器不用任何修改 启动内容协商配置 访…

ngx_os_init

定义在 src\os\unix\ngx_posix_init.c ngx_int_t ngx_os_init(ngx_log_t *log) {ngx_time_t *tp;ngx_uint_t n; #if (NGX_HAVE_LEVEL1_DCACHE_LINESIZE)long size; #endif#if (NGX_HAVE_OS_SPECIFIC_INIT)if (ngx_os_specific_init(log) ! NGX_OK) {return NGX_ERR…

深信服护网蓝初面试题

《网安面试指南》https://mp.weixin.qq.com/s/RIVYDmxI9g_TgGrpbdDKtA?token1860256701&langzh_CN 5000篇网安资料库https://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247486065&idx2&snb30ade8200e842743339d428f414475e&chksmc0e4732df793fa3bf39…

游戏引擎学习第206天

回顾并为当天的工作定下目标 接着回顾了前一天的进展。之前我们做了一些调试功能&#xff0c;并且已经完成了一些基础的工作&#xff0c;但是还有一些功能需要继续完善。其中一个目标是能够展示实体数据&#xff0c;以便在开发游戏逻辑系统时&#xff0c;可以清晰地查看和检查…

HTML 表单:构建交互式网页的关键元素

HTML 表单:构建交互式网页的关键元素 引言 HTML表单是构建交互式网页的核心组件之一,它允许用户与网站进行交互,提交信息、填写问卷或进行其他操作。本文将深入探讨HTML表单的基础知识、常用元素、表单验证以及如何优化表单设计,以提高用户体验和网站的可访问性。 HTML表…

Qt音频采集:QAudioInput详解与示例

1. 简介 QAudioInput是Qt Multimedia模块中用于音频采集的核心类&#xff0c;能够从麦克风等输入设备实时获取原始音频数据&#xff08;PCM格式&#xff09;。本文将通过原理讲解和代码示例&#xff0c;帮助开发者快速掌握音频采集的核心技术。 2. 核心功能 支持多种音频格式&…

下载安装Node.js及其他环境

提示&#xff1a;从Node版本降级到Vue项目运行 文章目录 下载Node.js环境配置配置环境变量 安装 cnpm&#xff08;我需要安装&#xff09;安装脚手架安装依赖安装淘宝镜像&#xff08;注意会更新&#xff09;cnpm vs npm 与新旧版本核心差异包管理器不同功能差异如何选择&#…

【后端】ORM / ODM

长期不定期更新&#xff0c;建议关注收藏点赞。 概述 ORM&#xff08;Object-Relational Mapping&#xff0c;对象关系映射&#xff09;&#xff1a;面向关系型数据库&#xff0c;ORM将对象映射到数据库的表和行&#xff08;例如MySQL、PostgreSQL&#xff09;。ODM&#xff0…

无限滚动(Infinite Scroll)页面谷歌不收录!必须改回分页吗?

近三年&#xff0c;全球超过58%的网站采用无限滚动设计&#xff08;数据来源&#xff1a;PageTraffic 2023&#xff09; 谷歌官方数据显示&#xff0c;动态加载内容的索引失败率高达73%&#xff08;Google Webmaster Report 2022&#xff09;&#xff0c;而采用纯无限滚动的页…