0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Mojo EPGAs简介—第2部分

半导体开发 来源:DevicePlus 作者:DevicePlus 2023-03-01 18:24 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

这篇文章来源于DevicePlus.com英语网站的翻译稿。

pYYBAGPzDniATJz6AAF2Ete58HU581.jpg

在本教程的第1部分中,我们介绍了FPGA,并在嵌入式 Micro的Mojo FPGA上完成了一个简单的入门项目。在第2部分中,我们将介绍一个更复杂的项目:在Mojo FPGA上实现硬件PWM。

脉冲宽度调制(PWM)被广泛应用于嵌入式系统中,用以控制LED亮度、电机转速,甚至可用于通信。如果您使用的是Arduino,那么在使用analogWrite()函数的时候一定遇到过PWM。在Mojo上实现PWM之前,我们应该首先了解一下PWM是如何工作的!

脉冲宽度调制(PWM)

微控制器和其他嵌入式系统处理器使用数字信号来进行计算和执行任务。这些信号仅以两种电平状态中的一种出现:“高”电平(通常为3.3V或5V)和“低”电平(通常为0V)。这两种电平分别编码为二进制1和0,因此可用于执行各种各样的工作任务。

但是,如果我们想输出比“开和关”更多分级的电压呢?在诸如上文中所提到的要求输出可变强度的应用激发了对该问题的探索。一种解决方案是将系统连接到称为“数模转换器DAC)”的外部设备,该设备从主处理器获取二进制1和0形式的数字信号输入,并输出几乎连续的0V到系统“最大电压”范围内的电压值。但是,对于大多数嵌入式系统应用程序来说,存在一种更简单的方法:PWM!

从某种程度上讲,PWM利用了人类的感知系统和物理系统(如电机)能够对变化的输入进行快速平均这一事实。系统生成一个包含高频率脉冲的数字信号,因此很难将每个脉冲区分开来。在给定的波形周期内,信号在该时间内的某些时间为高电平,其余时间为低电平—高电平所占的时间比例称为信号的占空比或工作周期。平均输出效果(无论是LED的亮度还是电机转速)取决于PWM信号的占空比。当然,顾名思义,我们可以通过更改波形的占空比(脉冲宽度)来改变输出效果!下图显示了不同占空比及其对应波形的比较。

poYBAGPzDn2ALbHWAADa7r7-mnE914.jpg

图1:不同占空比及其相关脉冲波形的比较。显然,当信号一直为高电平,占空比为100%时,出现了最“强烈”的输出效果

Arduino板上的微控制器IC(如ATMega芯片)具有专用于根据处理器指令生成PWM信号的内部硬件。这些电路的输出连接到微控制器IC上的特定引脚。这也意味着只有这些引脚可以提供PWM信号。但是,在像Mojo这样的FPGA上,我们可以根据需要配置内部硬件,也就是说我们可以创建任意数量的硬件PWM电路!

Mojo FPGA上的硬件PWM

在本教程中,我们将探索如何在Verilog中实现硬件PWM,并了解Verilog代码的模块化如何使我们能够根据需要在Mojo中配置尽可能多的硬件PWM电路。

以下是您需要遵照实施的所有内容:

• Mojo V3开发板

我们将在嵌入式Micro提供的Mojo Base Project的基础上,为该项目构建我们自己的Verilog代码。以这些项目为基础来构建是很有帮助的,因为设备规格和ISE中的其他初始化工作都已经为我们设置好了!如果需要,您可以通过对项目目录中的.xise项目文件进行重命名来更改项目名称。我将其命名为“MojoPWM.xise”。

通常,我们首先会在UCF中表明名称和引脚编号,用于与Mojo上的I/O引脚建立的不同连接。但是,对于本项目,我们将使用板载LED,信号名称和引脚连接都已经指定好了。因此,此处不需要额外的声明。我们将从创建一个新的Verilog模块开始,该模块将指定我们硬件PWM的行为。并非将代码直接放入mojo_top模块中,我们将创建一个独立的模块以利用模块化设计。如果我们要创建不同的硬件PWM电路来运行不同的LED,则只需要创建该种独立PWM模块的新实例即可,无需复制和粘贴大量代码。

右键单击左侧“Hierarchy”窗口中的任意位置,然后点击名为“New Source…”的选项,在“Source Type”的选项列表中,选择“Verilog Module”,并将文件命名为“PWM.v”,以此将创建出一个新的Verilog文件,该文件具有用于PWM模块的框架。

在真正开始编写代码之前,我们先来讨论一下我们的PWM实现方法。如前所述,我们用该硬件生成的信号本身是周期性的,也就是说信号值与时间有关。因此,我们必须根据不间断的滴答时钟信号来指定其行为。这个时钟信号已经作为系统输入包含在mojo_top模块中了,为方波信号,图形如下所示:

