按键与数码管显示
//学习按键识别,FPGA检测
//key1 key2 key3 key4的状态作为数据输入,数码管作为状态显示 //视频教程适合我们21EDA电子的所有学习板 module key_led(clk_50M,key,duan_ma,wei_ma);
input clk_50M; //系统时钟50M输入 从12脚输入。 input [3:0] key; //key1 key2 key3 key4为输入的键码的值 output [3:0] wei_ma; //数码管的位选
output [7:0] duan_ma; //数码管的段码ABCDEFGH wire [3:0] key; reg [7:0] duan_ma; reg [3:0] wei_ma;
reg [3:0] key_temp; //设置了一个寄存器 always @ (posedge clk_50M ) begin
key_temp<=key; //把键码的值赋给寄存器 case ( key_temp )
4'b1110:duan_ma<=8'b1111_1001; //段码//KEY1按下去显示1 4'b1101:duan_ma<=8'b1010_0100; //段码//KEY2按下去显示2 4'b1011:duan_ma<=8'b1011_0000; //段码//KEY3按下去显示3 4'b0111:duan_ma<=8'b1001_1001; //段码//KEY4按下去显示4 endcase end
always @ ( posedge clk_50M ) begin
case( key_temp )
4'b0111:wei_ma<=4'b0111; //位选信号 4'b1011:wei_ma<=4'b1011; 4'b1101:wei_ma<=4'b1101; 4'b1110:wei_ma<=4'b1110; endcase end
endmodule 拨码开关_LED
//拨码开关的 1 2 3 4 5 6 7 8作为输入 //本实验采用拨码开关来控制LED灯
//当然如果你的学习板没有拨码开关,可以用key1 key2 key3 key4 作为输入。 //视频教程适合我们21EDA电子的所有学习板 module led( switch, led ); // 模块名led input [7:0] switch; //拨码开关 output [7:0] led; //LED灯输出显示
assign led =switch; //把拨码开关的数据在LED灯上面显示 endmodule 还没弄懂 除法器
//两个3位二进制数的除法,结果(整数商)输出到数码管显示 module div(a,b,c,en);
input[2:0] a,b;//a 被除数,b 除数 output[7:0] c; reg[7:0] c; output[7:0] en;
reg[3:0] c_tmp;//商(整数部分)
reg[2:0] temp_reg;//计算的中间结果寄存器 integer i; assign en=0;
always@(a or b or temp_reg) begin temp_reg=0; c_tmp=0; if(b==0) c_tmp=4'he; else begin if(a[2]>=b) begin c_tmp[2]=1; temp_reg[2]=a[2]-b; end else begin c_tmp[2]=0; temp_reg[2]=a[2]; end if({temp_reg[2],a[1]}>=b) begin c_tmp[1]=1; temp_reg[2:1]={temp_reg[2],a[1]}-b; end else begin c_tmp[1]=0; temp_reg[2:1]={temp_reg[2],a[1]}; end if({temp_reg[2:1],a[0]}>=b) begin c_tmp[0]=1; temp_reg=0; end else begin c_tmp[0]=0; temp_reg=0;
end end end
always@(c_tmp) begin case(c_tmp) 4'b0000: c=8'b11000000; 4'b0001: c=8'b11111001; 4'b0010: c=8'b10100100; 4'b0011: c=8'b10110000; 4'b0100: c=8'b10011001; 4'b0101: c=8'b10010010; 4'b0110: c=8'b10000010; 4'b0111: c=8'b11111000; 4'b1000: c=8'b10000000; 4'b1001: c=8'b10010000; 4'b1010: c=8'b10001000; 4'b1011: c=8'b10000011; 4'b1100: c=8'b11000110; 4'b1101: c=8'b10100001; 4'b1110: c=8'b10000110; 4'b1111: c=8'b10001110; endcase end
endmodule
串口与电脑通信
//本模块的功能是验证实现和PC机进行基本的串口通信的功能。需要在 //PC机上安装一个串口调试工具来验证程序的功能。
//程序实现了一个收发一帧10个bit(即无奇偶校验位)的串口控 //制器,10个bit是1位起始位,8个数据位,1个结束
//位。串口的波特律由程序中定义的div_par参数决定,更改该参数可以实 //现相应的波特率。程序当前设定的div_par 的值是0x145,对应的波特率是 //9600。用一个8倍波特率的时钟将发送或接受每一位bit的周期时间 //划分为8个时隙以使通信同步.
//程序的工作过程是:串口处于全双工工作状态,按动key1,FPGA向PC发送“21 EDA\//字符串(串口调试工具设成按ASCII码接受方式);PC可随时向FPGA发送0-F的十六进制
//数据,FPGA接受后显示在7段数码管上。 //视频教程适合我们21EDA电子的所有学习板
module serial(clk,rst,rxd,txd,en,seg_data,key_input,lowbit); input clk,rst;
input rxd;//串行数据接收端 input key_input;//按键输入 output[7:0] en;
output[7:0] seg_data; reg[7:0] seg_data;
output txd;//串行数据发送端 output lowbit; // 没弄明白
////////////////////inner reg////////////////////
reg[15:0] div_reg;//分频计数器,分频值由波特率决定。分频后得到频率8倍波特率的时钟 reg[2:0] div8_tras_reg;//该寄存器的计数值对应发送时当前位于的时隙数 reg[2:0] div8_rec_reg;//该寄存器的计数值对应接收时当前位于的时隙数 reg[3:0] state_tras;//发送状态寄存器 reg[3:0] state_rec;//接受状态寄存器
reg clkbaud_tras;//以波特率为频率的发送使能信号 reg clkbaud_rec;//以波特率为频率的接受使能信号
reg clkbaud8x;//以8倍波特率为频率的时钟,它的作用是将发送或接受一个bit的时钟周期分为8个时隙
reg recstart;//开始发送标志 reg recstart_tmp;
reg trasstart;//开始接受标志 reg rxd_reg1;//接收寄存器1
reg rxd_reg2;//接收寄存器2,因为接收数据为异步信号,故用两级缓存 reg txd_reg;//发送寄存器
reg[7:0] rxd_buf;//接受数据缓存 reg[7:0] txd_buf;//发送数据缓存
reg[2:0] send_state;//每次按键给PC发送\字符串,这是发送状态寄存器 reg[19:0] cnt_delay;//延时去抖计数器 reg start_delaycnt;//开始延时计数标志
reg key_entry1,key_entry2;//确定有键按下标志 ////////////////////////////////////////////////
parameter div_par=16'h145;//分频参数,其值由对应的波特率计算而得,按此参数分频的时钟频率是波倍特率的8 //倍,此处值对应9600的波特率,即分频出的时钟频率是9600*8 (CLK 50M) //////////////////////////////////////////////// assign txd=txd_reg; assign lowbit=0;
assign en=0;//7段数码管使能信号赋值 always@(posedge clk ) begin if(!rst) begin cnt_delay<=0; start_delaycnt<=0; end else if(start_delaycnt) begin if(cnt_delay!=20'd800000) begin cnt_delay<=cnt_delay+1; end else begin cnt_delay<=0; start_delaycnt<=0; end end else begin if(!key_input&&cnt_delay==0) start_delaycnt<=1; end end
always@(posedge clk) begin if(!rst) key_entry1<=0; else begin if(key_entry2) key_entry1<=0; else if(cnt_delay==20'd800000) begin if(!key_input) key_entry1<=1; end end end
always@(posedge clk ) begin if(!rst)