安路SparkRoad开发板测评(4) ADC IP的使用
<p> EG4S20内部带了一个ADC,需要以IP的形式调用。FPGA IP核就当作一个积木来用,和自己编写的逻辑连起来就是了。</p><p> 在TD的Tools菜单上选择“IP Generator”,出现对话框后选择新建IP核,然后给IP取一个名称(对应生成的Verilog文件名),确定后出现IP选择对话框,找到ADC</p>
<p></p>
<p> 双击鼠标选择它,出现如下的配置界面:</p>
<p></p>
<p> </p>
<p> 紫色框代表硬件ADC模块,左边是输入,右边是输出。看名称能猜到信号都是什么意思了:eoc和soc分别是End of Conversion与Start of Conversion的意思,pd应该是Power Down吧。输出数据12-bit,只有一路,因此8个模拟输入通道需要选择,在方框中打勾表示使能对应的模拟输入通道,s 决定转换哪一个模拟输入。</p>
<p> 再填写一下Component name (需要和之前填写的IP名称一致,我觉是得多此一举),点OK按钮后将生成.v的文件。生成IP的一系列对话框都没有回退功能,界面缺乏说明,不清楚的要另找文档看。</p>
<p> 生成的ADC模块是这样:</p>
<p></p>
<p> 上面代码中的 EG_PHY_ADC就当作一个黑盒子好了。新工程中若没有其它模块,它就自动成为顶层,可以直接综合,出来结果:</p>
<p></p>
<p> </p>
<p> 注意,没有使用LE资源,也就是不需要额外的逻辑,ADC模块的引脚直接连到FPGA管脚了。现在没有写约束,,管脚是自动分配的。</p>
<p> 注意,模拟输入引脚并不在I/O口列表中,也不能在I/O约束对话框中指定。那么,怎么指派模拟输入引脚呢?很可能模拟输入功能是固定的引脚,因为已经有8个输入通道了,从哪个输入模拟信号是八选一……去SparkRoad板子的电路图上找找线索。</p>
<p> 果然,ADC的8个输入通道是引脚名称标住了的,跟MCU的ADC输入类似。</p>
<p></p>
<p> 根据电路图看来,在SparkRoad上只有通道1~7可以用。</p>
<p> </p>
<p> 为了把ADC转换的值呈现出来,我要写一个12位数据转换成十进制,驱动LED数码管的逻辑。在没有CPU的情况下,进行这个转换就要费些工夫了,需要做三次除以10的整数运算。TD里面提供了除法器的IP可以拿来用,不过我不打算用除法,我想就用循环减法来做。</p>
<p> 我的思路是这样的:9999以内的数,先与1000比较,若大于等于1000,就减去1000,千位计数加一,循环;然后与100比较,同理操作百位数字加一,循环;最后与10比较,直到小于10就转换完成了,以时钟周期为代价省去除法器。</p>
<p></p>
<p> 再编写一个LED数码管扫描驱动就简单了,最后写一个顶层,将几个模块连起来工作:</p>
<p></p>
<p> ADC转换我试着给一个脉冲当soc信号,看看结果的情况。数据输出如果是锁存的话,经过我的十进制转换逻辑给扫描显示,稳定的数字就是结果。</p>
<p> </p>
<p> 我选择的通道1输入。引脚悬空时,数字会随机跳动。和GND短路,显示数字就稳定在0了。</p>
<p></p>
<p> 接一节旧电池测量,读数在1642附近跳动(1643,1641都容易看到,也能看到1640,1644出现)</p>
<p></p>
<p> 我用万用表测电池电压显示1.321V,测量板子上ADC_REF电压(C18两端)显示3.291V,则换算ADC转换理论值是1644,差不多。</p>
<p> </p>
<p> 最后测一下ADC转换的时间。将ADC的soc和eoc以及ADC用的时钟引到FPGA脚上接示波器。ADC时钟采用24MHz分频后的1.5MHz. 我的示波器只有两通道,因此一个通道测soc并触发,另一个通道先测时钟保存为参考,再测eoc.</p>
<p></p>
<p> 可见转换过程用了15个时钟周期的样子。</p>
<p> FPGA内带的ADC和MCU带的是类似的,不同点在于FPGA里面直接操作ADC的控制信号,而MCU是读写总线上的ADC控制器的寄存器,是间接操作。</p>
表示没玩过,给你支持,加油! <p>为什么那个方波中间是折的?</p>
freebsder 发表于 2022-4-27 22:38
为什么那个方波中间是折的?
<p>那个是示波器保存的参考,叠加显示的,存的不是采样数据,当成低分辨率贴图理解就是了。</p>
<p>兄弟手好快呀,本打算这星期搞一下呢。我看了你很受启发</p>
请问数码管驱动怎么去写
页:
[1]