赞
踩
目录
我们要搞懂数码管首先要明白几个概念。
我们先看一个数码管
一个数码管是由a、b、c、d、e、f、g、dp八个二极管组成,八个LED一端接在一起,另一端引脚引出来。二极管如果阳极连在一起,就是共阳极数码管,阴极连在一起,就是共阴极数码管。
如上图,是一个共阴极数码管,要使数码管显示不同的数字,只需点亮对应LED即可。如:数码管显示“0”,则a、b、c、d、e、f六个LED亮,g、dp这俩个LED灭,即可显示“0”。
如果是一个数码管我们需要控制八个led来控制显示 如果是四个 理论上需要控制三十二个 太多了 我们这时候就引用了共阴和共阳的概念。
我们来看原理图(这里我这个板子是共阳,共阴同理)
一共只需要十二个引脚即可,四个段选 八个位选 通过D1234 不同的高低电平可以控制哪个数码管亮 通过给abcdefg dp 不同的高低电平 可以控制数码管显示什么
如果没学过51单片机的朋友可能还不理解如何实现控制四位数码管 看原理图 好像一个时刻只能显示一个数 这里运用了人类视觉的偏差 即当不同的数码管切换速度足够快 则可以出现同时显示的偏差 也就实现了四位数码管的显示
接着我们先看
这个就比较容易实现 我们按照原理图找到对应引脚(有些可以自己定义)
在下面选择pin planner 配置自己的引脚 (自行配置)
配置好了之后 全局编译 然后导入板子
选中里面sof文件 点击start 导入 (前面文章介绍过 这里也只简单介绍一遍)
- module KC14(clk,rst,seg,sel);
- input clk;
- input rst;
- output reg[7:0] seg;
- reg[1:0] num;
- output reg[3:0] sel;
-
- always@(posedge clk or negedge rst)
- begin
- begin
- if(!rst)
- seg<=8'b1111_1111;
- sel<=4'b1111;
- end
- else
- begin
- seg<=8'b1010_0100;//选位 亮具体哪个led 控制数码管显示数字
- sel<=4'b0111;//段选 控制哪个数码管亮
- end
- end
-
- endmodule
简单分析一下 大家应该对verilog语言有了基础的认识 主要讲一下段选和位选
段选 因为是共阳 而是D1 D2 D3 D4 为高电平即可 但是我们可以注意到 我给的是0
因为我们原理图接了一个
当给0电平时导通 这样我们通过控制四位二进制 0000到 1111 来控制哪个数码管亮 也就是段选
然后我们在上面也介绍过 abcdefg dp(.) 这八个led 我们通过给0 来控制数码管显示什么数字
上面例子给的是 8'b1010_0100 也就是2 我们想实现不同的数字对应不同的八位二进制数 大家可以自己尝试改变一下。
原理与上面类似 就不赘述了 主要加了一个定时 和 不同数码管的切换 如果上面例子看懂了 这里直接看代码应该就可以看懂 这里实现的是四个数码管 1234 定时1s 每秒切换 1234 分别显示
- module KC5(clk,rst,seg,sel);
- input clk;
- input rst;
- output reg[7:0] seg;
- reg[1:0] num;
- output reg[3:0] sel;
- reg[25:0] cnt;
- reg[25:0] clk_1s;
-
-
- always@(posedge clk or negedge rst)
- begin
- if(!rst)
- begin
- cnt=0;
- end
-
- else if(cnt==26'd24_999_999)
- cnt<=0;
- else
- cnt<=cnt+1;
- end
- //1s周期控制部分
- always@(posedge clk or negedge rst)
- begin
- if(!rst)
- clk_1s<=1;
- else if(cnt==26'd24_999_999)
- clk_1s<=~clk_1s;
- else
- clk_1s<=clk_1s;
- end
- always@(posedge clk_1s or negedge rst)
- begin
- if(!rst)
- begin
- seg<=8'b1111_1111;
- sel<=4'b0000;
- num<=0;
- end
- else
- begin
- case(num)
- 0:
- begin
- seg<=8'b1111_1001;
- sel<=4'b0111;
- num<=1;
- end
-
-
- 1:
- begin
- seg<=8'b1100_0100;
- sel<=4'b1011;
- num<=2;
- end
-
- 2:
- begin
- seg<=8'b1101_0000;
- sel<=4'b1101;
- num<=3;
- end
-
- 3:
- begin
- seg<=8'b1001_1001;
- sel<=4'b1110;
- num<=0;
- end
-
- default:num<=0;
- endcase
- end
- end
- endmodule
现象就是数码管1 显示1 数码管2 显示2 数码管3显示3 数码管4显示4 依次每秒转换
同一时刻 某个数码管 我们已经了解了 那么如何让四个数码管一起显示呢 这就需要我们在不同的段选中来回快速切换 当速度足够快时 就达到了我们想要的效果 四个数码管同时显示
- module KC6(clk,rst,seg,sel);
-
- input clk;
- input rst;
- output reg [7:0] seg;
- output reg [3:0] sel;
- reg [1:0] num;
- reg[16:0] cnt;
- reg[16:0] clk_1s;
-
- always@(posedge clk or negedge rst)
- begin
- if(!rst)
- begin
- cnt=0;
- end
-
- else if(cnt==26'd24_999)
- cnt<=0;
- else
- cnt<=cnt+1;
- end
- always@(posedge clk or negedge rst)
- begin
- if(!rst)
- clk_1s<=1;
- else if(cnt==26'd24_999)//注意区别上面 这里的cnt比上面的少 也就是转换的快
- clk_1s<=~clk_1s;//所以此时clk_1s不是1s
- else
- clk_1s<=clk_1s;
- end
-
-
- always@(posedge clk_1s or negedge rst)
- begin
- if(!rst)
- begin
- seg<=8'b1111_1111;
- sel<=4'b1111;
- end
-
- else
- begin
-
- case(num)
- 0:
- begin
- seg<=8'b1111_1001;
- sel<=4'b0111;
- num<=1;
- end
-
- 1:
- begin
- seg<=8'b1010_0100;
- num<=2;
- sel<=4'b1011;
- end
-
- 2:
- begin
- seg<=8'b1011_0000;
- num<=3;
- sel<=4'b1101;
- end
-
- 3:
- begin
- seg<=8'b1001_1001;
- num<=0;
- sel<=4'b1110;
- end
-
- default:num<=0;
-
- endcase
-
- end
- end
-
-
- endmodule
我么已经知道如何同时显示了 那么我们只需要多定义一个时钟 然后把上面的代码包含进来 就可以实现四位数码管同时显示 定时转换
这里我们要实现的是数码管1234 分别显示1234和4321 两者定时转换
- module KC7(clk,rst,seg,sel);
- output reg [7:0] seg;
- output reg [3:0] sel;
- input clk;
- input rst;
- reg num0;
- reg [1:0] num1;
- reg[26:0] clk1;
- reg[26:0] cnt;
- reg[26:0] clk_1s;
- reg[26:0]clk_2s;
-
- always@(posedge clk or negedge rst)
- begin
- if(!rst)
- begin
- cnt=0;
- end
-
- else if(cnt==26'd24_999)
- cnt<=0;
- else
- cnt<=cnt+1;
- end
- //1s周期控制部分
- always@(posedge clk )
- begin
- if(cnt==16'd24_999)
- clk_1s<=~clk_1s;
- else
- clk_1s<=clk_1s;
- end
-
- always@(posedge clk_1s or negedge rst)
- begin
- if(!rst)
- begin
- clk1<=0;
- end
-
- else if(clk1==16'd2499)
- begin
- clk_2s<=~clk_2s;
- clk1<=0;
- end
- else
- begin
- clk_2s=clk_2s;
- clk1<=clk1+1;
- if(num0==0)
- begin
- case (num1)
- 0:
- begin
- seg<=8'b1111_1001;
- sel<=4'b0111;
- num1<=1;
- end
- 1:
- begin
- seg<=8'b1010_0100;
- num1<=2;
- sel<=4'b1011;
- end
- 2:
- begin
- seg<=8'b1011_0000;
- num1<=3;
- sel<=4'b1101;
- end
- 3:
- begin
- seg<=8'b1001_1001;
- num1<=0;
- sel<=4'b1110;
- end
- default:num1<=0;
- endcase
- end
- else
- begin
- case (num1)
- 0:
- begin
- seg<=8'b1001_1001;
- sel<=4'b0111;
- num1<=1;
- end
- 1:
- begin
- seg<=8'b1011_0000;
- num1<=2;
- sel<=4'b1011;
- end
- 2:
- begin
- seg<=8'b1010_0100;
- num1<=3;
- sel<=4'b1101;
- end
- 3:
- begin
- seg<=8'b1111_1001;
- num1<=0;
- sel<=4'b1110;
- end
- default:num1<=0;
- endcase
- end
- end
- end
- always@(posedge clk_2s )
- begin
- num0=!num0;
- end
- endmodule
经验证 实验显现符合预期
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。