logo资料库

FPGA设计电子钟.doc

第1页 / 共15页
第2页 / 共15页
第3页 / 共15页
第4页 / 共15页
第5页 / 共15页
第6页 / 共15页
第7页 / 共15页
第8页 / 共15页
资料共15页,剩余部分请下载后查看
1代码
2代码
3代码
4代码
5代码
fpga 设计电子时钟(12864 显示) 设计心得: 1,进行分块设计,类似调用函数,脉冲使能 2,充分了解 fpga 的并行特性(c 程序的串行特性,不能并行处理,线性:只有完成了当前 任务,才能进行下一个任务) 设计问题: 1,似乎读有问题,在 char_LR=1 时,写的数据为汉字 (程序中时间没有更改,主要为了调试看波形) 实际板子验证时,将 LCD_clk 模块中的分频调为 50 到 100kHz 左右 整体架构 功能模块 液晶初始化时序 控制时序 时序处理 功能模块 初始化 写汉字 写字符 绘图 非忙应答 1,液晶上电初始化 2,清屏 1,采用绘图模式 2,一次一个汉字 3,位置,编码编号 1,采用 CDRAM 模式 2,一次一个字符 3,位置 1,采用绘图模式 2,大小可变(库编码内存不变) 3,位置,长宽
parameter Idle =8'b0000_0001, =8'b0000_0010, Basic_com Disp_set =8'b0000_0100, DDRAM_clear =8'b0000_1000, Wait_clear =8'b0001_0000, =8'b0010_0000, Point_set Show_on =8'b0100_0000, //basic instruction:0x30 //set show curse bling //colunm address X Stop =8'b1000_0000; 写字符的时序 由于字符属于半宽字形,且 DDRAM 形式下,每行只有 8 个地址,而字符可以写 16 个,因此用下面三个来表 示写的地址: input [1:0] input [2:0] input //row 0-3 //clunm 0-7 Y, X, LR, //0/1 因此当 LR=0 时,直接写地址,然后写一个字符编码即可 LR=1 时,先写地址,读出高位数据,然后写入两个字节(读出的数据,要写的数据)
parameter Idle DDRAM W_addr Dummy R_data W0_data W1_data Stop =8'b0000_0001, =8'b0000_0010, =8'b0000_0100, =8'b0000_1000, =8'b0001_0000, =8'b0010_0000, =8'b0100_0000, =8'b1000_0000; //drawing mode //row address Y // not really reading //reading high byte data # t1: # t1: # t1: 0 t2: 2305 t2: 2665 t2: 2305, T: 2665, T: 3265, T: 10,n_init: 10,n_char: 10,n_char: 38 6 10 完成了上述工作,就可以设计一个简单的电子时钟,其要求如下: 在屏幕上显示时间 00:00:00 要动态走 (主要就是控制脉冲信号的产生) 设计思路: 1,按下复位键,系统复位,时间变为 00:00:00 2,每一秒中时分秒数据更改 3,一秒钟时间到,产生 8 个字符写的脉冲,LCD 更新数据显示
00:00:01 00:01:59 1 代码 /* sign.v //creat the control sign clock h:m:s */ module sign( //module LED( //100kHz lcd_clk, sys_rst, input input output reg lcd_char_en, output reg lcd_init_en, output reg [7:0]char_data, output reg [2:0]char_X, output reg [1:0]char_Y, output reg char_LR ); parameter T_w_char = 5,
T_lcd_init = 40; reg [47:0] time_out; /* 1s */ reg [16:0] cnt_s; reg [5:0] cnt0_clk; reg [3:0] cnt1_clk; reg [2:0] cnt_char; reg [5:0] sec,min; reg [4:0] hour; reg flag_s,flag_init; always @ (posedge lcd_clk or negedge sys_rst) if(!sys_rst) begin begin //100kHz cnt_s <=0; cnt0_clk<=0; cnt1_clk<=0; cnt_char<=0; <=0; sec <=0; min hour <=0; flag_s <=0; flag_init <=1'b1; char_Y <= 2'b10; else end begin if(cnt_s == (40-1)) begin cnt_s <=0; flag_s<=1'b1; data_deal; //task end else cnt_s <=cnt_s+1'b1; if(flag_init) begin cnt0_clk <= cnt0_clk +1'b1; case(cnt0_clk) : begin lcd_init_en <=1'b0; end : begin lcd_init_en <=1'b1; end : begin lcd_init_en <=1'b1; end : begin lcd_init_en <=1'b0; end 1 2 3 4 T_lcd_init: begin flag_init <=0;
cnt0_clk <=0; end default: lcd_init_en <=0; endcase end else if(flag_s) begin cnt1_clk <= cnt1_clk +1'b1; case(cnt1_clk) : begin lcd_char_en <=1'b0;end : begin lcd_char_en <=1'b1;end : begin lcd_char_en <=1'b1;end : begin lcd_char_en <=1'b0;end 1 2 3 4 T_w_char: begin if(cnt_char == 3'b111) begin cnt_char<=0; flag_s <=0; end else cnt_char <=cnt_char+1'b1; cnt1_clk <=0; end default: lcd_char_en <=0; endcase case(cnt_char) //2 3 4 5 end //x0:00:00 end //0x:00:00 058 end //00:x0:00 end //00:0x:00 058 0 1 2 3 4 5 6 : begin char_X <=3'b000; char_LR <=0; char_data <=time_out[47:40]; : begin char_X <=3'b001; char_LR <=0; char_data <=time_out[39:32]; : begin char_X <=3'b010; char_LR <=0; char_data <=8'h3a; end //: ascii : begin char_X <=3'b011; char_LR <=0; char_data <=time_out[31:24]; : begin char_X <=3'b100; char_LR <=0; char_data <=time_out[23:16]; : begin char_X <=3'b101; char_LR <=0; char_data <=8'h3a; end //: ascii : begin char_X <=3'b110; char_LR <=0; char_data <=time_out[15: 8]; end
//00:00:x0 7 : begin char_X <=3'b111; char_LR <=0; char_data <=time_out[7 : 0]; end endcase end end end task data_deal; begin if(sec == 59) if(min ==59) if(hour == 23) begin hour<=0;min <=0;sec <=0; end begin hour<=hour + 1'b1; min <=0; sec<=0; end else else begin min <= min+1'b1; sec <=0; end else sec <= sec +1'b1; time_out[47:40] <= 8'h30+(hour/10); time_out[39:32] <= 8'h30+(hour%10); time_out[31:24] <= 8'h30+(min /10); time_out[23:16] <= 8'h30+(min %10); time_out[15: 8] <= 8'h30+(sec /10); time_out[ 7: 0] <= 8'h30+(sec %10); end endtask endmodule 2 代码 module LCD_init( //module LED( input input input output output output inout lcd_clk, sys_clk, lcd_en, reg LCD_RS, reg LCD_RW, reg LCD_EN, [7:0] LCD_DATA, //1 is actived
output reg ACK ); reg flag; reg [7:0] lcd_data; reg [7:0] State; reg link_rs; reg link_data; parameter =8'b0000_0010, //basic instruction:0x30 //set show curse bling //colunm address X =8'b0000_0001, Idle Basic_com Disp_set =8'b0000_0100, DDRAM_clear =8'b0000_1000, Wait_clear =8'b0001_0000, Point_set =8'b0010_0000, Show_on Stop =8'b1000_0000; =8'b0100_0000, reg [9:0] cnt; //16*2*32=2^10 byte(8bits) /* LCD_RW LCD_DATA*/ assign LCD_DATA = link_data ? lcd_data: 8'hzz; /* LCD_RW LCD_EN */ always @ (posedge sys_clk) begin if(flag) begin LCD_RW =0; LCD_EN = lcd_clk; else end begin LCD_RW =1'bz; LCD_EN =1'bz; end end /* LCD_RS */ always @ (posedge lcd_clk) begin if(link_rs) LCD_RS <=1'b0; else LCD_RS <=1'bz; end /*-Main state transter-*/ always @ (posedge lcd_clk) begin case (State) Idle : begin if(lcd_en) begin link_rs=1; State <= Basic_com; end
分享到:
收藏