当前位置: 首页 > article >正文

ZYNQ 7020 学习记录-2呼吸灯(模块化)

系列文章目录

1.点灯
2.呼吸灯(模块化)


文章目录

  • 系列文章目录
  • 前言
  • 一、模块实例化
  • 二、呼吸灯
    • 1.原理解释
    • 2.按键消抖模块
    • 3.呼吸灯模块
    • 4.顶层模块
    • 5.上板验证
  • 总结


前言

由于研究生课题组所需学习ZYNQ,以下是本人自学ZYNQ的学习记录,所用板卡为:基于 XILINX ZYNQ7000 开发平台的开发板(型号:AX7021B) 2022 款。
在这里插入图片描述

一、模块实例化

模块化,相当于将一个模块当作一个函数,使用在另一个模块中,代码就可以显得有序、不冗余。
示例如下:
加法模块

module add(
    input   num1,    //子模块输入1
    input   num2,    //子模块输入2
    output  add		//子模块输出     
    );
    
assign led = key;
    
endmodule

顶层模块

module top_add(
    input   wire [10:0] a,    		//顶层模块输入1
    input   wire [10:0] b,    		//顶层模块输入2
    output  wire [10:0] sum   //顶层模块输出     
    );
    
add u_add(
	.num1(a),
	.num2(b),
	.add(sum)
);
    
endmodule

二、呼吸灯

1.原理解释

代码如下(示例):

// 呼吸灯由两个部分组成
// 一个是由亮到暗的过程,一个是由暗到亮的过程
// 我们是在固定的频率下通过调整“高电平”的占空比来调控led灯的亮度    ;定义一个LED灯高占空比递增/递减信号inc_dec_flag
// LED灯的亮度由亮到暗变化,就是LED灯信号的高占空比开始递减        inc_dec_flag=1'b1
// LED灯的亮度由暗到亮变化,就是LED灯信号的高占空比开始递增        inc_dec_flag=1'b0
// 系统时钟周期为20ns(50MHz)
// 计时2us=100*20ns——100个周期;从0开始到99     计时4us=200*20ns——200个周期;从0开始到199
// 计时2ms=1000*2us——1000个周期;从0开始到999   计时4ms=1000*4us——1000个周期;从0开始到999
// 计时2s=1000*2ms——1000个周期;从0开始到999    计时4s=1000*4ms——1000个周期;从0开始到999
// 故在2ms从0到999计数时,此时2s计数器进1,故2ms计数值小于等于2s计数器的个数从1到1000在逐渐增多,且每次以2us增加
// 可以定义在2ms小于等于2s计数器值时,给led高电平(变亮)

2.按键消抖模块

// 按键消抖
// 原理:滤除按键值保持时间小于20ms的信号
// 在按键被按下或者被释放时导致按键值产生变化时,从20ms开始倒计时,
// 如果倒计时结束后,按键值仍然保持不变,则认为是一次有效的按键事件。
// 否则,认为是一次无效的按键事件。
// 有效的按键事件会被传递到下一个模块,无效的按键事件会被忽略。
// 该模块的输入为按键信号,输出为有效的按键事件。
// 系统时钟为50MHz,时钟周期为20ns。

module keydebounce (
    input clk, // 系统时钟
    input rst, // 复位信号

    output reg rst_filter
);

parameter CNT_MAX = 20'd1000000;//消抖时间20ms

reg [19:0] cnt;
reg key_d0;//将按键信号延迟一个时钟周期
reg key_d1;//将按键信号延迟两个时钟周期

// 按键信号的延迟
always @(posedge clk ) begin
    key_d0 <= rst;
    key_d1 <= key_d0;
end

