回答

收藏

【课程2】FPGA控制LED动态

FPGA/DSP FPGA/DSP 3205 人阅读 | 0 人回复 | 2013-08-16

话说这么久了,哪些买板子的人到哪去了,最近也是忙了点,根据大家的反馈,有些入门的同学自己都学到后面去了,有搞ps2的,VGA的等,貌似把基本板的资源都学完了,但是本人还是为了广大入门FPGA的同学,还是一步一步来把,回头看看,收获甚多。
在介绍led广告灯玩法之前,我们一起回顾下第一课LED灯的程序。如下所示:
  module turn_on_led( output [8:1] LED // LED[1] ~ LED[8]  端口声明,输//入还是输出端口
);   
// 开发板上LED[1]在左,LED[8]在右
// 送1灭,送0亮
assign LED = 8'b10101010;// 点亮LED[1]、LED[3]、LED[5]、LED[7]
endmodule
verilog是以模块module设计作为并行进程模块,如上所示,每个module内含有端口什么,模块名称,逻辑控制语句。具体详见之前上传的入门教程,或者详细了解module请下载文件Verilog模块module.rar
上面程序直接输出高低电平控制led灯的状态,如果我们需要让led灯动起来,该怎么做?如果你写过单片机程序或者c语言,会想到先让一个灯亮,在让另外一个灯亮,顺序驱动多个led灯亮灭状态,则可以实现led灯的动态显示,如下程序所示,让你的led动起来。

*     文件名称:water_led.v
*     描述:流水灯,并会调整
module water_led(
  input        CLOCK_50,                // 板载时钟50MHz
  input        Q_KEY,                   // 板载按键RST
  output [8:1] LED                      // LED[1] ~ LED[8]
);   

//++++++++++++++++++++++++++++++++++++++
// 分频部分 开始
//++++++++++++++++++++++++++++++++++++++
reg [23:0] cnt;                         // 计数子

// 溢出后自动重新计数
always @ (posedge CLOCK_50, negedge Q_KEY)
  if (!Q_KEY)
    cnt <= 0;
  else
    cnt <= cnt + 1'b1;

wire led_clk = cnt[23];                 // 每(2^24/50M = 0.3355)sec取一次
//--------------------------------------
// 分频部分 结束
//--------------------------------------

//++++++++++++++++++++++++++++++++++++++
// 流水灯部分 开始
//++++++++++++++++++++++++++++++++++++++
reg [8:1] led_r;                        // 定义输出寄存器
reg       dir;                          // 循环方向控制

always @ (posedge led_clk, negedge Q_KEY)
  if (!Q_KEY)                           // 复位后右移
    dir <= 0;                       
  else
    // 到达左右端点否?到达则换向
    if(led_r == 8'h7F && dir == 0)
      dir <= 1;
    else if(led_r == 8'h01 && dir == 1)
      dir <= 0;

always @ (posedge led_clk, negedge Q_KEY)
  if (!Q_KEY)                           // 复位后右移              
    led_r <= 8'h01;         
  else
    // 根据dir,左右移位
    // 注意:LED实际移位方向与led_r移位方向相反
    // 因为开发板上LED[1]在左,LED[8]在右
    if(!dir)
      led_r <= (led_r << 1) + 1'b1;     // LED右移;加法比移位的运算优先级高
    else
      led_r <= (led_r >> 1);            // LED左移

// 为什么要取反?
// 因为开发板上的LED是送0亮,送1灭
assign LED = ~led_r;                    // 寄存器输出
//--------------------------------------
// 流水灯部分 结束
//--------------------------------------
Endmodule

懂了?懂了就上传你的设计代码与视频,一起分享你的学习笔记。





分享到:
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条