MYIR zynq fpga 学习过程(4)流水灯以及呼吸灯

前言

从这节开始算是正式接触代码了,像创建工程等重复性操作就不再写上来了。

流水灯

创建代码文件

  • 添加源文件
    在这里插入图片描述
  • 选择create file,并为文件命名,然后finish,OK
    在这里插入图片描述

编写代码

  • 确定输入输出
module led(
    input          sys_clk  ,  //系统时钟
    input          sys_rst_n,  //系统复位,低电平有效
    output  [2:0]  rgb_led         //三色的LED灯
    );
  • 确定其他参数

确定参数的时候要注意位宽。其中,时钟频率为50Mhz,则意味着计数器的位宽需要能容纳 5 ∗ 1 0 7 5*10^7 5107次的计数,那么位宽为26位。
而颜色有3钟,那么位宽为3位。

reg  [25:0]  cnt ;	//定时计数器
reg  [2:0]   led_count;//led切换
reg  [2:0]	  temp_rgb_led;//暂存变量
  • 确定时钟计数模块
always @ (posedge sys_clk or negedge sys_rst_n)		begin
    if(!sys_rst_n)	//下降沿复位
        cnt <= 26'd0;	//时钟清零
    else if(cnt < 26'd5000_0000)	//计数器在0~5000_000之间进行计数
        cnt <= cnt + 1'b1;
    else
        cnt <= 26'd0;
end	
  • 确定三色灯模块
always@(posedge sys_clk or negedge sys_rst_n)	begin //注意三色灯是共阳极接法
      if(!sys_rst_n)
           temp_rgb_led <= 3'b111;
      else begin
      case(led_count)	//切换三色灯颜色
            3'd0: temp_rgb_led <= 3'b110;
            3'd1: temp_rgb_led <= 3'b101;
            3'd2: temp_rgb_led <= 3'b011;
            3'd3: temp_rgb_led <= 3'b000;
           default : temp_rgb_led <= 3'b111;
       endcase 
       end
end 
  • 将暂变量赋值
assign rgb_led = temp_rgb_led;

设置IO口约束

  • 点击Open Elaborated Design
    在这里插入图片描述

  • 生成网表文件,可以查看RTL图
    在这里插入图片描述

  • 点出latout的IO planning
    在这里插入图片描述

  • 分配IO口,改变IO std
    在这里插入图片描述

  • 保存约束文件,并命名
    在这里插入图片描述

  • 连接开发板,生成比特流文件
    在这里插入图片描述

  • 比特文件生成后,打开硬件调试
    在这里插入图片描述

  • Open target

  • 在这里插入图片描述

  • 编译文件,大功告成
    在这里插入图片描述

呼吸灯

PWM模块

  • 确定参数

其中占空比14位是因为1.2KHZ,而时钟为12MHZ,12M/1.2K=10000,转为2进制则14位

    reg		[13:0] period_cnt;//1.2khz,占空比周期
    reg  	    [13:0] duty_cycle;//占空比
    reg			   inc_dec_flag;//0由暗到亮,1由亮到暗
  • PWM计数
always@(posedge sys_clk or negedge sys_rst_n)		begin	
    if(!sys_rst_n)	//下降沿复位
        period_cnt <= 14'd0;	
    else if(period_cnt < 14'd1_0000)			//计数器在0~10000之间进行计数,在数字中间加入下划线不影响数值本身,只是方便阅读
        period_cnt <= period_cnt + 1'b1;
    else
        period_cnt <= 14'd0;
end
  • PWM模块
always@(posedge sys_clk or negedge sys_rst_n)		begin	
	if(!sys_rst_n)	begin//下降沿复位
		duty_cycle   <= 14'b0;
		inc_dec_flag <= 1'b0;
	end
	else	begin
		if(period_cnt == 14'd1_0000)	begin
			if(!inc_dec_flag)	begin
				if(duty_cycle == 14'd1_0000)	begin
					inc_dec_flag <= 1'b1;
				end
				else	begin
					duty_cycle <= duty_cycle + 14'd100;//呼吸灯变化速度为1%
				end
			end
			else	begin
				if(duty_cycle == 14'd0)	begin
					inc_dec_flag <= 1'b0;
				end
				else	begin
					duty_cycle <= duty_cycle - 14'd100;//呼吸灯变化速度为1%
				end
			end
		end
	end
end

-整体代码

module breath_led(
	input sys_clk,		//12mhz时钟
	input sys_rst_n,
	output reg [2:0] rgb_led
    );
    reg		[13:0] period_cnt;//1.2khz,占空比周期
    reg  	[13:0] duty_cycle;//占空比
    reg			   inc_dec_flag;//0由暗到亮,1由亮到暗
    reg		[23:0] cnt;
    reg  	[2:0]  led_count;//led切换
    
always@(posedge sys_clk or negedge sys_rst_n)		begin	
    if(!sys_rst_n)	//下降沿复位
        cnt <= 24'd0;	//时钟清零
    else if(cnt < 24'd1200_0000)	//计数器在0~1200000之间进行计数,在数字中间加入下划线不影响数值本身,只是方便阅读
        cnt <= cnt + 1'b1;
    else
        cnt <= 24'd0;
end	

always@(posedge sys_clk or negedge sys_rst_n)		begin	
    if(!sys_rst_n)	//下降沿复位
        period_cnt <= 14'd0;	
    else if(period_cnt < 14'd1_0000)			//计数器在0~10000之间进行计数,在数字中间加入下划线不影响数值本身,只是方便阅读
        period_cnt <= period_cnt + 1'b1;
    else
        period_cnt <= 14'd0;
end

always@(posedge sys_clk or negedge sys_rst_n)		begin	
	if(!sys_rst_n)	begin//下降沿复位
		duty_cycle   <= 14'b0;
		inc_dec_flag <= 1'b0;
	end
	else	begin
		if(period_cnt == 14'd1_0000)	begin
			if(!inc_dec_flag)	begin
				if(duty_cycle == 14'd1_0000)	begin
					inc_dec_flag <= 1'b1;
				end
				else	begin
					duty_cycle <= duty_cycle + 14'd100;//呼吸灯变化速度为1%
				end
			end
			else	begin
				if(duty_cycle == 14'd0)	begin
					inc_dec_flag <= 1'b0;
				end
				else	begin
					duty_cycle <= duty_cycle - 14'd100;//呼吸灯变化速度为1%
				end
			end
		end
	end
end

always@(posedge sys_clk or negedge sys_rst_n)	begin //控制三色灯颜色转换
      if(!sys_rst_n)
           led_count <= 3'd0;
      else if(cnt==24'd1200_0000)   //一秒切换一次
           led_count <= led_count + 1'b1;
      else if(led_count==3'd4)
           led_count <= 3'd0;
end  

always@(posedge sys_clk or negedge sys_rst_n)	begin //注意三色灯是共阳极接法
      if(!sys_rst_n)	begin
           rgb_led <= 3'b111;
      end
      
      else begin
		  if(period_cnt >= duty_cycle)	begin
			  case(led_count)	//切换三色灯颜色
					3'd0: rgb_led <= 3'b110;
					3'd1: rgb_led <= 3'b101;
					3'd2: rgb_led <= 3'b011;
					3'd3: rgb_led <= 3'b000;
				   default : rgb_led <= 3'b111;
			   endcase 
		  end
		  else	begin
		  		rgb_led <= 3'b111;
		  end
      end
end 
endmodule

剩下的IO约束和生成比特流代码就不再重复赘述了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值