// 按键消抖计数器——计时20ms
always @(posedge clk ) begin
    if(key_d1 != key_d0) //按键状态发生变化
        cnt <= CNT_MAX; // 开始计时
    else begin  //按键状态保持不变
        if(cnt > 20'd0) //计数器开始递减
            cnt <= cnt - 1'b1;
        else
            cnt <= 20'd0; //计数器归零
    end
end
// 按键有效输出
always @(posedge clk ) begin
    if(cnt == 20'd1) //计数器归零,按键有效
        rst_filter <= key_d1;
    else //计数器未归零,按键无效
        rst_filter <= rst_filter;
end
    
endmodule

3.呼吸灯模块

module breath_led (
    input clk,
    input rst,

    output reg led
    
);

parameter CNT_2US_MAX = 7'd100;
parameter CNT_2MS_MAX = 10'd1000;
parameter CNT_2S_MAX = 10'd1000;

reg[8:0] cnt_2us;
reg[9:0] cnt_2ms;
reg[9:0] cnt_2s;
reg inc_dec_flag;    

//计数2us
always@(posedge clk or negedge rst)begin
    if(!rst)
        cnt_2us <= 7'b0;
    else if(cnt_2us == (CNT_2US_MAX-7'b1))
        cnt_2us <= 7'b0;
    else
        cnt_2us <= cnt_2us + 7'b1; 
end

//计数2ms
always@(posedge clk or negedge rst)begin
    if(!rst)
        cnt_2ms <= 10'b0;
    else if(cnt_2ms == (CNT_2MS_MAX-10'b1) && cnt_2us == (CNT_2US_MAX-7'b1))
        cnt_2ms <= 10'b0;
    else if(cnt_2us == (CNT_2US_MAX-7'b1))
        cnt_2ms <= cnt_2ms + 10'b1;
    else
        cnt_2ms <= cnt_2ms;
end

//计数2s
always@(posedge clk or negedge rst)begin
    if(!rst)
        cnt_2s <= 10'b0;
    else if(cnt_2s == (CNT_2S_MAX-10'b1) && cnt_2ms == (CNT_2MS_MAX-7'b1) && cnt_2us == (CNT_2US_MAX-7'b1))
        cnt_2s <= 10'b0;
    else if(cnt_2us == (CNT_2US_MAX-7'b1) && cnt_2ms == (CNT_2MS_MAX-7'b1))
        cnt_2s <= cnt_2s + 10'b1;
    else
        cnt_2s <= cnt_2s;
end

// LED灯的亮度由亮到暗变化,就是LED灯信号的高占空比开始递减        inc_dec_flag=1'b1
// LED灯的亮度由暗到亮变化,就是LED灯信号的高占空比开始递增        inc_dec_flag=1'b0
    
always@(posedge clk or negedge rst)begin
    if(!rst)
        inc_dec_flag <= 1'b0;
    else if(cnt_2s == (CNT_2S_MAX-10'b1) && cnt_2ms == (CNT_2MS_MAX-7'b1) && cnt_2us == (CNT_2US_MAX-7'b1))
        inc_dec_flag <= ~inc_dec_flag;
    else
        inc_dec_flag <= inc_dec_flag;
end

    
// 定义在2ms小于等于2s计数器值时,给led高电平(变亮)
always@(posedge clk or negedge rst)begin
    if(!rst)
        led <= 1'b1;//led灯初始状态为高电平,本项目的灯低电平点亮
    else if((inc_dec_flag == 1'b1 && cnt_2ms >= cnt_2s) || (inc_dec_flag == 1'b0 && cnt_2ms <= cnt_2s))
        led <= 1'b0;
    else
        led <= 1'b1;
end
    
endmodule

4.顶层模块

//将呼吸灯模块通过例化到顶层
module top_breath_led(
    input clk,
    input rst,

    output  led1,    //2s
    output  led2    //4s
);

wire rst_filter; // 按键消抖后的值

// 实例化按键消抖模块
keydebounce u_keydebounce (
    .clk(clk),
    .rst(rst),
    .rst_filter(rst_filter)
);

// 实例化呼吸灯模块
// 2s
breath_led #(
    .CNT_2US_MAX(7'd100),
    .CNT_2MS_MAX(10'd1000),
    .CNT_2S_MAX(10'd1000)
) u_breath_led1(
    .clk(clk),
    .rst(rst_filter),
    .led(led1)
);

// 4s
breath_led #(
    .CNT_2US_MAX(8'd200),
    .CNT_2MS_MAX(10'd1000),
    .CNT_2S_MAX(10'd1000)
) u_breath_led2(
    .clk(clk),
    .rst(rst_filter),
    .led(led2)
);

endmodule

5.上板验证

IO定义如下,其中LED1为实图中的绿色灯( Y19),LED2为红色灯(AA19),时钟接口为Y9,rst为用户按键2(A17)
在这里插入图片描述
在这里插入图片描述
具体扩展版引脚分配图如下:
在这里插入图片描述
如图可视,频率不一致的呼吸效果:
在这里插入图片描述

总结

以上就是今天要讲的内容,本文仅仅简单介绍了XILINX ZYNQ7020的使用,如有任何问题请发送邮件至:zelinliu@nuaa.edu.cn


http://www.kler.cn/news/302260.html

相关文章:

  • 【短距离通信】【WiFi】精讲WiFi P2P discovery阶段
  • Python世界:基于PESQ的自动化语音打分脚本实践
  • 【安当产品应用案例100集】016-如何实现人大金仓数据库的透明加密及访问控制
  • 从搜索热度上看Arcgis的衰退
  • 初识php库管理工具composer的体验【爽】使用phpword模板功能替换里面的字符串文本
  • 鸿蒙开发5.0【帧率】解析
  • 排序链表(归并排序)
  • 2024年AI智能电销机器人为什么那么火爆
  • 阿里巴巴1688中国站商品搜索API返回值深度解析与实战应用
  • 四川财谷通赋能抖音小店前景璀璨
  • 【828华为云征文|手把手教你如何用华为云Flexus X实例部署之前爆火的“人生重启“游戏】
  • SpringBoot基础 -- 高级特性
  • 浅谈C#之线程创建和管理
  • 基于深度学习的多模态信息检索
  • MapBox Android版开发 4 国际化功能v11
  • 什么不建议通过 `Executors` 构建线程池?
  • 抓包工具检测手把手教学 - 某招聘网站
  • 7-6 列出连通集
  • pyqt自定义文本编辑器
  • TCP通信实现
  • 2024 天池云原生编程挑战赛决赛名单公布,9 月 20 日开启终极答辩
  • 【从0开始在CentOS 9中安装redis】
  • Windows编译Hikari-LLVM15[llvm-18.1.8rel]并集成到Android Studio NDK
  • openVX加速-常见问题:适用场景、AI加速、安装方式等
  • 模板(C++)
  • Java中的List与Set转换
  • jantic/DeOldify部署(图片上色)附带Dockerfile和镜像
  • Linux下的系统接口(实时更新)
  • 人工智能安全治理框架导图
  • 【泰克生物】酵母单杂交技术在基因调控研究中的应用