项目名称
显示缩放的圆域
具体要求
显示一个逐渐放大然后再逐渐缩小的圆域
项目说明及代码设计
这个项目其实也比较简单,但是笔者花费了一个下午的时间,实践出真知,在上个工程彩色环显示的基础上进行改进。
首先要计算圆域放大和缩小的时间,圆域的放大可以看成半径从零到最大的过程,根据圆的标准方程公式
可以得到圆域面积
采用的是640*480的分辨率,圆域面积最大为240*240=57600,如果设计57600的计数器,由于系统时钟为50M,总共需要57600*20=115200ns就可以将圆域放大,肉眼根本观测不到,可以再设计一个计数器,进行每个像素环显示进行计数,计数最大设为1000,每次计数满1000产生标志信号来增加一个像素环。
圆域的放大缩小可以看成是面积计数从0到57600再到0的过程,可以设计一个状态机,状态0从1计数到57599,状态1从57600计数到0。
代码设计
主要代码设计, 笔者在设计过程中,由于仿真时间较长,调试极不方便,针对这种情况可以设计简单的代码仿真其功能是否完善,之后可以进行移植。
//每计数1000次一个圆环像素向外扩展,直到显示最大圆
reg flag;
reg[9:0]cnt;
always@(posedge clk or negedge rst_n)
if(!rst_n)begin
cnt<=0;
flag<=0;
end
else if(cnt==10'd999)begin
cnt<=0;
flag<=1;
end
else begin
cnt<=cnt+1;
flag<=0;
end
//显示区域
reg [17:0] area;
always@(*)
begin
area=v_x*v_x+v_y*v_y;
end
//状态1从小到大从1计数到57599,状态2从大到小从57600计数到0
//所设计的计数器从0-57600-0
reg [15:0]range;
reg state;
always@(posedge clk or negedge rst_n)
if(!rst_n)begin
range<=16'd0;
state<=0;
end
else begin
case(state)
0: begin
if(flag)
begin
if(range<16'd57599)
range<=range+1;
else begin
state<=1;
range<=16'd57600;
end
end
else
range<=range;
end
1: begin
if(flag)
begin
if(range>0)
range<=range-1;
else begin
state<=0;
range<=1;
end
end
else
range<=range;
end
default:;
endcase
end
//显示
always@(posedge clk or negedge rst_n)
if(!rst_n)begin
vga_rgb<=0;
end
else if(area<=range)
vga_rgb<=green;
else
vga_rgb<=0;
assign lcd_sync=1'd0;
assign lcd_blank=vga_hs & vga_vs;
assign lcd_dclk=~clk;
显示结果