poYBAGPzDoCAV2iDAABcO-740FM109.jpg

我们的硬件操作可总结如下:

• 每个时钟周期(从信号的上升沿开始),我们将增加内部计数器的值,该值的范围为0-255。

• 占空比将作为输入包含在模块中,范围为0-255(就像Arduino的硬件PWM中的那样)。如果我们的计数器值小于占空比,那么输出信号将为高电平,否则,输出信号将为低电平。

• 在复位线上收到高电平值时,硬件将复位计数器。

我们选择值255作为最大计数器值,因为这是8位数值中可以存储的最大值(11111111)。如果从该值增加1,则计数器将回复到00000000,因为会溢出。要了解有关二进制计算和整数的二进制表示的更多信息,请点击下面附录中的链接进行查看!

这是一个时序图,表示我们随内部时钟信号的硬件操作:

pYYBAGPzDoKANbACAAB1FR-Pfis294.jpg

图2:占空比为3/255的8位硬件PWM模块的时序图。二进制中的最大占空比值与最大计数器值相同,均为11111111

我们将以输入和输出信号列表作为开始,进行对PWM模块的Verilog描述:

input clk,

input rst,

input[7:0] duty,

output sig_drv

您可能已经从它们的名称中看出来了,这四个信号分别为时钟、复位、占空比值和PWM输出信号。

接下来,我们需要限定输出信号sig_drv的数据类型。Verilog有两种数据类型,线网(wire)和寄存器(reg)。虽然这两种类型之间的差异对我们的应用程序来说是很微小的,但是有一个主要区别需要注意,就是当我们就像在本项目中这样使用always块时,只能写regs而不能写wires。我们随后会讨论always块及其相关操作。如果信号列表中的信号没有被限定为wire或reg,Verilog将默认其声明为wire类型。在这种情况下,我们需要通过模块信号列表之后的以下行将sig_drv描述为reg:

reg sig_drv;

我们还将使用如上所述的8位计数器,并且通过always块对其进行设置。因此,我们需要声明一个8位大小的计数器,如下所示:

reg[7:0] counter;

您可能已经注意到了,像许多其他编程语言一样,Verilog是0索引的,这意味着计数总是从0开始的。因此,一个8位计数器中的位索引值为数字0到7。

接下来,我们对8位计数器的向上计数和输出信号的驱动的逻辑进行描述。我们可以使用always来完成!always块是一种Verilog结构,用户可以指定仅在always块的触发条件被满足时才会进行的操作。一个 always块的基本结构如下:

always @ (…)

begin

end

在 “@” 符号后的括号内,用户需要指定触发条件,该条件将决定何时执行块内的逻辑。在我们的项目中,需要两个always块:

always @(*)

begin

end

always @(posedge clk or posedge rst)

begin

end

在第一个块中,触发条件为“*” ,这意味着只要项目中的任何信号发生变化,该块内的逻辑就会被执行。硬件工程师可能将此块称为组合逻辑,该逻辑始终将输出值定义为输入值的某些函数。在此块中,我们将放入在所有时刻都起作用的逻辑,而不是每个时钟周期只执行一次的逻辑,如输出信号的驱动。

如前所述,输出信号为高电平驱动还是低电平驱动取决于计数器相比于占空比的大小。可以通过以下代码行中的always @ (*) 块实现此功能:

if (duty > counter)

begin

sig_drv = 1’b1;

end

else

begin

sig_drv = 1’b0;

end

sig_drv信号的宽度为1位(只有0和1两种值…一个位),因此我们在给它分配的值前加上字符“1’b”。从上面的代码中我们可以看到,当占空比大于计数器值时,sig_drv线被驱动为1(高),否则被驱动为0(低)。

在第二个块中,触发条件为posedge clk 或 posedge rst。这意味着当时钟信号从低电平变为高电平或复位线从低电平变为高电平时,该块内的逻辑被执行,且在每个时钟周期内仅执行一次。我们将使用该always块来指定每执行一个时钟周期时的计数器增加。可以使用此块中的以下代码行完成此操作:

if (rst)

begin

counter <= 8’b0;

end

else

begin

counter <= counter + 1;

end

if语句的第一段指定了当复位线变为高电平时,必须将8位计数器复位为全零。第二段的else条件下指定了如果复位线不是高电平,则计数器的值会被增加。

我们可以看到分配给计数器的值取决于其先前的值。硬件工程师将这种类型的逻辑称为顺序模型,因为输出既是输入的函数,也是过去状态值的函数。

