FPGA_学习_09_PWM呼吸灯

news2024/9/24 5:30:38

PWM在三相电机控制中,有着非常重要的地位。 如果你需要用FPGA去实现三相电机的控制, PWM这一关是绕不过的。好在PWM的基本原理是比较简单的。所以原理部分本文就略过,本文基于PWM实现呼吸灯。

1 时序 

{signal: [
    {name: 'clk',   		wave: 'p...............................'	},
    {},
    {name: 'rst_n',			wave: '01..............................'	},
    {},
    {name: 'cnt_ms',		wave: '2.222222222222222222222222222222'	, data: ['0','1','2','...','MAX','0','1','2','...','MAX','0','1','2','...','MAX','0','1','2','...','MAX','0','1','2','...','MAX','0','1','2','...','MAX']},
    {},
    {name: 'cnt_1s',		wave: '2.....2....2....2....2....2....2'	, data: ['0','1','2','...','MAX','0','1','2','...','MAX']},
    {},    
    {name: 'pwm',			wave: '0.....10...1.0..1..0.1....0....1'	},
    {},
    {name: 'duty_cycle',	wave: '2.....2....2....2....2....2....2'	, data: ['0%','1%','2%','...','100%','99%','98%']},
    {},    
    {name: 'workflag',    	wave: '0.........................1.....'	},
    {}
]}

 2 FPGA源文件

