FPGA 20个例程篇:4.串行DAC输出模拟电压控制LED亮度

二、常用通信协议,摸索探究:

4.串行DAC输出模拟电压控制LED亮度

         TLC5615是一颗在实战项目中广泛使用的串行DAC,通过这个例程的学习实践,一方面我们可以掌握SPI通信的底层逻辑,另一方面DAC在电力电子、医疗设备、军工雷达领域普遍使用,例如通过运放叠加用于后端功率模块基准的给定等,大家如果条件允许,可以买一个普通1000-2000元的示波器方便后期嵌入式研发工作,开发板上在DAC的输出端连接了SMA座子,可以直接连到示波器上,即能准确测量出DAC发出的模拟信号波形和幅值,当然在绘制开发板原理图时,考虑了更多人性化设计,板子上引出了一个红色发光二极管到DAC的输出端,所以在手边没有示波器的情况下,大家可以直观地观察发光二极管的亮度从而判断DAC的输出情况,如图1所示是豌豆开发板上串行DAC TLC5615的参考电路。

 图1 豌豆开发板Artix7上TLC5615电路

       大家可以回忆下前面一个串口通信的例程中,是不是有几个比较重要的概念例如:波特率、开始位、停止位等,其实相类似地SPI里也有几个关键的概念例如:SCK时钟频率、CPOL、CPHA等。所以在设计这个例程的代码之前,那就让我们首先做好准备工作,即较为系统性地学习SPI通信协议的底层实现逻辑,以及阅读TLC5615芯片手册并提炼程序设计中有用的信息点。

      SPI全称是串行外设接口(Serial Peripheral Interface),可以理解为一种通信协议,也就是用来传输数据的。SPI 是由摩托罗拉(Motorola)公司开发的全双工同步串行总线,是SOC芯片和外围设备之间进行通信的同步串行端口。

     关于SPI通信有很多版本的解释,笔者这里也用最通俗地话去说明:第一、SPI通信需要四根线,即spi_sck时钟,spi_cs片选,spi_mosi数据的主机输出从机输入,spi_miso数据的主机输入从机输出;第二、spi_sck时钟是由主机给出的,因为主从机之间进行SPI通信,那么肯定要保证两者之间的时钟一致,否则就会数据收发紊乱;第三、SPI的CPOL极性和CPHA相位是描述spi_sck时钟的特性核心参数,即主从机需要两者之间的时钟特性保持一致才能进行正常通信;第四、在建立SPI通信的过程中,主机一定要拉低spi_cs片选信号,才能使得整个通信有效。

       这里多说一句,在这个例程和此后的SD卡例程、FLASH例程中,均由FPGA作为主机和外接设备进行SPI通信,所以spi_sck时钟由FPGA端给定,但在实际项目工程中FPGA和ARM端通信,往往FPGA端作为从机,这时就需要ARM端给出spi_sck时钟,FPGA端通过内部快时钟来检测spi_sck时钟上升沿和下降沿,再相应地进行数据的接收和发送!

      关于CPOL和CPHA网上也有很多版本的说法,看来看去很容易被绕糊涂,回过头想一想反正CPOL和CPHA只有两种取值即0或1,那么按照排列组合的原理,对于主机端只有四种可能,在这里笔者简单地整理如下:

   1.CPOL为0,CPHA为0,spi_sck时钟信号空闲为低电平,上升沿采样,下降沿输出

   2.CPOL为0,CPHA为1,spi_sck时钟信号空闲为低电平,上升沿输出,下降沿采样

   3.CPOL为1,CPHA为0,spi_sck时钟信号空闲为高电平,上升沿输出,下降沿采样

   4.CPOL为1,CPHA为1,spi_sck时钟信号空闲为高电平,上升沿采样,下降沿输出

      可能具体图片比抽象文字叙述更加直观生动,为了帮助大家更好地理解SPI的时序逻辑,笔者特意找到一副非常经典的图片,如图2所示详细描述了SPI通信协议在不同CPOL极性和CPHA相位下所对应的采样和输出时序逻辑,对照上面的文字叙述和下面的图片逻辑,在这里大家可以再回顾下,加速对SPI底层时序逻辑的理解!

