1.开发板简介
1.1开发板布局
1.2引脚分配
2.开发板输入输出端口
2.1 verilog所有外设端口声明
module all(
input wire sys_clk,// 12M时钟 //PCLK-J5
input wire sys_rst_n,//K4 // J14
/************************LED****************************/
output wire [7:0]led,//LED8~LED1:K11,L11,K12,L15,M12,M14,N14,N15
/**********************RGBLED***************************/
output wire [2:0]RGBLED1,//MSB~LSB=BGR:E14,E15,G15
output wire [2:0]RGBLED2,//MSB~LSB=BGR:D12,C14,C15
/**********************轻触开关**************************/
input wire key1,key2,key3, //key1~key3:J9,K14,,J11
/**********************拨码开关**************************/
input wire sw1,sw2,sw3,sw4, //sw1~sw4:J12,H11,H12,H13
/*********************数码管*****************************/
/*| A | B | C | D | E | F | G | DP | SEG|数码管|
| E1| D2| K2| J2| G2| F5| G5| L1 | E2 | 1 |
| A3| A2| P2| P1| N1| C1| C2| R2 | B1 | 2 |*/
output wire [8:0] segment_led_1, //数码管1,MSB~LSB = SEG,DP,G,F,E,D,C,B,A
output wire [8:0] segment_led_2, //数码管2,MSB~LSB = SEG,DP,G,F,E,D,C,B,A
/**********************OLED*****************************/
output reg oled_clk,//GPIO35- B4
output reg oled_dat,//GPIO34- A5
output reg oled_rst,//GPIO33- A7
output reg oled_dcn,//GPIO32- B6
output reg oled_csn,//GPIO31- E7
/**********************CH340****************************/
input wire RX, //GPIO0- M4
output wire TX, // GPIO1 P3
/***********************BEEPER**************************/
output wire BEEPER,//GPIO16- R14
/***********************PWM*****************************/
output wire pwm, //GPIO17- P15
/***********************DS18B20*************************/
inout wire ds18b20_dq,// GPIO15- P12
/***********************ADC*****************************/
input wire ADC_SDO,//GPIO10- P7
output wire ADC_CLK,ADC_CS,//GPIO11- P8, GPIO12- P9
/***********************DAC*****************************/
output wire [9:0]DA //DA0~DA9:B15,B14,B13,A14,B11,A13,A11,A9,D10,B8
);
endmodule
2.2 TCL引脚绑定脚本
package require ::quartus::project
set_location_assignment PIN_P8 -to ADC_CLK
set_location_assignment PIN_P9 -to ADC_CS
set_location_assignment PIN_P7 -to ADC_SDO
set_location_assignment PIN_R14 -to BEEPER
set_location_assignment PIN_B8 -to DA[9]
set_location_assignment PIN_D10 -to DA[8]
set_location_assignment PIN_A9 -to DA[7]
set_location_assignment PIN_A11 -to DA[6]
set_location_assignment PIN_A13 -to DA[5]
set_location_assignment PIN_B11 -to DA[4]
set_location_assignment PIN_A14 -to DA[3]
set_location_assignment PIN_B13 -to DA[2]
set_location_assignment PIN_B14 -to DA[1]
set_location_assignment PIN_B15 -to DA[0]
set_location_assignment PIN_E14 -to RGBLED1[2]
set_location_assignment PIN_E15 -to RGBLED1[1]
set_location_assignment PIN_G15 -to RGBLED1[0]
set_location_assignment PIN_D12 -to RGBLED2[2]
set_location_assignment PIN_C14 -to RGBLED2[1]
set_location_assignment PIN_C15 -to RGBLED2[0]
set_location_assignment PIN_M4 -to RX
set_location_assignment PIN_P3 -to TX
set_location_assignment PIN_P12 -to ds18b20_dq
set_location_assignment PIN_J9 -to key1
set_location_assignment PIN_K14 -to key2
set_location_assignment PIN_J11 -to key3
set_location_assignment PIN_K11 -to led[7]
set_location_assignment PIN_L11 -to led[6]
set_location_assignment PIN_K12 -to led[5]
set_location_assignment PIN_L15 -to led[4]
set_location_assignment PIN_M12 -to led[3]
set_location_assignment PIN_M14 -to led[2]
set_location_assignment PIN_N14 -to led[1]
set_location_assignment PIN_N15 -to led[0]
set_location_assignment PIN_B4 -to oled_clk
set_location_assignment PIN_E7 -to oled_csn
set_location_assignment PIN_A5 -to oled_dat
set_location_assignment PIN_B6 -to oled_dcn
set_location_assignment PIN_A7 -to oled_rst
set_location_assignment PIN_P15 -to pwm
set_location_assignment PIN_E2 -to segment_led_1[8]
set_location_assignment PIN_L1 -to segment_led_1[7]
set_location_assignment PIN_G5 -to segment_led_1[6]
set_location_assignment PIN_F5 -to segment_led_1[5]
set_location_assignment PIN_G2 -to segment_led_1[4]
set_location_assignment PIN_J2 -to segment_led_1[3]
set_location_assignment PIN_K2 -to segment_led_1[2]
set_location_assignment PIN_D2 -to segment_led_1[1]
set_location_assignment PIN_E1 -to segment_led_1[0]
set_location_assignment PIN_B1 -to segment_led_2[8]
set_location_assignment PIN_R2 -to segment_led_2[7]
set_location_assignment PIN_C2 -to segment_led_2[6]
set_location_assignment PIN_C1 -to segment_led_2[5]
set_location_assignment PIN_N1 -to segment_led_2[4]
set_location_assignment PIN_P1 -to segment_led_2[3]
set_location_assignment PIN_P2 -to segment_led_2[2]
set_location_assignment PIN_A2 -to segment_led_2[1]
set_location_assignment PIN_A3 -to segment_led_2[0]
set_location_assignment PIN_J12 -to sw1
set_location_assignment PIN_H11 -to sw2
set_location_assignment PIN_H12 -to sw3
set_location_assignment PIN_H13 -to sw4
set_location_assignment PIN_J5 -to sys_clk
set_location_assignment PIN_J14 -to sys_rst_n
3.信号发生器(简易方法)
3.1 Verilog代码
top.v
`include "key.v"
module top(
input wire sys_clk,// 12M时钟 //PCLK-J5
input wire sys_rst_n,//K4 // J14
/**********************轻触开关**************************/
input wire key1, //key1:J9,
/**********************拨码开关**************************/
input wire sw1,sw2,sw3,sw4, //sw1~sw4:J12,H11,H12,H13
/***********************DAC*****************************/
output [9:0]DA //DA0~DA9:B15,B14,B13,A14,B11,A13,A11,A9,D10,B8
//电压最大值2^10-1=1023单位
);
wire [15:0] cnt_max;//
wire key1_flag,key2_flag,key3_flag;
reg [1:0]mode;//0:方波 1:三角波 2:锯齿波
reg [16:0]cnt;
/**********************************/
assign cnt_max={sw1,sw2,sw3,sw4}?{sw1,sw2,sw3,sw4}*2048-1:3;
assign DA=((mode==1)?(cnt<(cnt_max+1)/2?({sw1,sw2,sw3,sw4}?cnt/{sw1,sw2,sw3,sw4}:cnt):({sw1,sw2,sw3,sw4}?(cnt_max-cnt)/{sw1,sw2,sw3,sw4}:(cnt_max-cnt))):
((mode==2)?cnt/{sw1,sw2,sw3,sw4}:
(cnt<(cnt_max-1)/2?0:10'd1023)));
always @(posedge key1_flag) begin
if(mode<2)
mode<=mode+1'b1;
else
mode<=0;
end
always @(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n) begin
cnt<=0;
end
else begin
if(cnt<cnt_max-1)
cnt<=cnt+1'b1;
else
cnt<=15'd0;
end
end
key key_inst1(
.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n),
.key_in(key1),
.key_flag(key1_flag)
);
endmodule
key.v
module key
#(
parameter KEY_CNT_MAX = 20'd239_999 //计数器计数最大值20ms
)
(
input sys_clk,sys_rst_n,
input key_in,
output reg key_flag
);
reg [19:0] cnt_20ms ; //计数器
/***************按键消抖**********************/
//cnt_20ms:如果时钟的上升沿检测到外部按键输入的值为低电平时,计数器开始计数
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_20ms <= 20'b0;
else if(key_in == 1'b1)
cnt_20ms <= 20'b0;
else if(cnt_20ms == KEY_CNT_MAX && key_in == 1'b0)
cnt_20ms <= cnt_20ms;
else
cnt_20ms <= cnt_20ms + 1'b1;
//key_flag:当计数满20ms后产生按键有效标志位
//且key_flag在999_999时拉高,维持一个时钟的高电平
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
key_flag <= 1'b0;
else if(cnt_20ms > KEY_CNT_MAX -1'b1)
key_flag <= 1'b1;
else
key_flag <= 1'b0;
/********************************************/
endmodule
3.2 Tcl引脚绑定脚本
package require ::quartus::project
set_location_assignment PIN_B8 -to DA[9]
set_location_assignment PIN_D10 -to DA[8]
set_location_assignment PIN_A9 -to DA[7]
set_location_assignment PIN_A11 -to DA[6]
set_location_assignment PIN_A13 -to DA[5]
set_location_assignment PIN_B11 -to DA[4]
set_location_assignment PIN_A14 -to DA[3]
set_location_assignment PIN_B13 -to DA[2]
set_location_assignment PIN_B14 -to DA[1]
set_location_assignment PIN_B15 -to DA[0]
set_location_assignment PIN_J9 -to key1
set_location_assignment PIN_J12 -to sw1
set_location_assignment PIN_H11 -to sw2
set_location_assignment PIN_H12 -to sw3
set_location_assignment PIN_H13 -to sw4
set_location_assignment PIN_J5 -to sys_clk
set_location_assignment PIN_J14 -to sys_rst_n
4.定时器(数码管显示)
4.1 TCL引脚绑定脚本
clock.tcl
package require ::quartus::project
set_location_assignment PIN_J5 -to sys_clk
set_location_assignment PIN_J14 -to sys_rst_n
set_location_assignment PIN_J9 -to key1
set_location_assignment PIN_N15 -to led
set_location_assignment PIN_E2 -to segment_led_1[8]
set_location_assignment PIN_L1 -to segment_led_1[7]
set_location_assignment PIN_G5 -to segment_led_1[6]
set_location_assignment PIN_F5 -to segment_led_1[5]
set_location_assignment PIN_G2 -to segment_led_1[4]
set_location_assignment PIN_J2 -to segment_led_1[3]
set_location_assignment PIN_K2 -to segment_led_1[2]
set_location_assignment PIN_D2 -to segment_led_1[1]
set_location_assignment PIN_E1 -to segment_led_1[0]
set_location_assignment PIN_B1 -to segment_led_2[8]
set_location_assignment PIN_R2 -to segment_led_2[7]
set_location_assignment PIN_C2 -to segment_led_2[6]
set_location_assignment PIN_C1 -to segment_led_2[5]
set_location_assignment PIN_N1 -to segment_led_2[4]
set_location_assignment PIN_P1 -to segment_led_2[3]
set_location_assignment PIN_P2 -to segment_led_2[2]
set_location_assignment PIN_A2 -to segment_led_2[1]
set_location_assignment PIN_A3 -to segment_led_2[0]
set_location_assignment PIN_R14 -to BEEPER
4.2 Verilog 代码
top.v
//`include "key.v"
//`include"divide.v"
//`include "segment.v"
//`include"counter.v"
//`include "led.v"
//`include "buzzer.v"
//`include "mode_s.v"
module top
(
input wire sys_clk, // 12M时钟
input wire sys_rst_n, //K4
output led, //指示当前模式20/30
input wire key1,
output wire [8:0] segment_led_1, //数码管1,MSB~LSB = SEG,DP,G,F,E,D,C,B,A
output wire [8:0] segment_led_2, //数码管2,MSB~LSB = SEG,DP,G,F,E,D,C,B,A
output wire BEEPER //蜂鸣器 计时结束响应
);
wire [3:0] secH,secL;
wire clk_1hz;
wire clk_2khz;
wire key_flag;
wire mode;
wire[3:0] secH_max;
wire co_ge,co_shi;
divide #(.divide_p(24'd12_000_000))//Clock
divide_inst_1hz
(
.clk_in(sys_clk),
.rst_n(sys_rst_n),
.clk_out(clk_1hz)
);
divide #(.divide_p(24'd6_000))//BEEPER
divide_inst_2khz
(
.clk_in(sys_clk),
.rst_n(sys_rst_n),
.clk_out(clk_2khz)
);
counter #(.W(4)) //个位数据
counter_ge(
.CLK(clk_1hz),
.Loadn(1'b1),
.CLRn(sys_rst_n),
.N(10),
.D(4'd0),
.Q(secL),
.Co(co_ge)
);
counter #(.W(4)) //十位数据
counter_shi(
.CLK(co_ge),
.Loadn(1'b1),
.CLRn(sys_rst_n),
.N(secH_max),
.D(4'd0),
.Q(secH),
.Co(co_shi)
);
segment seg_1( //十位数码管
.seg_data(secH),
.segment_led(segment_led_1)
);
segment seg_2( //个位数码管
.seg_data(secL),
.segment_led(segment_led_2)
);
key key1_inst //模式切换按键
(
.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n),
.key_in(key1),
.key_flag(key_flag)
);
led led_inst( //模式指示灯
.mode(mode),
.led(led)
);
buzzer buzzer_inst( //计时结束蜂鸣器响应
.freq(clk_2khz),
.enable(co_ge&co_shi),
.buzzer_out(BEEPER)
);
mode_s mode_inst( //模式切换
.key_flag(key_flag),
.mode(mode),
.secH_max(secH_max)
);
endmodule
segment.v
module segment(
input [3:0] seg_data,
output reg [8:0] segment_led//数码管1,MSB~LSB = SEG,DP,G,F,E,D,C,B,A
);
always @(*) begin
case(seg_data)
4'h0:
segment_led <= 9'h3f; //h3f=0 0011 1111=~SEG F E D C B A
4'h1:
segment_led <= 9'h06;
4'h2:
segment_led <= 9'h5b;
4'h3:
segment_led <= 9'h4f;
4'h4:
segment_led <= 9'h66;
4'h5:
segment_led <= 9'h6d;
4'h6:
segment_led <= 9'h7d;
4'h7:
segment_led <= 9'h07;
4'h8:
segment_led <= 9'h7f;
4'h9:
segment_led <= 9'h6f;
4'ha:
segment_led <= 9'h77;
4'hb:
segment_led <= 9'h7c;
4'hc:
segment_led <= 9'h39;
4'hd:
segment_led <= 9'h5e;
4'he:
segment_led <= 9'h79;
4'hf:
segment_led <= 9'h71;
default:
segment_led <= 9'h00;
endcase
end
endmodule
divide.v
module divide
#(
parameter divide_p = 24'd12_000_000 //偶分频系数 T=1s,duty=50% 12_000_000 5_999_999
)
(
input wire clk_in,
input wire rst_n,
output reg clk_out
);
reg [23:0] cnt;
always@(posedge clk_in or negedge rst_n) begin
if(rst_n == 1'b0) begin
cnt <= 23'b0;
clk_out<=0;
end
else if(cnt <(divide_p)/2-1)
cnt<=cnt+1'b1;
else begin
cnt<=23'b0;
clk_out<=~clk_out;
end
end
endmodule
counter.v
module counter
#(
parameter W=4
)(
input CLK,
input Loadn,
input CLRn,
input [W-1:0] N,
input [W-1:0] D,
output reg [W-1:0] Q,
output reg Co
);
always @(posedge CLK,negedge CLRn) begin
if(~CLRn) begin
Q <= 0;
Co <=0;
end
else if (~Loadn)
Q <= D;
else if(Q==N-1) begin
Q<=0;
Co<=1;
end
else begin
Q<=Q+1;
Co<=0;
end
end
endmodule
mode_s.v
module mode_s( //模式切换子模块
input key_flag,
output reg mode,
output reg [3:0] secH_max
);
always@(posedge key_flag) begin
mode<=!mode;
secH_max =(mode ?4'd3:4'd2);
end
endmodule
key.v
module key
#(
parameter KEY_CNT_MAX = 20'd239_999 //计数器计数最大值20ms
)
(
input sys_clk,sys_rst_n,
input key_in,
output reg key_flag
);
reg [19:0] cnt_20ms ; //计数器
/***************按键消抖**********************/
//cnt_20ms:如果时钟的上升沿检测到外部按键输入的值为低电平时,计数器开始计数
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_20ms <= 20'b0;
else if(key_in == 1'b1)
cnt_20ms <= 20'b0;
else if(cnt_20ms == KEY_CNT_MAX && key_in == 1'b0)
cnt_20ms <= cnt_20ms;
else
cnt_20ms <= cnt_20ms + 1'b1;
//key_flag:当计数满20ms后产生按键有效标志位
//且key_flag在999_999时拉高,维持一个时钟的高电平
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
key_flag <= 1'b0;
else if(cnt_20ms > KEY_CNT_MAX -1'b1)
key_flag <= 1'b1;
else
key_flag <= 1'b0;
/********************************************/
endmodule
led.v
module led (
input mode,
output led
);
assign led = mode;
endmodule
buzzer.v
module buzzer(
input freq,
input enable,
output buzzer_out
);
assign buzzer_out = (enable? freq : 1'b0);
endmodule
5.OLED显示
top.v
`include "divide.v"
`include "oled12832.v"
`include "segment.v"
module top(
input wire sys_clk,// 12M时钟
input wire sys_rst_n,//K4
/**********************轻触开关**************************/
input wire key1,key2,key3,
/*********************数码管*****************************/
output wire [8:0] segment_led_1, //数码管1,MSB~LSB = SEG,DP,G,F,E,D,C,B,A
output wire [8:0] segment_led_2, //数码管2,MSB~LSB = SEG,DP,G,F,E,D,C,B,A
/**********************OLED*****************************/
output wire oled_clk,
output wire oled_dat,
output wire oled_rst,
output wire oled_dcn,
output wire oled_csn,
/***********************BEEPER**************************/
output wire BEEPER//GPIO16- R14
);
reg [3:0] secH,secL;
reg[3:0] minH,minL;
wire clk_1hz;
/**********************************************/
always@(posedge clk_1hz or negedge sys_rst_n) begin
if(sys_rst_n == 1'b0) begin
secH <= 4'b0000;
secL <= 4'b0000;
minH <= 4'b0000;
minL <= 4'b0000;
end
else begin
if(secL == 4'd9) begin
secL <= 4'b0000;
if(secH == 4'd5) begin
secH<=4'b0000;
if(minL == 4'd9) begin
minL <= 4'b0000;
if(minH == 4'd5) begin
minH <= 4'b0000;
end
else
minH <= minH + 1'b1;
end
else
minL<=minL+1'b1;
end
else
secH <= secH + 1'b1;
end
else
secL <= secL + 1'b1;
end
end
/********************************************/
divide divide_inst(
.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n),
.clk_out(clk_1hz)
);
segment seg_inst(
.seg_data_1(secH),
.seg_data_2(secL),
.segment_led_1(segment_led_1),
.segment_led_2(segment_led_2)
);
oled12832 oled_inst(
.clk(sys_clk),
.rst(sys_rst_n),
.oled_clk(oled_clk),
.oled_dat(oled_dat),
.oled_rst(oled_rst),
.oled_dcn(oled_dcn),
.oled_csn(oled_csn),
.clk_1hz(clk_1hz),
.secH(secH),
.secL(secL),
.minH(minH),
.minL(minL)
);
/*******************************************/
endmodule
oled12832.v
// --------------------------------------------------------------------
// >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
// --------------------------------------------------------------------
// Module: OLED12832
//
// Author: Step
//
// Description: OLED12832_Driver,使用8*8点阵字库,每行显示128/8=16个字符
//
// Web: www.stepfpga.com
//
// --------------------------------------------------------------------
// Code Revision History :
// --------------------------------------------------------------------
// Version: |Mod. Date: |Changes Made:
// V1.0 |2015/11/11 |Initial ver
// --------------------------------------------------------------------
module oled12832
(
input wire clk,
input wire rst,
output reg oled_csn,oled_rst,oled_dcn,oled_clk,oled_dat,
input clk_1hz,
input wire [3:0] secH,
input wire [3:0] secL,
input wire [3:0] minL,
input wire [3:0] minH
);
localparam INIT_DEPTH = 16'd25; //初始化的命令的数量
localparam IDLE = 6'h1,
MAIN = 6'h2,
INIT = 6'h4,
SCAN = 6'h8,
WRITE = 6'h10,
DELAY = 6'h20;
localparam HIGH = 1'b1,
LOW = 1'b0;
localparam DATA = 1'b1,
CMD = 1'b0;
localparam time_long = 5 ;
localparam temp_long = 12;
reg [7:0] cmd[24:0] ;
reg [39:0] mem[123:0] ;
reg [159:0] font10x16_mem [17:0];
reg [255:0] font16x16_mem[3:0];
reg [7:0] y_p,x_ph, x_pl;
reg [(8*21-1):0] char;
reg [7:0] num, char_reg ;
reg [4:0] cnt_main ,cnt_init,cnt_clear,cnt_write;
reg [5:0]cnt_scan;
reg [15:0] num_delay, cnt_delay, cnt ;
reg [5:0] state , state_back;
reg [1:0]font;
always @(posedge clk or negedge rst) begin
if(!rst) begin
cnt_main <= 1'b0;
cnt_init <= 1'b0;
cnt_scan <= 1'b0;
cnt_write <= 1'b0;
y_p <= 1'b0;
x_ph <= 1'b0;
x_pl <= 1'b0;
num <= 1'b0;
char <= 1'b0;
char_reg <= 1'b0;
num_delay <= 16'd5;
cnt_delay <= 1'b0;
cnt <= 1'b0;
font <= 2'd0;
oled_csn <= HIGH;
oled_rst <= HIGH;
oled_dcn <= CMD;
oled_clk <= HIGH;
oled_dat <= LOW;
state <= IDLE;
state_back <= IDLE;
end
else begin
case(state)
IDLE: begin
cnt_main <= 1'b0;
cnt_init <= 1'b0;
cnt_clear <= 1'b0;
cnt_scan <= 1'b0;
cnt_write <= 1'b0;
y_p <= 1'b0;
x_ph <= 1'b0;
x_pl <= 1'b0;
num <= 1'b0;
char <= 1'b0;
char_reg <= 1'b0;
num_delay <= 16'd5;
cnt_delay <= 1'b0;
cnt <= 1'b0;
oled_csn <= HIGH;
oled_rst <= HIGH;
oled_dcn <= CMD;
oled_clk <= HIGH;
oled_dat <= LOW;
state <= MAIN;
state_back <= MAIN;
end
MAIN: begin
if (1) begin
if(cnt_main >= 5'd8)
cnt_main <= 5'd5;
else
cnt_main <= cnt_main + 1'b1;
case(cnt_main) //MAIN状态
5'd0: begin
state <= INIT;
end
// 清空屏幕
5'd1: begin
y_p <= 8'hb0;
x_ph <= 8'h10;
x_pl <= 8'h00;
num <= 5'd16;
char <= " ";
state <= SCAN;
end
5'd2: begin
y_p <= 8'hb1;
x_ph <= 8'h10;
x_pl <= 8'h00;
num <= 5'd16;
char <= " ";
state <= SCAN;
end
5'd3: begin
y_p <= 8'hb2;
x_ph <= 8'h10;
x_pl <= 8'h00;
num <= 5'd16;
char <= " ";
state <= SCAN;
end
5'd4: begin
y_p <= 8'hb3;
x_ph <= 8'h10;
x_pl <= 8'h00;
num <= 5'd16;
char <= " ";
state <= SCAN;
end
5'd5: begin
y_p <= 8'hb0;
x_ph <= 8'h12;/****00-80*******/
x_pl <= 8'h08;
num <= 5'd5;
font <= 2'd1;
char <= {4'h0,minH,4'h0,minL,(clk_1hz ? 8'd16:8'd17),4'h0,secH[3:0],4'h0,secL[3:0]};
state <= SCAN;
end
5'd6: begin
y_p <= 8'hb1;
x_ph <= 8'h12;
x_pl <= 8'h08;
num <= 5'd5;
font <= 2'd1;
state <= SCAN;
end
5'd7: begin
y_p <= 8'hb2;
x_ph <= 8'h12;
x_pl <= 8'h00;
num <= 5'd4;
font <= 2'd2;
char <= {8'd0,8'd1,8'd2,8'd3};
state <= SCAN;
end
5'd8: begin
y_p <= 8'hb3;
x_ph <= 8'h12;
x_pl <= 8'h00;
num <= 5'd4;
font <= 2'd2;
// char <= {"FPGA"};
state <= SCAN;
end
default:
state <= IDLE;
endcase
end
end
INIT: begin //初始化状态
case(cnt_init)
5'd0: begin
oled_rst <= LOW;
cnt_init <= cnt_init + 1'b1;
end //复位有效
5'd1: begin
num_delay <= 16'd25000;
state <= DELAY;
state_back <= INIT;
cnt_init <= cnt_init + 1'b1;
end //延时大于3us
5'd2: begin
oled_rst <= HIGH;
cnt_init <= cnt_init + 1'b1;
end //复位恢复
5'd3: begin
num_delay <= 16'd25000;
state <= DELAY;
state_back <= INIT;
cnt_init <= cnt_init + 1'b1;
end //延时大于220us
5'd4: begin
if(cnt>=INIT_DEPTH) begin //当25条指令及数据发出后,配置完成
cnt <= 1'b0;
cnt_init <= cnt_init + 1'b1;
end
else begin
cnt <= cnt + 1'b1;
num_delay <= 16'd5;
oled_dcn <= CMD;
char_reg <= cmd[cnt];
state <= WRITE;
state_back <= INIT;
end
end
5'd5: begin
cnt_init <= 1'b0;
state <= MAIN;
end //初始化完成,返回MAIN状态
default:
state <= IDLE;
endcase
end
SCAN: begin //刷屏状态,从RAM中读取数据刷屏
if (font==2'd0) begin // 一页数据的刷屏
if(cnt_scan == 5'd11) begin
if(num)
cnt_scan <= 5'd3;
else
cnt_scan <= cnt_scan + 1'b1;
end
else if(cnt_scan == 5'd12)
cnt_scan <= 1'b0;
else
cnt_scan <= cnt_scan + 1'b1;
case(cnt_scan)
5'd0: begin
oled_dcn <= CMD;
char_reg <= y_p;
state <= WRITE;
state_back <= SCAN;
end //定位列页地址
5'd1: begin
oled_dcn <= CMD;
char_reg <= x_pl;
state <= WRITE;
state_back <= SCAN;
end //定位行地址低位
5'd2: begin
oled_dcn <= CMD;
char_reg <= x_ph;
state <= WRITE;
state_back <= SCAN;
end //定位行地址高位
5'd3: begin
num <= num - 1'b1;
end
5'd4: begin
oled_dcn <= DATA;
char_reg <= 8'h00;
state <= WRITE;
state_back <= SCAN;
end //将5*8点阵编程8*8
5'd5: begin
oled_dcn <= DATA;
char_reg <= 8'h00;
state <= WRITE;
state_back <= SCAN;
end //将5*8点阵编程8*8
5'd6: begin
oled_dcn <= DATA;
char_reg <= 8'h00;
state <= WRITE;
state_back <= SCAN;
end //将5*8点阵编程8*8
5'd7: begin
oled_dcn <= DATA;
char_reg <= mem[char[(num*8)+:8]][39:32];
state <= WRITE;
state_back <= SCAN;
end
5'd8: begin
oled_dcn <= DATA;
char_reg <= mem[char[(num*8)+:8]][31:24];
state <= WRITE;
state_back <= SCAN;
end
5'd9: begin
oled_dcn <= DATA;
char_reg <= mem[char[(num*8)+:8]][23:16];
state <= WRITE;
state_back <= SCAN;
end
5'd10: begin
oled_dcn <= DATA;
char_reg <= mem[char[(num*8)+:8]][15: 8];
state <= WRITE;
state_back <= SCAN;
end
5'd11: begin
oled_dcn <= DATA;
char_reg <= mem[char[(num*8)+:8]][ 7: 0];
state <= WRITE;
state_back <= SCAN;
end
5'd12: begin
state <= MAIN;
end
default:
state <= IDLE;
endcase
end
else if(font==2'd1) begin // 两页数据的刷屏
if(cnt_scan == 5'd13) begin
if(num)
cnt_scan <= 5'd3;
else
cnt_scan <= cnt_scan + 1'b1;
end
else if(cnt_scan == 5'd28) begin
if(num)
cnt_scan <= 5'd18;
else
cnt_scan <= cnt_scan + 1'b1;
end
else if(cnt_scan == 5'd29)
cnt_scan <= 1'b0;
else
cnt_scan <= cnt_scan + 1'b1;
case(cnt_scan)
5'd0: begin
oled_dcn <= CMD;
char_reg <= y_p;
state <= WRITE;
state_back <= SCAN;
end //定位列页地址
5'd1: begin
oled_dcn <= CMD;
char_reg <= x_pl;
state <= WRITE;
state_back <= SCAN;
end //定位行地址低位
5'd2: begin
oled_dcn <= CMD;
char_reg <= x_ph;
state <= WRITE;
state_back <= SCAN;
end //定位行地址高位
5'd3: begin
num <= num - 1'b1;
end
5'd4: begin
oled_dcn <= DATA;
char_reg <= font10x16_mem[char[(num*8)+:8]][159-:8];
state <= WRITE;
state_back <= SCAN;
end
5'd5: begin
oled_dcn <= DATA;
char_reg <= font10x16_mem[char[(num*8)+:8]][151-:8];
state <= WRITE;
state_back <= SCAN;
end
5'd6: begin
oled_dcn <= DATA;
char_reg <= font10x16_mem[char[(num*8)+:8]][143-:8];
state <= WRITE;
state_back <= SCAN;
end
5'd7: begin
oled_dcn <= DATA;
char_reg <= font10x16_mem[char[(num*8)+:8]][135-:8];
state <= WRITE;
state_back <= SCAN;
end
5'd8: begin
oled_dcn <= DATA;
char_reg <= font10x16_mem[char[(num*8)+:8]][127-:8];
state <= WRITE;
state_back <= SCAN;
end
5'd9: begin
oled_dcn <= DATA;
char_reg <= font10x16_mem[char[(num*8)+:8]][119-:8];
state <= WRITE;
state_back <= SCAN;
end
5'd10: begin
oled_dcn <= DATA;
char_reg <= font10x16_mem[char[(num*8)+:8]][111-:8];
state <= WRITE;
state_back <= SCAN;
end
5'd11: begin
oled_dcn <= DATA;
char_reg <= font10x16_mem[char[(num*8)+:8]][103-:8];
state <= WRITE;
state_back <= SCAN;
end
5'd12: begin
oled_dcn <= DATA;
char_reg <= font10x16_mem[char[(num*8)+:8]][ 95-:8];
state <= WRITE;
state_back <= SCAN;
end
5'd13: begin
oled_dcn <= DATA;
char_reg <= font10x16_mem[char[(num*8)+:8]][ 87-:8];
state <= WRITE;
state_back <= SCAN;
end
5'd14: begin
state <= MAIN;
end
5'd15: begin
oled_dcn <= CMD;
char_reg <= y_p ;
state <= WRITE;
state_back <= SCAN;
end //定位列页地址
5'd16: begin
oled_dcn <= CMD;
char_reg <= x_pl;
state <= WRITE;
state_back <= SCAN;
end //定位行地址低位
5'd17: begin
oled_dcn <= CMD;
char_reg <= x_ph;
state <= WRITE;
state_back <= SCAN;
end //定位行地址高位
5'd18: begin
num <= num - 1'b1;
end
5'd19: begin
oled_dcn <= DATA;
char_reg <= font10x16_mem[char[(num*8)+:8]][ 79-:8];
state <= WRITE;
state_back <= SCAN;
end
5'd20: begin
oled_dcn <= DATA;
char_reg <= font10x16_mem[char[(num*8)+:8]][ 71-:8];
state <= WRITE;
state_back <= SCAN;
end
5'd21: begin
oled_dcn <= DATA;
char_reg <= font10x16_mem[char[(num*8)+:8]][ 63-:8];
state <= WRITE;
state_back <= SCAN;
end
5'd22: begin
oled_dcn <= DATA;
char_reg <= font10x16_mem[char[(num*8)+:8]][ 55-:8];
state <= WRITE;
state_back <= SCAN;
end
5'd23: begin
oled_dcn <= DATA;
char_reg <= font10x16_mem[char[(num*8)+:8]][ 47-:8];
state <= WRITE;
state_back <= SCAN;
end
5'd24: begin
oled_dcn <= DATA;
char_reg <= font10x16_mem[char[(num*8)+:8]][ 39-:8];
state <= WRITE;
state_back <= SCAN;
end
5'd25: begin
oled_dcn <= DATA;
char_reg <= font10x16_mem[char[(num*8)+:8]][ 31-:8];
state <= WRITE;
state_back <= SCAN;
end
5'd26: begin
oled_dcn <= DATA;
char_reg <= font10x16_mem[char[(num*8)+:8]][ 23-:8];
state <= WRITE;
state_back <= SCAN;
end
5'd27: begin
oled_dcn <= DATA;
char_reg <= font10x16_mem[char[(num*8)+:8]][ 15-:8];
state <= WRITE;
state_back <= SCAN;
end
5'd28: begin
oled_dcn <= DATA;
char_reg <= font10x16_mem[char[(num*8)+:8]][ 7-:8];
state <= WRITE;
state_back <= SCAN;
end
5'd29: begin
state <= MAIN;
end
default:
state <= IDLE;
endcase
end
else if(font==2'd2) begin // 两页数据的刷屏//16*16
if(cnt_scan == 6'd19) begin
if(num)
cnt_scan <= 6'd3;
else
cnt_scan <= cnt_scan + 1'b1;
end
else if(cnt_scan == 6'd40) begin
if(num)
cnt_scan <= 6'd24;
else
cnt_scan <= cnt_scan + 1'b1;
end
else if(cnt_scan == 6'd41)
cnt_scan <= 1'b0;
else
cnt_scan <= cnt_scan + 1'b1;
case(cnt_scan)
6'd0: begin
oled_dcn <= CMD;
char_reg <= y_p;
state <= WRITE;
state_back <= SCAN;
end //定位列页地址
6'd1: begin
oled_dcn <= CMD;
char_reg <= x_pl;
state <= WRITE;
state_back <= SCAN;
end //定位行地址低位
6'd2: begin
oled_dcn <= CMD;
char_reg <= x_ph;
state <= WRITE;
state_back <= SCAN;
end //定位行地址高位
6'd3: begin
num <= num - 1'b1;
end
6'd4: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][255-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd5: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][247-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd6: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][239-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd7: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][231-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd8: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][223-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd9: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][215-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd10: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][207-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd11: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][199-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd12: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][ 191-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd13: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][ 183-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd14: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][ 175-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd15: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][ 167-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd16: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][ 159-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd17: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][ 151-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd18: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][ 143-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd19: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][ 135-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd20: begin
state <= MAIN;
end
6'd21: begin
oled_dcn <= CMD;
char_reg <= y_p ;
state <= WRITE;
state_back <= SCAN;
end //定位列页地址
6'd22: begin
oled_dcn <= CMD;
char_reg <= x_pl;
state <= WRITE;
state_back <= SCAN;
end //定位行地址低位
6'd23: begin
oled_dcn <= CMD;
char_reg <= x_ph;
state <= WRITE;
state_back <= SCAN;
end //定位行地址高位
6'd24: begin
num <= num - 1'b1;
end
6'd25: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][ 127-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd26: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][ 119-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd27: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][ 111-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd28: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][ 103-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd29: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][ 95-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd30: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][ 87-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd31: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][ 79-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd32: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][ 71-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd33: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][ 63-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd34: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][ 55-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd35: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][ 47-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd36: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][ 39-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd37: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][ 31-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd38: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][ 23-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd39: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][ 15-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd40: begin
oled_dcn <= DATA;
char_reg <= font16x16_mem[char[(num*8)+:8]][ 7-:8];
state <= WRITE;
state_back <= SCAN;
end
6'd41: begin
state <= MAIN;
end
default:
state <= IDLE;
endcase
end
end
WRITE: begin //WRITE状态,将数据按照SPI时序发送给屏幕
if(cnt_write >= 5'd17)
cnt_write <= 1'b0;
else
cnt_write <= cnt_write + 1'b1;
case(cnt_write)
5'd 0: begin
oled_csn <= LOW;
end //9位数据最高位为命令数据控制位
5'd 1: begin
oled_clk <= LOW;
oled_dat <= char_reg[7];
end //先发高位数据
5'd 2: begin
oled_clk <= HIGH;
end
5'd 3: begin
oled_clk <= LOW;
oled_dat <= char_reg[6];
end
5'd 4: begin
oled_clk <= HIGH;
end
5'd 5: begin
oled_clk <= LOW;
oled_dat <= char_reg[5];
end
5'd 6: begin
oled_clk <= HIGH;
end
5'd 7: begin
oled_clk <= LOW;
oled_dat <= char_reg[4];
end
5'd 8: begin
oled_clk <= HIGH;
end
5'd 9: begin
oled_clk <= LOW;
oled_dat <= char_reg[3];
end
5'd10: begin
oled_clk <= HIGH;
end
5'd11: begin
oled_clk <= LOW;
oled_dat <= char_reg[2];
end
5'd12: begin
oled_clk <= HIGH;
end
5'd13: begin
oled_clk <= LOW;
oled_dat <= char_reg[1];
end
5'd14: begin
oled_clk <= HIGH;
end
5'd15: begin
oled_clk <= LOW;
oled_dat <= char_reg[0];
end //后发低位数据
5'd16: begin
oled_clk <= HIGH;
end
5'd17: begin
oled_csn <= HIGH;
state <= DELAY;
end //
default:
state <= IDLE;
endcase
end
DELAY: begin //延时状态
if(cnt_delay >= num_delay) begin
cnt_delay <= 16'd0;
state <= state_back;
end
else
cnt_delay <= cnt_delay + 1'b1;
end
default:
state <= IDLE;
endcase
end
end
initial begin
cnt_main = 1'b0;
cnt_init = 1'b0;
cnt_scan = 1'b0;
cnt_write = 1'b0;
y_p = 1'b0;
x_ph = 1'b0;
x_pl = 1'b0;
num = 1'b0;
char = 1'b0;
char_reg = 1'b0;
num_delay = 16'd5;
cnt_delay = 1'b0;
cnt = 1'b0;
oled_csn <= HIGH;
oled_rst <= HIGH;
oled_dcn <= CMD;
oled_clk <= HIGH;
oled_dat <= LOW;
state <= IDLE;
state_back <= IDLE;
cmd[ 0] = {8'hae};
cmd[ 1] = {8'h00};//00
cmd[ 2] = {8'h10};
cmd[ 3] = {8'h00};
cmd[ 4] = {8'hb0};
cmd[ 5] = {8'h81};
cmd[ 6] = {8'hff};
cmd[ 7] = {8'ha1};
cmd[ 8] = {8'ha6};
cmd[ 9] = {8'ha8};//--set multiplex ratio(1 to 64)
cmd[10] = {8'h1f};//1f:0.91 OLED12832 3f: 0.96 OLED12864
cmd[11] = {8'hc8};
cmd[12] = {8'hd3};
cmd[13] = {8'h00};
cmd[14] = {8'hd5};
cmd[15] = {8'h80};
cmd[16] = {8'hd9};
cmd[17] = {8'h1f};
cmd[18] = {8'hda};//--set com pins hardware configuration
cmd[19] = {8'h02};//12:0.96 OLED12864 02:0.91 OLED12832
cmd[20] = {8'hdb};
cmd[21] = {8'h20};
cmd[22] = {8'h8d};
cmd[23] = {8'h14};
cmd[24] = {8'haf};
mem[ 0] = {8'h3E, 8'h51, 8'h49, 8'h45, 8'h3E}; // 48 0
mem[ 1] = {8'h00, 8'h42, 8'h7F, 8'h40, 8'h00}; // 49 1
mem[ 2] = {8'h42, 8'h61, 8'h51, 8'h49, 8'h46}; // 50 2
mem[ 3] = {8'h21, 8'h41, 8'h45, 8'h4B, 8'h31}; // 51 3
mem[ 4] = {8'h18, 8'h14, 8'h12, 8'h7F, 8'h10}; // 52 4
mem[ 5] = {8'h27, 8'h45, 8'h45, 8'h45, 8'h39}; // 53 5
mem[ 6] = {8'h3C, 8'h4A, 8'h49, 8'h49, 8'h30}; // 54 6
mem[ 7] = {8'h01, 8'h71, 8'h09, 8'h05, 8'h03}; // 55 7
mem[ 8] = {8'h36, 8'h49, 8'h49, 8'h49, 8'h36}; // 56 8
mem[ 9] = {8'h06, 8'h49, 8'h49, 8'h29, 8'h1E}; // 57 9
mem[ 10] = {8'h7C, 8'h12, 8'h11, 8'h12, 8'h7C}; // 65 A
mem[ 11] = {8'h7F, 8'h49, 8'h49, 8'h49, 8'h36}; // 66 B
mem[ 12] = {8'h3E, 8'h41, 8'h41, 8'h41, 8'h22}; // 67 C
mem[ 13] = {8'h7F, 8'h41, 8'h41, 8'h22, 8'h1C}; // 68 D
mem[ 14] = {8'h7F, 8'h49, 8'h49, 8'h49, 8'h41}; // 69 E
mem[ 15] = {8'h7F, 8'h09, 8'h09, 8'h09, 8'h01}; // 70 F
mem[ 32] = {8'h00, 8'h00, 8'h00, 8'h00, 8'h00}; // 32 sp
mem[ 33] = {8'h00, 8'h00, 8'h2f, 8'h00, 8'h00}; // 33 !
mem[ 34] = {8'h00, 8'h07, 8'h00, 8'h07, 8'h00}; // 34
mem[ 35] = {8'h14, 8'h7f, 8'h14, 8'h7f, 8'h14}; // 35 #
mem[ 36] = {8'h24, 8'h2a, 8'h7f, 8'h2a, 8'h12}; // 36 $
mem[ 37] = {8'h62, 8'h64, 8'h08, 8'h13, 8'h23}; // 37 %
mem[ 38] = {8'h36, 8'h49, 8'h55, 8'h22, 8'h50}; // 38 &
mem[ 39] = {8'h00, 8'h05, 8'h03, 8'h00, 8'h00}; // 39 '
mem[ 40] = {8'h00, 8'h1c, 8'h22, 8'h41, 8'h00}; // 40 (
mem[ 41] = {8'h00, 8'h41, 8'h22, 8'h1c, 8'h00}; // 41 )
mem[ 42] = {8'h14, 8'h08, 8'h3E, 8'h08, 8'h14}; // 42 *
mem[ 43] = {8'h08, 8'h08, 8'h3E, 8'h08, 8'h08}; // 43 +
mem[ 44] = {8'h00, 8'h00, 8'hA0, 8'h60, 8'h00}; // 44 ,
mem[ 45] = {8'h08, 8'h08, 8'h08, 8'h08, 8'h08}; // 45 -
mem[ 46] = {8'h00, 8'h60, 8'h60, 8'h00, 8'h00}; // 46 .
mem[ 47] = {8'h20, 8'h10, 8'h08, 8'h04, 8'h02}; // 47 /
mem[ 48] = {8'h3E, 8'h51, 8'h49, 8'h45, 8'h3E}; // 48 0
mem[ 49] = {8'h00, 8'h42, 8'h7F, 8'h40, 8'h00}; // 49 1
mem[ 50] = {8'h42, 8'h61, 8'h51, 8'h49, 8'h46}; // 50 2
mem[ 51] = {8'h21, 8'h41, 8'h45, 8'h4B, 8'h31}; // 51 3
mem[ 52] = {8'h18, 8'h14, 8'h12, 8'h7F, 8'h10}; // 52 4
mem[ 53] = {8'h27, 8'h45, 8'h45, 8'h45, 8'h39}; // 53 5
mem[ 54] = {8'h3C, 8'h4A, 8'h49, 8'h49, 8'h30}; // 54 6
mem[ 55] = {8'h01, 8'h71, 8'h09, 8'h05, 8'h03}; // 55 7
mem[ 56] = {8'h36, 8'h49, 8'h49, 8'h49, 8'h36}; // 56 8
mem[ 57] = {8'h06, 8'h49, 8'h49, 8'h29, 8'h1E}; // 57 9
mem[ 58] = {8'h00, 8'h36, 8'h36, 8'h00, 8'h00}; // 58 :
mem[ 59] = {8'h00, 8'h56, 8'h36, 8'h00, 8'h00}; // 59 ;
mem[ 60] = {8'h08, 8'h14, 8'h22, 8'h41, 8'h00}; // 60 <
mem[ 61] = {8'h14, 8'h14, 8'h14, 8'h14, 8'h14}; // 61 =
mem[ 62] = {8'h00, 8'h41, 8'h22, 8'h14, 8'h08}; // 62 >
mem[ 63] = {8'h02, 8'h01, 8'h51, 8'h09, 8'h06}; // 63 ?
mem[ 64] = {8'h32, 8'h49, 8'h59, 8'h51, 8'h3E}; // 64 @
mem[ 65] = {8'h7C, 8'h12, 8'h11, 8'h12, 8'h7C}; // 65 A
mem[ 66] = {8'h7F, 8'h49, 8'h49, 8'h49, 8'h36}; // 66 B
mem[ 67] = {8'h3E, 8'h41, 8'h41, 8'h41, 8'h22}; // 67 C
mem[ 68] = {8'h7F, 8'h41, 8'h41, 8'h22, 8'h1C}; // 68 D
mem[ 69] = {8'h7F, 8'h49, 8'h49, 8'h49, 8'h41}; // 69 E
mem[ 70] = {8'h7F, 8'h09, 8'h09, 8'h09, 8'h01}; // 70 F
mem[ 71] = {8'h3E, 8'h41, 8'h49, 8'h49, 8'h7A}; // 71 G
mem[ 72] = {8'h7F, 8'h08, 8'h08, 8'h08, 8'h7F}; // 72 H
mem[ 73] = {8'h00, 8'h41, 8'h7F, 8'h41, 8'h00}; // 73 I
mem[ 74] = {8'h20, 8'h40, 8'h41, 8'h3F, 8'h01}; // 74 J
mem[ 75] = {8'h7F, 8'h08, 8'h14, 8'h22, 8'h41}; // 75 K
mem[ 76] = {8'h7F, 8'h40, 8'h40, 8'h40, 8'h40}; // 76 L
mem[ 77] = {8'h7F, 8'h02, 8'h0C, 8'h02, 8'h7F}; // 77 M
mem[ 78] = {8'h7F, 8'h04, 8'h08, 8'h10, 8'h7F}; // 78 N
mem[ 79] = {8'h3E, 8'h41, 8'h41, 8'h41, 8'h3E}; // 79 O
mem[ 80] = {8'h7F, 8'h09, 8'h09, 8'h09, 8'h06}; // 80 P
mem[ 81] = {8'h3E, 8'h41, 8'h51, 8'h21, 8'h5E}; // 81 Q
mem[ 82] = {8'h7F, 8'h09, 8'h19, 8'h29, 8'h46}; // 82 R
mem[ 83] = {8'h46, 8'h49, 8'h49, 8'h49, 8'h31}; // 83 S
mem[ 84] = {8'h01, 8'h01, 8'h7F, 8'h01, 8'h01}; // 84 T
mem[ 85] = {8'h3F, 8'h40, 8'h40, 8'h40, 8'h3F}; // 85 U
mem[ 86] = {8'h1F, 8'h20, 8'h40, 8'h20, 8'h1F}; // 86 V
mem[ 87] = {8'h3F, 8'h40, 8'h38, 8'h40, 8'h3F}; // 87 W
mem[ 88] = {8'h63, 8'h14, 8'h08, 8'h14, 8'h63}; // 88 X
mem[ 89] = {8'h07, 8'h08, 8'h70, 8'h08, 8'h07}; // 89 Y
mem[ 90] = {8'h61, 8'h51, 8'h49, 8'h45, 8'h43}; // 90 Z
mem[ 91] = {8'h00, 8'h7F, 8'h41, 8'h41, 8'h00}; // 91 [
mem[ 92] = {8'h55, 8'h2A, 8'h55, 8'h2A, 8'h55}; // 92 .
mem[ 93] = {8'h00, 8'h41, 8'h41, 8'h7F, 8'h00}; // 93 ]
mem[ 94] = {8'h04, 8'h02, 8'h01, 8'h02, 8'h04}; // 94 ^
mem[ 95] = {8'h40, 8'h40, 8'h40, 8'h40, 8'h40}; // 95 _
mem[ 96] = {8'h00, 8'h01, 8'h02, 8'h04, 8'h00}; // 96 '
mem[ 97] = {8'h20, 8'h54, 8'h54, 8'h54, 8'h78}; // 97 a
mem[ 98] = {8'h7F, 8'h48, 8'h44, 8'h44, 8'h38}; // 98 b
mem[ 99] = {8'h38, 8'h44, 8'h44, 8'h44, 8'h20}; // 99 c
mem[100] = {8'h38, 8'h44, 8'h44, 8'h48, 8'h7F}; // 100 d
mem[101] = {8'h38, 8'h54, 8'h54, 8'h54, 8'h18}; // 101 e
mem[102] = {8'h08, 8'h7E, 8'h09, 8'h01, 8'h02}; // 102 f
mem[103] = {8'h18, 8'hA4, 8'hA4, 8'hA4, 8'h7C}; // 103 g
mem[104] = {8'h7F, 8'h08, 8'h04, 8'h04, 8'h78}; // 104 h
mem[105] = {8'h00, 8'h44, 8'h7D, 8'h40, 8'h00}; // 105 i
mem[106] = {8'h40, 8'h80, 8'h84, 8'h7D, 8'h00}; // 106 j
mem[107] = {8'h7F, 8'h10, 8'h28, 8'h44, 8'h00}; // 107 k
mem[108] = {8'h00, 8'h41, 8'h7F, 8'h40, 8'h00}; // 108 l
mem[109] = {8'h7C, 8'h04, 8'h18, 8'h04, 8'h78}; // 109 m
mem[110] = {8'h7C, 8'h08, 8'h04, 8'h04, 8'h78}; // 110 n
mem[111] = {8'h38, 8'h44, 8'h44, 8'h44, 8'h38}; // 111 o
mem[112] = {8'hFC, 8'h24, 8'h24, 8'h24, 8'h18}; // 112 p
mem[113] = {8'h18, 8'h24, 8'h24, 8'h18, 8'hFC}; // 113 q
mem[114] = {8'h7C, 8'h08, 8'h04, 8'h04, 8'h08}; // 114 r
mem[115] = {8'h48, 8'h54, 8'h54, 8'h54, 8'h20}; // 115 s
mem[116] = {8'h04, 8'h3F, 8'h44, 8'h40, 8'h20}; // 116 t
mem[117] = {8'h3C, 8'h40, 8'h40, 8'h20, 8'h7C}; // 117 u
mem[118] = {8'h1C, 8'h20, 8'h40, 8'h20, 8'h1C}; // 118 v
mem[119] = {8'h3C, 8'h40, 8'h30, 8'h40, 8'h3C}; // 119 w
mem[120] = {8'h44, 8'h28, 8'h10, 8'h28, 8'h44}; // 120 x
mem[121] = {8'h1C, 8'hA0, 8'hA0, 8'hA0, 8'h7C}; // 121 y
mem[122] = {8'h44, 8'h64, 8'h54, 8'h4C, 8'h44}; // 122 z
mem[123] = {8'h00, 8'h00, 8'h00, 8'h03, 8'h03}; // 123
//10*16
font10x16_mem[0] = {8'h00,8'hE0,8'hF0,8'h18,8'h08,8'h08,8'h18,8'hF0,8'hE0,8'h00,
8'h00,8'h07,8'h0F,8'h18,8'h10,8'h10,8'h18,8'h0F,8'h07,8'h00};/*"0",0*/
font10x16_mem[1] = {8'h00,8'h10,8'h10,8'h08,8'hF8,8'hF8,8'h00,8'h00,8'h00,8'h00,8'h00,8'h10,8'h10,8'h10,8'h1F,8'h1F,8'h10,8'h10,8'h10,8'h00};/*"1",1*/
font10x16_mem[2] = {8'h00,8'h08,8'h08,8'h08,8'h08,8'h98,8'hF8,8'h70,8'h00,8'h00,8'h00,8'h18,8'h1C,8'h16,8'h13,8'h11,8'h10,8'h10,8'h00,8'h00};/*"2",2*/
font10x16_mem[3] = {8'h00,8'h08,8'h88,8'h88,8'h88,8'hC8,8'h78,8'h30,8'h00,8'h00,8'h00,8'h10,8'h10,8'h10,8'h10,8'h19,8'h0F,8'h0E,8'h00,8'h00};/*"3",3*/
font10x16_mem[4] = {8'h00,8'h00,8'h80,8'hE0,8'h30,8'hF8,8'hF8,8'h00,8'h00,8'h00,8'h00,8'h03,8'h03,8'h02,8'h02,8'h1F,8'h1F,8'h02,8'h02,8'h00};/*"4",4*/
font10x16_mem[5] = {8'h00,8'h00,8'hF8,8'hF8,8'h88,8'h88,8'h08,8'h08,8'h00,8'h00,8'h00,8'h00,8'h10,8'h10,8'h10,8'h19,8'h0F,8'h0F,8'h00,8'h00};/*"5",5*/
font10x16_mem[6] = {8'h00,8'hC0,8'hF0,8'h38,8'h88,8'h88,8'h88,8'h88,8'h00,8'h00,8'h00,8'h07,8'h0F,8'h19,8'h10,8'h10,8'h19,8'h0F,8'h07,8'h00};/*"6",6*/
font10x16_mem[7] = {8'h00,8'h00,8'h08,8'h08,8'h08,8'h08,8'hC8,8'h78,8'h18,8'h00,8'h00,8'h00,8'h00,8'h18,8'h1E,8'h07,8'h01,8'h00,8'h00,8'h00};/*"7",7*/
font10x16_mem[8] = {8'h00,8'h00,8'h70,8'h78,8'hC8,8'h88,8'h48,8'h78,8'h30,8'h00,8'h00,8'h0E,8'h1F,8'h19,8'h10,8'h11,8'h11,8'h0F,8'h0E,8'h00};/*"8",8*/
font10x16_mem[9] = {8'h00,8'hE0,8'hF0,8'h98,8'h08,8'h08,8'h98,8'hF0,8'hE0,8'h00,8'h00,8'h00,8'h11,8'h11,8'h11,8'h11,8'h1C,8'h0F,8'h03,8'h00};/*"9",9*/
font10x16_mem[10] = {8'h00,8'h00,8'h80,8'hE0,8'h78,8'h78,8'hE0,8'h80,8'h00,8'h00,8'h10,8'h1E,8'h0F,8'h03,8'h02,8'h02,8'h03,8'h0F,8'h1C,8'h10};/*"A",10*/
font10x16_mem[11] = {8'h00,8'hF8,8'hF8,8'h88,8'h88,8'h88,8'h48,8'h78,8'h30,8'h00,8'h00,8'h1F,8'h1F,8'h10,8'h10,8'h10,8'h11,8'h1F,8'h0E,8'h00};/*"B",11*/
font10x16_mem[12] = {8'h00,8'hC0,8'hF0,8'h30,8'h18,8'h08,8'h08,8'h08,8'h08,8'h00,8'h00,8'h03,8'h0F,8'h0C,8'h18,8'h10,8'h10,8'h10,8'h10,8'h00};/*"C",12*/
font10x16_mem[13] = {8'h00,8'hF8,8'hF8,8'h08,8'h08,8'h08,8'h18,8'hF0,8'hE0,8'h00,8'h00,8'h1F,8'h1F,8'h10,8'h10,8'h10,8'h08,8'h0F,8'h03,8'h00};/*"D",13*/
font10x16_mem[14] = {8'h00,8'h00,8'hF8,8'hF8,8'h88,8'h88,8'h88,8'h88,8'h08,8'h00,8'h00,8'h00,8'h1F,8'h1F,8'h10,8'h10,8'h10,8'h10,8'h10,8'h00};/*"E",14*/
font10x16_mem[15] = {8'h00,8'h00,8'hF8,8'hF8,8'h88,8'h88,8'h88,8'h88,8'h08,8'h00,8'h00,8'h00,8'h1F,8'h1F,8'h00,8'h00,8'h00,8'h00,8'h00,8'h00};/*"F",15*/
font10x16_mem[16] = {8'h00,8'h00,8'h00,8'h00,8'hC0,8'hC0,8'h00,8'h00,8'h00,8'h00,8'h00,8'h00,8'h00,8'h00,8'h18,8'h18,8'h00,8'h00,8'h00,8'h00};/*":",16*/
font10x16_mem[17] = {8'h00,8'h00,8'h00,8'h00,8'h00,8'h00,8'h00,8'h00,8'h00,8'h00,8'h00,8'h00,8'h00,8'h00,8'h00,8'h00,8'h00,8'h00,8'h00,8'h00};/*" ",17*/
font16x16_mem[0]={8'h00,8'hE0,8'h00,8'hFF,8'h10,8'h20,8'h02,8'hF2,8'h92,8'h92,8'h92,8'h92,8'h92,8'hF2,8'h02,8'h00,
8'h01,8'h00,8'h00,8'hFF,8'h00,8'h00,8'h40,8'h4F,8'h44,8'h44,8'h44,8'h44,8'h44,8'h4F,8'h40,8'h00};/*"恒",0*/
font16x16_mem[1]={8'h00,8'h00,8'h00,8'hBE,8'h2A,8'h2A,8'h2A,8'hEA,8'h2A,8'h2A,8'h2A,8'h3E,8'h00,8'h00,8'h00,8'h00,
8'h00,8'h44,8'h42,8'h49,8'h49,8'h49,8'h49,8'h7F,8'h49,8'h49,8'h49,8'h49,8'h41,8'h40,8'h00,8'h00};/*"星",0*/
font16x16_mem[2]={8'h00,8'h02,8'h02,8'h02,8'h02,8'h82,8'h42,8'hF2,8'h0E,8'h42,8'h82,8'h02,8'h02,8'h02,8'h00,8'h00,
8'h10,8'h08,8'h04,8'h02,8'h01,8'h00,8'h00,8'hFF,8'h00,8'h00,8'h00,8'h01,8'h02,8'h0C,8'h00,8'h00};/*"不",1*/
font16x16_mem[3]={8'h00,8'h00,8'h00,8'hFE,8'h02,8'h02,8'h02,8'hF2,8'h02,8'h02,8'h02,8'hFE,8'h00,8'h00,8'h00,8'h00,
8'h80,8'h80,8'h40,8'h47,8'h20,8'h18,8'h06,8'h01,8'h7E,8'h80,8'h80,8'h87,8'h80,8'h80,8'hE0,8'h00};/*"见",2*/
end
endmodule
segment.v
module segment
(
input wire [3:0] seg_data_1, //四位输入数据信号
input wire [3:0] seg_data_2, //四位输入数据信号
output wire [8:0] segment_led_1, //数码管1,MSB~LSB = SEG,DP,G,F,E,D,C,B,A
output wire [8:0] segment_led_2 //数码管2,MSB~LSB = SEG,DP,G,F,E,D,C,B,A
);
reg[8:0] seg [15:0]; //存储7段数码管译码数据
initial
begin
seg[0] = 9'h3f; // 0 0011 1111
seg[1] = 9'h06; // 1
seg[2] = 9'h5b; // 2
seg[3] = 9'h4f; // 3
seg[4] = 9'h66; // 4
seg[5] = 9'h6d; // 5
seg[6] = 9'h7d; // 6
seg[7] = 9'h07; // 7
seg[8] = 9'h7f; // 8
seg[9] = 9'h6f; // 9
seg[10]= 9'h77; // A
seg[11]= 9'h7C; // b
seg[12]= 9'h39; // C
seg[13]= 9'h5e; // d
seg[14]= 9'h79; // E
seg[15]= 9'h71; // F
end
assign segment_led_1 = seg[seg_data_1];
assign segment_led_2 = seg[seg_data_2];
endmodule
divide.v
module divide
#(
parameter CNT_1HZ_MAX = 25'd5_999_999//T=1s,duty=50%
)
(
input wire sys_clk,
input wire sys_rst_n,
output reg clk_out
);
reg [25:0] cnt;
reg cnt_flag;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt <= 25'b0;
else if(cnt == CNT_1HZ_MAX)
cnt <= 25'b0;
else
cnt <= cnt + 1'b1;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_flag <= 1'b0;
else if(cnt == CNT_1HZ_MAX-25'b1)
cnt_flag <= 1'b1;
else
cnt_flag <= 1'b0;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
clk_out <= 1'b1;
else if(cnt_flag == 1'b1)
clk_out <= ~clk_out;
endmodule