关于该代码最后需要说明的是 “<=” 运算符,即非阻塞赋值运算符,用于将值赋给计数器变量。当我们像往常一样使用 “=” 运算符(阻塞赋值运算符)来给信号赋值时,其实我们已经默许Verilog对编写的代码自上而下来执行。换句话说,如果我们连续编写了两个“=”赋值语句,那么第一个赋值操作将会在第二个赋值操作开始之前完成执行。这其实在某些逻辑上是必要的,因为我们可能会使用以此方式分配的值进行后续计算。

但是,在基于高速时钟信号的顺序逻辑中,我们实际上希望所有的值的分配都在某种程度上并行发生(如果它们彼此独立的话),这样我们就不会将程序延迟到与下一个时钟边沿发生冲突的程度。在本程序中,我们没有在每个时钟边沿上指定执行多种任务。但是,如果我们需要这样做的话,使用非阻塞赋值运算符可以完成这项操作。

完整的PWM模块应如下所示:

poYBAGPzDoWAGF7tAAFeBv0BQ1g726.jpg

现在我们已经创建了PWM模块,可以在mojo_top模块中将其实例化了!在Verilog中,将一个模块在另一个模块中实例化使您可以在更高级别的模块中一次或多次调用子模块功能,而不必复制其代码。就我们的项目来说,我们可以根据需要创建足够多的PWM信号来驱动不同的LED,甚至连接到Mojode 输出引脚上!要配置PWM信号来点亮Mojo上的第8个LED,我们可以添加以下行:

PWM my_pwm(.clk(clk), .rst(rst), .duty(8’b01000000), .sig_drv(led[7]));

该行的第一个单词PWM是我们要实例化的模块的名称。这将在我们选择实例化多个副本时帮助识别同一PWM模块的不同实例。

在模块名称后的括号内,我们使用了.(signal_name) 格式将更高级别模块 (signal_name) 中的信号分配给子模块中的相应信号 (module_signal_name)。

如果要更改PWM信号的占空比,我们要做的就是更改传递到占空比参数中的值。如果被驱动的输出信号,则只需要将作为参数传递的信号更改为.sig_drv。

您所完成的mojo_top模块应如下所示:

poYBAGPzDoqAdaXiAAOZdv9CCYA058.jpg

要将代码上传到Mojo板上,请按照之前的步骤进行操作:在ISE中生成编程文件,加载Mojo Loader应用程序,然后将.bin文件上传到Mojo。

恭喜您!您已经在Mojo上实现硬件PWM了!如果想进行进一步的实验,请尝试创建多个硬件PWM信号并为其提供不同的占空比参数!您可以通过修改代码,来实现通过一些拨动开关将占空比值输入到Mojo中吗?

我们希望您对自己的第一个FPGA项目感到满意!请继续关注来获取更多有关FPGA和微控制器的教程!