`timescale 1ns / 1ps

module pwm_led(
        input   wire            clk     ,
        input   wire            rst_n   ,
        output  wire    [1:0]   led         
);


//==================================================================
//                        Parameter define
//==================================================================

localparam      CNT_1MS         = 50_000 - 1;   // 20ns x 50_000 = 1ms
localparam      CNT_1S          = 1000 - 1;     // 1ms x 1000 = 1s
localparam      CHANGE_TIME     = 500 - 1;      // 1ms x 500 = 0.5s
localparam      PWM_OFFSET      = 100;


//==================================================================
//                        Internal Signals
//==================================================================

reg     [31:0]  cnt_ms          ;
reg     [31:0]  cnt_s           ;
reg             pwm             ;
reg     [31:0]  duty_cycle      ;
reg             work_flag       ;

assign led[1] = ~pwm;
assign led[0] = 1'b0;

//----------------------------- cnt_ms -----------------------------
always @(posedge clk or negedge rst_n) begin
        if (rst_n == 1'b0) begin
                cnt_ms  <= 'd0;         
        end
        else if (cnt_ms == CNT_1MS) begin
                cnt_ms  <= 'd0;
        end
        else begin
                cnt_ms  <= cnt_ms + 1'b1;
        end
end

//----------------------------- cnt_s -----------------------------
always @(posedge clk or negedge rst_n) begin
        if (rst_n == 1'b0) begin
                cnt_s   <= 'd0;              
        end
        else if(cnt_ms == CNT_1MS) begin
                if (cnt_s == CNT_1S) begin
                        cnt_s   <= 'd0;
                end
                else begin
                        cnt_s   <= cnt_s + 1'b1;
                end
        end
        else begin
                cnt_s   <= cnt_s;
        end
end

//----------------------------- work_flag -----------------------------
// 0 ~ 0.5s     work_flag == 0
// 0.5s ~ 1s    work_flag == 1 
always @(posedge clk or negedge rst_n) begin
        if (rst_n == 1'b0) begin
                work_flag <= 1'b0;                 
        end
        else if (cnt_s == CHANGE_TIME && cnt_ms == CNT_1MS) begin
                work_flag <= 1'b1;
        end
        else if (cnt_s == CNT_1S && cnt_ms == CNT_1MS) begin
                work_flag <= 1'b0;
        end
        else begin
                work_flag <= work_flag;
        end
end

//----------------------------- duty_cycle -----------------------------
always @(posedge clk or negedge rst_n) begin
        if (rst_n == 1'b0) begin
                duty_cycle      <= 'd0;                 
        end
        else if (work_flag == 1'b0) begin
                if (cnt_ms == CNT_1MS) begin
                        duty_cycle <= duty_cycle + PWM_OFFSET;
                end
                else begin
                        duty_cycle <= duty_cycle;
                end
        end
        else if (work_flag <= 1'b1) begin
                if (cnt_ms == CNT_1MS) begin
                        duty_cycle <= duty_cycle - PWM_OFFSET;
                end
                else begin
                        duty_cycle <= duty_cycle;
                end
        end
        else begin
                duty_cycle <= duty_cycle;
        end
end

//----------------------------- pwm -----------------------------
always @(posedge clk or negedge rst_n) begin
        if (rst_n == 1'b0) begin
                pwm <= 1'b1;                   
        end
        else if (cnt_ms < duty_cycle) begin
                pwm <= 1'b1;
        end
        else begin
                pwm <= 1'b0;
        end
end

endmodule

3 约束文件

create_clock	-period			20.000		[	get_ports	clk	]

set_property    PACKAGE_PIN		N18			[	get_ports	clk			]
set_property    PACKAGE_PIN		P15			[	get_ports	{led[0]}	]
set_property    PACKAGE_PIN		U12			[	get_ports	{led[1]}	]
set_property    PACKAGE_PIN		T12			[	get_ports	rst_n		]

set_property    IOSTANDARD      LVCMOS33	[	get_ports	clk			]  
set_property    IOSTANDARD      LVCMOS33	[	get_ports	{led[*]}	]  
set_property    IOSTANDARD      LVCMOS33	[	get_ports	rst_n		]  

4 运行结果

PWM呼吸灯

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

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

相关文章

4 STM32启动过程(以Cortex-M3为例)(保姆级介绍)

设计知识点补充在前&#xff1a; 1.关于存储器映射、存储器重映射、内存映射、地址映射、地址转换等计算机专业名词详解 参考见 关于存储器映射、存储器重映射、内存映射、地址映射、地址转换等计算机专业名词详解_Vincent_Song的博客-CSDN博客 2.哈佛结构和冯诺依曼结构的区别…

vue2中左侧菜单和头部tab标签联动

效果图 我这里是使用的vue2 element-ui来实现的&#xff0c;代码可以直接拿来使用 一、首先先安装element-ui element-ui官网 npm i element-ui -S 然后在main.js里面配置&#xff0c;安装官网的步骤来就可以了&#xff0c;这里就不一一介绍了 import Vue from vue; impor…

用wget等命令行工具下载Jenkins上的文件

背景 现在一般公司的内部CI系统都用Jenkins实现&#xff0c;本地部署的时候我会将待测试文件下载到本地&#xff0c;再上传到Linux开发板&#xff0c;但能否从Linux开发板直接下载呢&#xff1f;只要Linux与Jenkins server之间的网络是联通的&#xff0c;那就可以 解决方法 …

【从零开始学习JAVA | 第二十三篇】集合体系结构

目录 前言&#xff1a; 单列集合&#xff1a; set与list的区别&#xff1a; 双列集合&#xff1a; map的特点&#xff1a; 总结&#xff1a; 前言&#xff1a; JAVA中为我们提供了很多集合&#xff0c;这些集合都有自己很独特的特点&#xff0c;因此我们要学习所有的…

网络安全合规-网络安全工程师发展前景(三)

上海网络安全工程师工资按工作经验统计&#xff0c;其中应届毕业生工资5250&#xff0c;0-2年工资8910&#xff0c;3-5年工资11330&#xff0c;8-10年工资13500&#xff0c;6-7年工资16170&#xff0c;该数据仅供参考。 北京网络安全工程师工资按工作经验统计&#xff0c;其中…

python selenium 定位鼠标悬浮后的新弹窗数据

背景 最近需要获取网页上的标签数据&#xff0c;但是标签大于3个以后是隐藏的&#xff0c;需要鼠标hover上去才显示。如下图&#xff0c;图一是刚进来界面展示的&#xff0c;需要知道额外的7个标签则需要将鼠标移动到目标上面去。 但是比较尴尬的一个点是&#xff0c;当游览器打…

数据结构C语言版本(中)

第四章 串 串&#xff1a;限定数据元素类型的线性表。 应用实例&#xff1a; 编辑软件(本质上是字符串处理) 信息检索、病毒查找(字符串比较) 第一节 逻辑结构 一、定义 串是由字符组成的线性表。 STRING(D&#xff0c;S&#xff0c;P) D {ai| ai∈CHARACTER(字符集), i0,1…

Verilog基础之八、多路选择器实现

一、前言 选择器在FPGA中是基础的组成部分&#xff0c;英文全称为Multiplexer&#xff0c;为一个多输入单输出的结构。以器件xc7k480tffv1156为例&#xff0c;在slice中&#xff0c;也可以看到F7AMUX&#xff0c;F8MUX&#xff0c;这两个MUX都是二输入单输出的选择器。 二、工程…

【雕爷学编程】Arduino动手做(128)---2路I2C电平转换模块

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

VR虚拟现实技术为机械专业教学带来新思路

随着虚拟现实技术的发展&#xff0c;VR已经成为机械专业教学的一种新方式。它可以为学生提供更加生动、直观的学习体验&#xff0c;同时也可以帮助教师更好地进行教学和评估。以下是广州华锐互动总结的一些常见的应用场景&#xff1a; 模拟实验和操作&#xff1a;VR可以为学生提…

(UE4/5) PS中生成LUT进行UE4/5的色域颜色校正

整理自官方&#xff1a;使用虚幻引擎查找表&#xff08;LUT&#xff09;进行颜色校正 | 虚幻引擎5.2文档 (unrealengine.com) 一、Unreal Engine中截图 在UE4/5中截一张场景图&#xff08;比较有代表性的&#xff09; 然后&#xff0c;用这张图片&#xff1a;&#xff08;不要…

Qt使用事件(event)与定时器实现字幕滚动

目录 1、效果展示2、实现思路3、滚动窗口部件3.1、成员变量3.2、事件重写3.3、成员方法3.3、方法实现 1、效果展示 我们经常能够在外面看到那种滚动字幕&#xff0c;那么就拿qt来做一个吧。 2、实现思路 实现一个窗口部件&#xff0c;这个窗口部件显示了一串文本标语,它会每…

H3C-HCL-SE-“01-路由备份与链路聚合实验“

实验拓扑图&#xff1a; 实验需求&#xff1a; 1、按照图示配置 IP 地址&#xff0c;R3 上连接 192.168.X.X/24 4个业务网段 2、配置 RIPv2 协议使全网互通&#xff0c;R1 和 R3 的直连链路不运行 RIP 3、R1 上配置静态路由直接经过 R3 到达所有业务网段 4、R1 和 R2 上不允…

第八十五天学习记录:C++核心:内存分区模型

内存分区模型 C程序在执行时&#xff0c;将内存大方向划分为4个区域 1、代码区&#xff1a;存放函数体的二进制代码&#xff0c;由操作系统进行管理 2、全局区&#xff1a;存放全局变量和静态变量以及常量 3、栈区&#xff1a;由编译器自动分配释放&#xff0c;存放函数的参数…

【雕爷学编程】Arduino动手做(129)---TTS文字转语音合成模块

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

python爬虫_requests入门指引

文章目录 ⭐前言⭐requests库&#x1f496; pip安装requests&#x1f496; requests get&#x1f496; requests post 结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享关于python的requests库用法。 该系列文章&#xff1a; python爬虫_基本数据类型 python爬虫…

Edge浏览器可以多开吗?

问答链接&#xff1a;Edge浏览器可以多开吗&#xff1f; 可以。 如果你的edge浏览器是默认路径安装的&#xff0c;那么打开命令提示符窗口输入以下两条命令即可启动一个数据完全隔离的edge浏览器。 mkdir C:\logs001 "C:\Program Files (x86)\Microsoft\Edge\Applicati…

shell [[]] 语法错误解决方式

错误如图&#xff1a; /linux/install.sh:行15: if [[ $contrainsha e *$contrainsname* ]] /linux/install.sh:行15: 条件表达式中有语法错误 附近有语法错误/linux/install.sh:行15: ]] [[]]语法 当[[ ]]判断expr成立时&#xff0c;退出状态为0&#xff0c;否则为非0值。…

STM32F103使用USART3/UART4乱码问题

源程序为USART1的配置&#xff0c;更改USART3/4相应寄存器测试&#xff0c;测试一直显示有规律乱码&#xff0c;收发不符。 void uart_init(u32 pclk,u32 bound) { float temp;u16 mantissa;u16 fraction; temp(float)(pclk*1000000)/(bound*16);//得到USARTDIVmantissa…

labview 公式节点转换(U16->S16)

问题&#xff1a;在和测力计通讯时&#xff0c;需要把读出的裸数据转化有符号整数 其它网友的文章可以进行转换 &#xff08;笔记&#xff09;labview各种进制转换&#xff08;通讯得到的负数补码转换成负数原码&#xff09;_labview数字间的进制转换_是孑然呀的博客-CSDN博客…