设为首页 加入收藏

TOP

「FPGA项目」—— 基于AMBA总线的流水灯控制系统(六)
2023-07-23 13:25:06 】 浏览:313
Tags:FPGA 项目 基于 AMBA 水灯控
= CU_state; end end WRITE_DATA_3 : begin if ( iHREADY ) begin CU_state <= READ_DATA_RO; end else begin CU_state <= CU_state; end end default: CU_state <= CONFIG_0; endcase end end

4.2 LED控制方法

LED灯的亮灭改变,是通过配置GPIO内的寄存器实现的,

具体来说,是借助总线信号HWDATA对GPIO的reg_DATA[7:4]寄存器进行配置,

在绪论章节中,我们介绍过LED_mode的编码方式:

    // LED_mode Parameters
    parameter    MODE0     = 4'b0001,
    parameter    MODE1     = 4'b0010,
    parameter    MODE2     = 4'b0100,
    parameter    MODE3     = 4'b1000,

LED_mode采用了One-hot编码,这是为了对HWDATA进行assign赋值的时候,判断条件写起来简便一些,

现在我们就可以设计出各种流水灯模式下的组合逻辑了,

各模式下的LED亮灭随时间改变是通过计时器辅助的,

也就是下面代码中的timer,timer是一个32位寄存器:

reg  [31:0]  timer   ;
always @ (posedge iHCLK or negedge iHRESETn)    begin
        if ( !iHRESETn )                           
            timer <= 32'd0;                     // when the reset signal valid,time counter clearing
        else if (timer == 32'd199_999_999)      // 4 seconds count(50M*4-1=199999999)
            timer <= 32'd0;                     // count done,clearing the time counter
        else
		    timer <= timer + 1'b1;              // timer counter = timer counter + 1
    end

本质是将每一秒分成了50M帧(系统工作时钟频率为50MHz),

我们用assign语句给不同的帧下的HWDATA赋不同的值就行了,

首先是普通流水灯模式(工作模式0):
(注意,下面的LED[3:0]在WRITE_DATA_0~3状态下将会作为HWDATA[7:4]对GPIO_DATA寄存器进行配置)

assign LED[3:0] =         
        // mode0 普通流水灯模式
        ( led_mode[0] && timer >= 32'd149_999_999 ) ? 4'b0111 : // LED4亮 
        ( led_mode[0] && timer >= 32'd99_999_999  ) ? 4'b1011 : // LED3亮
        ( led_mode[0] && timer >= 32'd49_999_999  ) ? 4'b1101 : // LED2亮
        ( led_mode[0]                             ) ? 4'b1110 : // LED1亮  
....(其他模式)

这里就体现出One-hot编码的好处了,可以用( led_mode[0] )作为是否处于模式0的判定,
否则需要写成( led_mode == MODE_0 ),

接下来是加速流水灯模式(工作模式1):

assign LED[3:0] =         
        // mode1 加速流水灯模式
        ( led_mode[1] && timer >= 32'd174_999_999 ) ? 4'b0111 : // LED4亮 
        ( led_mode[1] && timer >= 32'd149_999_999 ) ? 4'b1011 : // LED3亮
        ( led_mode[1] && timer >= 32'd124_999_999 ) ? 4'b1101 : // LED2亮
        ( led_mode[1] && timer >= 32'd99_999_999  ) ? 4'b1110 : // LED1亮
        ( led_mode[1] && timer >= 32'd74_999_999  ) ? 4'b0111 : // LED4亮  
        ( led_mode[1] && timer >= 32'd49_999_999  ) ? 4'b1011 : // LED3亮
        ( led_mode[1] && timer >= 32'd24_999_999  ) ? 4'b1101 : // LED2亮
        ( led_mode[1]                             ) ? 4'b1110 : // LED1亮   
....(其他模式)

心跳模式(工作模式2):

assign LED[3:0] =     
        // mode2 心跳模式
        ( led_mode[2] && timer >= 32'd189_999_999 ) ? 4'b0000 : // 全亮 
        ( led_mode[2] && timer >= 32'd179_999_999 ) ? 4'b1111 : // 全灭
        ( led_mode[2] && timer >= 32'd169_999_999 ) ? 4'b0000 : // 全亮
        ( led_mode[2]                             ) ? 4'b1111 : // 全灭
....(其他模式)

最后是呼吸灯模式(工作模式3),

该模式相对复杂一些,前面提到过是通过改变占空比控制LED灯亮度的,

占空比的改变是通过对timer的判断实现的,

举个例子:

assign LED[3:0] = 
        // 占空比 1/4  = 25%
        ( led_mode[3] && (timer >= 32'd89_999_999 )  && (timer[1:0] == 2'b00 )  ) ? 4'b0000 :
        ( led_mode[3] && (timer >= 32'd89_999_999 )                             ) ? 4'b1111 : 
....(其他模式)

(timer[1:0] == 2'b00 )的判定,在timer的值每增加4的过程中,必定出现且只出现1次

这样在 (timer >= 32'd89_999_999 )的这段期间内,

LED灯的驱动引脚就会在25%的时间里处于低电平(点亮),剩下的75%时间里处于高电平(熄灭),

同理,(timer[2:0] == 3'b0 )就能得到1/8的占空比,也就是12.5%,

这样就有:

assign LED[3:0] = 
        // mode3 呼吸灯模式
        // 占空比 0%
        ( led_mode[3] && (timer >= 32'd189_999_999)                             ) ? 4'b1111 : 
        // 占空比 1/64 = 1.56%  
        ( led_mode[3] && (timer >= 32'd169_999_999)  && (timer[5:0] == 6'b000)  ) ? 4'b0000 : 
        ( led_mode[3] && (timer >= 32'd169_999_999)                             ) ? 4'b1111 : 
        // 占空比 1/32 = 3.12%
        ( led_mode[3] && (timer >= 32'd149_999_999)  && (timer[4:0] == 5'b000)  ) ? 4'b0000 : 
        ( led_mode[3]
首页 上一页 3 4 5 6 7 8 9 下一页 尾页 6/10/10
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇ZYNQ基于DMA的串口传图 下一篇数字分频器设计(偶数分频、奇数..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目