审核编辑黄宇

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

    关注

    48

    文章

    8249

    浏览量

    162289
  • PWM
    PWM
    +关注

    关注

    116

    文章

    5847

    浏览量

    223741
  • Arduino
    +关注

    关注

    190

    文章

    6514

    浏览量

    195922
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    集装箱储能系统标准解析系列(一)|IEC 62933-2-1:电能存储(EES)系统 2-1部分-储能单元参数和试验方法

    IEC 62933-2-1 电能存储(EES)系统 2-1部分:储能单元参数和试验方法
    的头像 发表于 11-25 15:40 700次阅读
    集装箱储能系统标准解析系列(一)|IEC 62933-<b class='flag-5'>2</b>-1:电能存储(EES)系统 <b class='flag-5'>第</b><b class='flag-5'>2</b>-1<b class='flag-5'>部分</b>-储能单元参数和试验方法

    集装箱储能系统标准解析系列(三)| IEC TS 62933-4-1电能存储系统(EES) 4-1部分:环境问题指导

    IEC TS 62933-4-1电能存储系统(EES) 4-1部分:环境问题指导 通用规范
    的头像 发表于 11-25 15:11 164次阅读
    集装箱储能系统标准解析系列(三)| IEC TS 62933-4-1电能存储系统(EES) <b class='flag-5'>第</b>4-1<b class='flag-5'>部分</b>:环境问题指导

    一文了解Mojo编程语言

    Mojo 语言的具体介绍: 核心特点 Python 兼容性 Mojo 支持大部分 Python 语法和标准库,可直接调用 Python 生态系统中的库,降低了学习成本。 极致性能优化 通过静态编译
    发表于 11-07 05:59

    瑞为技术牵头制定的国家标准《信息技术 可扩展的生物特征识别数据交换格式 1部分:框架》正式发布

    近日,由瑞为技术牵头、中国电标院等参与制定的国家标准《信息技术 可扩展的生物特征识别数据交换格式 1部分:框架》正式发布。 同时,瑞为参编的其他6项可扩展系列标准(涵盖指纹、人脸、虹膜、血管、全身
    的头像 发表于 04-22 18:05 788次阅读

    基于运算放大器和模拟集成电路的电路设计(3版)

    内容介绍: 本文全面阐述以运算放大器和模拟集成电路为主要器件构成的电路原理、设计方法和实际应用。电路设计以实际器件为背景,对实现中的许多实际问题尤为关注。全书共13章,包含三大部分。第一部分
    发表于 04-16 14:34

    DLPC3478固件加载只有前面一部分是怎么回事?

    我们现在自己研发的DLPC378+DLPA2005+DLP3010板子,Flash型号和TIDA-080003 参考设计上的一样 W25Q32JVSSIQ。现在用示波器测试到固件只加载了一部分
    发表于 02-21 07:57

    DLPC3433部分DSI失效的原因?如何解决?

    部分板子,在无法实现4步,始终无法显示系统输出的DSI,接入后,仍然是马赛克图案。 我们可以确保我们输出的DSI没有问题,因为正常板子是可以输出完整的DSI视频信息,同时我们是同一批生产的板子,目前出现不一致的情况。 请求帮助: 分析DLPC3433
    发表于 02-21 07:24

    运算放大器速成课程2部分:关键参数教程

    电路设计人员根据几个器件参数选择运算放大器。这些参数必须满足运算放大器应用的要求。下面列出了最常考虑的参数。本教程的2部分解释了它们的定义和用途。
    的头像 发表于 02-20 18:22 942次阅读
    运算放大器速成课程<b class='flag-5'>第</b><b class='flag-5'>2</b><b class='flag-5'>部分</b>:关键参数教程

    运算放大器速成课程1部分:基础教程

    理解运算放大器的基本原理对于在工业、汽车和电信应用中销售微控制器(MCU)至关重要。运算放大器对现实传感器的输出信号进行放大和滤波,以便模数转换器能够访问这些信号,无论它们是分立器件还是集成到MCU中。本教程的1部分介绍了运算放大器的基本知识。
    的头像 发表于 02-20 18:05 981次阅读
    运算放大器速成课程<b class='flag-5'>第</b>1<b class='flag-5'>部分</b>:基础教程

    ISO 16750-2-2010 道路车辆电气和电子设备的环境条件和试验2部分:电气负载

    电子发烧友网站提供《ISO 16750-2-2010 道路车辆电气和电子设备的环境条件和试验2部分:电气负载.pdf》资料免费下载
    发表于 02-11 15:39 4次下载

    微软科技如何应对AI原生企业浪潮

    本文改编自微软AI at Work首席营销官贾里德·斯帕塔罗(Jared Spataro)的“关于Al原生组织系列文章”,其中1部分揭示了AI原生组织的核心原则,2
    的头像 发表于 02-11 10:34 863次阅读

    GB/T 31467.1-2015电动汽车用锂离子动力蓄电池包和系统1部分:高功率应用测试规程

    GBT31467.1-2015 电动汽车用锂离子动力蓄电池包和系统 1部分 高功率应用测试规程
    发表于 02-10 15:40 3次下载

    建造方程式赛车:BSPD 2 部分

    作者:Antonio Velasco 继续 UCI FSAE 团队完成制动系统合理性装置(或 BSPD)设计过程的第二部分,我们研究这种安全电路的工作原理及其背后的要求。我们的目标是在明年的多项比赛
    的头像 发表于 01-26 17:47 1971次阅读
    建造方程式赛车:BSPD <b class='flag-5'>第</b> <b class='flag-5'>2</b> <b class='flag-5'>部分</b>

    松下MPS媒体制作平台 第九篇:视频混合器插件(第四部分)

    一共制作了四部分的教程,本期是第四部分。您也可以参阅第一、二、三部分做好相应的准备和熟悉工作。 本期我们将介绍如何在多视图界面进行以下操作: 1.多视图设置 2.切换输出视频 3.注销
    的头像 发表于 01-16 11:30 1090次阅读
    松下MPS媒体制作平台 第九篇:视频混合器插件(第四<b class='flag-5'>部分</b>)

    松下MPS媒体制作平台第八篇:视频混合器插件(第三部分)

    多种视频素材进行合成。 关于视频混合器的操作介绍,我们一共制作了四部分的MPS媒体制作平台教程,本期是第三部分。在进入本部分之前,您也可以参阅第一、二部分做好相应的准备和熟悉工作。 本
    的头像 发表于 01-08 10:10 935次阅读
    松下MPS媒体制作平台第八篇:视频混合器插件(第三<b class='flag-5'>部分</b>)