图2 SPI通信协议在不同CPOL极性和CPHA相位下所对应的采样和输出时序逻辑

      在了解清楚SPI的通信原理后,我们也不先着急动手开始编码,在此之前还需要读一读TLC5615的芯片手册,因为豌豆开发板搭载外设相比市面同类开发板要丰富很多,设计二十个例程,不仅循循渐进更加系统性地实践和掌握FPGA设计,同时也把板载的所有外设都设计成不同的例程,所以在学习的过程中肯定会涉及到阅读芯片手册提取关键信息的环节。

       其实大家不需要有太多畏惧感,因为成为一名优秀的嵌入式工程师,每天和硬件打交道,阅读芯片手册是工作中所必须面对的,这里不需要像上学读书一样,比如学习谭浩强C语言和严蔚敏数据结构,对着每句话琢磨,把每个知识点都学一遍,当成看一本工具书就好, 就如同学习的时候手边会有常备一本英汉词典,见到不认识的单词,查明白再用,带着问题去看即可。

       芯片手册通常包含:应用场景、型号介绍、引脚说明、驱动逻辑、封装尺寸、参考电路等几大块信息,有不同需求看不同内容即可,例如硬件工程师需要芯片选型、画板焊接,那关注更多的地方在于引脚说明、参考电路、型号介绍、封装尺寸等方面,判断所选芯片是否满足设计需求,有哪些引脚需要引出,再参考手册提供的电路去设计原理图,对照封装尺寸做好原器件封装即可,而对于软件工程师来说,在拿到PCB板实物后,对照硬件工程师给出的原理图,关注更多的是驱动逻辑方面的设计。

       下面笔者带着大家一起来读一读TLC5615的芯片手册,站在项目实战的角度,和大家一起去提炼程序设计方面的有效信息,如图3所示,是TLC5615的芯片内部构造和引脚说明,对照图2-7所示的开发板原理图,可以看到SCLK、CS、DIN分别对应了SPI通信的spi_sck时钟,spi_cs片选,spi_mosi数据的主机输出从机输入,OUT对应DAC芯片的输出,细心的同学会注意到REFIN引脚,这是DAC芯片的参考电平引脚,在芯片手册的第三页,我们可以发现硬件上,这个参考电平的取值范围在2V到VDD-2V之间,开发板上VDD使用DC/DC的5V供电,而VREF则使用一个纹波较小的2.5V稳压LDO供电,所以Vrefin刚好在芯片手册的范围内2V-3V之间。

 图3 TLC5615的内部结构和引脚说明

      如图4所示是TLC5615的Vout输出模拟电压值计算说明,据此我们可以知道这颗串行DAC的位宽是10bit,那么例如按照芯片手册给出的例子,参考电平Vrefin是2.048V, Vout=2*Vrefin*din/1024,当din取值1023时,Vout输出接近于4.096V,当din取值0时,Vout输出是0V。而原理图中,我们给出的参考电平Vrefin是2.5V,如果din取值1023时,Vout输出接近于5V。

图4 TLC5615的Vout输出模拟电压值计算说明

      如图5所示是对TLC5615芯片控制的时序逻辑,这其实就是个标准的SPI通信协议,当然芯片手册标明了SPI通信中保持时间和建立时间的区间范围,同时需要注意到DAC每次发送din的数据位是12位,其中前10位是有效数据,后2位是无效数据,这里我们把后2位都统一发送位2位的0。

 图5 对TLC5615的控制时序逻辑

       如图6所示是TLC5615与SOC芯片连接示意图,大家可以清楚地看到芯片手册里要求对SPI控制DAC的CPOL极性和CPHA相位已经给出,即CPOL和CPHA均为0,也标明了DOUT即spi_miso引脚可以不连接,但可以用于验证数据的传输,因为豌豆开发板搭载很多外设引脚紧张,所以原理图上没有把DAC的DOUT引脚引出。

 图6 TLC5615与SOC芯片连接示意图

       到这里已经把SPI的底层通信逻辑、TLC5615手册的有效信息都整理完毕,下面就只用动手编码即可,在这个例程中笔者和大家一起去写一个通用性的SPI底层逻辑,如表1所示是该模块的信号列表, 模块中CPOL和CPHA通过输入信号给定,所以其具有更多的通用性,如图7所示是CPOL和CPHA均为1时SPI通信的时序逻辑,即spi_sck时钟信号空闲为高电平,上升沿采样,下降沿输出,有兴趣的同学可以用Timegen去动手画一画CPOL和CPHA均为0时SPI通信的时序逻辑,也都大同小异,如图8是 SPI底层模块的代码设计,大家可以对照图7的时序图尝试写出对应的verilog代码。

 图7 CPOL和CPHA均为1时SPI通信的时序逻辑

信号列表

信号名

I/O

位宽

clk

I

1

rst_n

I

1

spi_en

I

1

tx_spi_data

I

10

spi_cpol

I

1

spi_cpha

I

1

spi_mosi

O

1

spi_sck

O

1

spi_cs

O

1

表1 spi_driver模块信号列表

图8 SPI底层模块的代码设计

      在这个例程中我们来实现一个基本功能,FPGA控制串行DAC芯片循环输入0-1023,改变电压模拟控制LED亮度,这里通过一个计数器模块每隔10ms时间从0-1023,如表2所示是定时向SPI总线输入数据计数器模块的信号列表,该模块的代码设计如图9所示,非常简单只是用一个定时器cnt0数10ms时间,再用一个定时器cnt1数0-1023的数,然后每隔10ms把数据发往spi_driver模块。

信号列表

信号名

I/O

位宽

clk

I

1

rst_n

I

1

spi_mosi_dout

O

10

spi_mosi_dout_vld

O

1

表2 spi_mosi_dout模块信号列表

图9 定时器发数模块的代码设计

        如图10所示是串行DAC输出模拟电压控制LED亮度顶层文件的例化,这里我们用PLL IP核事先把50Mhz的晶振时钟分配成6.25Mhz的,再给spi_driver使用,spi_driver模块也对时钟进行了四分频,即DAC的驱动时钟为1.5625Mhz,笔者在各个模块中也把关键信号添加到ILA IP核,方便大家上板观察,如图11所示,是串行DAC的SMA座子连接到示波器上所观察的输出波形,可以清楚地看到示波器的横坐标(时间坐标是2S一格),纵坐标(电压坐标是2.5V一格),完全符合预期,因为原理图中TLC5615的VREF引脚是由2.5V给定参考,当DIN输入是1023时,DAC的输出按照之前芯片手册的分析,则接近于5V即纵坐标接近两格,从0数到1023,一共用了10ms*1024约等于10秒钟即横坐标五格左右。

 图10 串行DAC输出模拟电压控制LED亮度顶层文件的例化
 

 图11 示波器观察到的串行DAC模拟电压输出
 

  • 10
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值