×

Verilog中Pmod ALS的SPI接口代码

消耗积分:0 | 格式:zip | 大小:0.00 MB | 2023-06-15

分享资料个

描述

在这个项目中,SPI 接口代码是用 Verilog 编写的,用于连接来自 Pmod-ALS 的 8 位 ADC。8 位二进制转换为 BCD 并显示在 7 段显示器上。Verilog 代码是在 Basys 3 板上的 Artix-7 FPGA 上合成的。

关于我.. 我已经开始学习 Verilog,从硬件的角度思考是非常充实和令人兴奋的。该项目需要更改和改进,我很高兴知道您对此有何看法。

概述

该项目由三个模块组成,如下所示。

  • spi_interface
  • 双重涉猎
  • 七段显示
pYYBAGNsYi-APv2uAACYht8SlTc962.png
图 1:架构
 

模块组织:

poYBAGNsYjOAcW95AACfbxx8hh4099.png
图 2:Vivado 中的模块组织
 

模块一:SPI接口

(模块:spi_interface)

Pmod 环境光传感器 (ALS) 具有一个带有高速 SPI 接口的 8 位 ADC(来自 Texas Instruments 的 ADC081S021)。

pYYBAGNsYjeAfB6bAABb4iwbAsM245.png
图 3:spi_interface
 

由于在硬件上调试时序非常重要,因此我分配了 3 个 I/O 用于监控 Digilent Analog Discovery 上 Pmod ALS 的 CS、SCLK、SDO 线。

注意:即使在仿真中分析和调试时序(通过测试台代码),在逻辑分析仪上连接一些信号也变得非常有必要——在下图中用蓝色框表示

poYBAGNsYjqAMiCiAACpx6od2kE382.png
图 4:模块__spi_interface_code
 
pYYBAGNsYj2APXnlAAIAXMNYZ6A694.png
图 5:监控信号__spi_interface
 
pYYBAGNsYj-AWCOFAAEgbyLJqZU605.png
图 6:监控信号__SPI_AnalogDiscovery
 

架构:SPI接口

传感器规范描述了以下时序图,它是 verilog spi_interface 代码的完整基础。

这是通过两个 8 位计数器和一个 8 位寄存器实现的。

reg [7:0] data_counter;         // Free running counter till 20, to time CS 
reg [7:0] clk_div;              // Prescaler 100 MHz FPGA clock to 1.92 MHz SPI Clock
reg [7:0] r_RX_Byte = 8'b0000_0000; // MISO: Received 1 byte of data from PMOD_ALS
poYBAGNsYkGAIyQCAABtVb0H6H8537.png
图 7:Pmod ALS SPI 时序图
 

时钟分频器(clk_div):从主时钟(Basys 3 板上的 100 MHz)导出 spi 时钟(1.92 MHz)。

poYBAGNsYkSAKtwjAABCI6OJaDY288.png
图 8:spi_interface_code_clock_divider
 

Pmod ALS 上的 ADC 将光强度的模拟值转换为数字值,然后将其串行化以在 SPI 总线上传输。

前 3 位和后 4 位是零和 1 个三态位。中间的 8 位是数据。我们的 verilog 代码在 spi 时钟的帮助下同步捕获这些数据。

数据计数器:data_counter 是一个自由运行的计数器,由 spi 时钟计时。它被调整为触发数据读取和控制从/到 Pmod-SDO 的芯片选择。

一旦 data_counter 变为 20,它就会被重置为 0。在 16 时,CS 按照时序图的要求被拉高。

poYBAGNsYkeAEpTJAABsN66Tc5s357.png
图 9:spi_interface_code_data_counter
 

注意:CS 可以作为该模块的输入,以便顶层应用程序可以命令 CS 引脚。

SDO数据读取:按照时序图图 6 将 SDO 数据读取到 8 位寄存器(MSB 在前)。

poYBAGNsYkqABCsPAACEAQkp-Ns399.png
图 10_spi_interface_code_SDO_data_read
 

模块 2:双重涉猎

读取的 8 位数据被转换为三个 4 位 BCD 矢量,以便能够在 7 段显示器上的每个十进制数字处驱动每个 LED。请在https://www.nandland.com/vhdl/modules/double-dabble.html阅读 Russel 的这篇漂亮的文章

我使用了他的 double dabble 算法的 verilog 代码并纳入了这个项目。谢谢拉塞尔:)

poYBAGNsYkyAAazhAACuwS7c1I0415.png
图 11: 数据流__spi_interface 双涉足 7 seg 显示
 

模块三:七段显示

该模块将 4 位 BCD 矢量转换为驱动 Basys 3 板上四个七段显示器的 LED。

pYYBAGNsYlOAIi3NAAC2bG5xac0756.png
图 12:seven_segment_display_code
 

有关七段显示的详细信息,请参阅 Basys 3 参考手册。https://reference.digilentinc.com/programmable-logic/basys-3/reference-manual

模拟:

请在 GitHub 存储库中找到测试平台代码。

所有三个模块都被实例化。

poYBAGNsYleAan_fAAB7tTJN9oE814.png
图 13:tb_code_1
 
pYYBAGNsYlmALg3XAACq-1aSuAk157.png
图 14:tb_code_2
 

串行数据在 SDO 线上传输,用于仿真和验证。有待验证双dabble算法和七段显示器的阳极/阴极控制是否能正常工作。

结果:

pYYBAGNsYl2AfjZgAAFrhcVwnPc390.png
 
poYBAGNsYmGAVy9MAAFatrlb7r8749.jpg
 
poYBAGNsYmqASIUTAAMp2pEejgs301.jpg
 

概括

与这个项目一起工作非常有趣。需要改进以降低的频率传输数据字节以及在七段显示模块中,以便数据字节的所有三位数字都清楚地显示在显示器上。我很高兴听到您对这个项目的想法。

最重要的是特别感谢来自nandland.com的 Russel和来自Simply Embedded的 Greidi Ajalik 我从你那里学到了很多东西,并感谢你所做的工作。

感谢您的阅读!


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"//m.obk20.com/www/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="//m.obk20.com/vip/index?aid=" + webid return false } //是会员 if (data.code > 0) { $('body').append(htmlSetNormalDownload); var getWidth=$("#poplayer").width(); $("#poplayer").css("margin-left","-"+getWidth/2+"px"); $('#tips').html(data.msg) $('.download_confirm').click(function(){ $('#dialog').remove(); }) } else { var down_url = $('#vipdownload').attr('data-url'); isBindAnalysisForm(pop_this, down_url, 1) } }); }); //是否开通VIP $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code == 2 || data.code ==5){ //跳转到VIP升级页面 $('#vipdownload>span').text("开通VIP 免费下载") return false }else{ // 待续费 if(data.code == 3) { vipExpiredInfo.ifVipExpired = true vipExpiredInfo.vipExpiredDate = data.data.endoftime } $('#vipdownload .icon-vip-tips').remove() $('#vipdownload>span').text("VIP免积分下载") } }); }).on("click",".download_cancel",function(){ $('#dialog').remove(); }) var setWeixinShare={};//定义默认的微信分享信息,页面如果要自定义分享,直接更改此变量即可 if(window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){ var d={ title:'Verilog中Pmod ALS的SPI接口代码',//标题 desc:$('[name=description]').attr("content"), //描述 imgUrl:'https://'+location.host+'/static/images/ele-logo.png',// 分享图标,默认是logo link:'',//链接 type:'',// 分享类型,music、video或link,不填默认为link dataUrl:'',//如果type是music或video,则要提供数据链接,默认为空 success:'', // 用户确认分享后执行的回调函数 cancel:''// 用户取消分享后执行的回调函数 } setWeixinShare=$.extend(d,setWeixinShare); $.ajax({ url:"https://www.elecfans.com/app/wechat/index.php?s=Home/ShareConfig/index", data:"share_url="+encodeURIComponent(location.href)+"&format=jsonp&domain=m", type:'get', dataType:'jsonp', success:function(res){ if(res.status!="successed"){ return false; } $.getScript('https://res.wx.qq.com/open/js/jweixin-1.0.0.js',function(result,status){ if(status!="success"){ return false; } var getWxCfg=res.data; wx.config({ //debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId:getWxCfg.appId, // 必填,公众号的唯一标识 timestamp:getWxCfg.timestamp, // 必填,生成签名的时间戳 nonceStr:getWxCfg.nonceStr, // 必填,生成签名的随机串 signature:getWxCfg.signature,// 必填,签名,见附录1 jsApiList:['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function(){ //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口 wx.onMenuShareTimeline({ title: setWeixinShare.title, // 分享标题 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享给朋友”按钮点击状态及自定义分享内容接口 wx.onMenuShareAppMessage({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 type: setWeixinShare.type, // 分享类型,music、video或link,不填默认为link dataUrl: setWeixinShare.dataUrl, // 如果type是music或video,则要提供数据链接,默认为空 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ”按钮点击状态及自定义分享内容接口 wx.onMenuShareQQ({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口 wx.onMenuShareWeibo({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口 wx.onMenuShareQZone({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); }); }); } }); } function openX_ad(posterid, htmlid, width, height) { if ($(htmlid).length > 0) { var randomnumber = Math.random(); var now_url = encodeURIComponent(window.location.href); var ga = document.createElement('iframe'); ga.src = 'https://www1.elecfans.com/www/delivery/myafr.php?target=_blank&cb=' + randomnumber + '&zoneid=' + posterid+'&prefer='+now_url; ga.width = width; ga.height = height; ga.frameBorder = 0; ga.scrolling = 'no'; var s = $(htmlid).append(ga); } } openX_ad(828, '#berry-300', 300, 250);