VGA显示正圆

  接着上次的随笔,既然VGA时序已经实现了,那么就显示点东西看看吧。

  想显示个圆,但是无从下手,参考了这篇文章:https://user.qzone.qq.com/1241003385/blog/1543804422

  仔细阅读了这篇文章后才理解所谓显示圆的算法很简单,圆的标准方程是(x - a) ² + (y - b) ² = r ²,只要控制显示范围满足圆的方程就可以了。

  当(x-a)2+(y-b)2<=r2区域是圆内,(x-a)2+(y-b)2>=r2的区域就是圆外。

  这里显示圆的半径是50个像素点,并且以屏幕正中心为原点所以需要满足条件:

  distance = (x-a)*(x-a) + (y-b)*(y-b) = (h_cnt-96-48 -320) *(h_cnt-96-48-320) +(v_cnt-2-33 -240) *(v_cnt-2-33 -240);

  其中96,48为行显示区域以外,320为显示行的中心,2,33为场显示区域以外,320为显示列的正中心。

  如果distance小于r2=(50)2=2500 ,说明在圆内,否则在圆外。

  代码如下:

  

  1. module vga_driver(  
  2.     clk         ,  
  3.     rst_n       ,  
  4.     vga_hys     ,  
  5.     vga_vys     ,  
  6.     vga_rgb       
  7. );  
  8.   
  9. parameter       DATA_W  = 16;  
  10. parameter       LCD_GREEN = 16'b00000_111111_00000;  
  11. parameter       LCD_WHITE = 16'b11111_111111_11111;  
  12.   
  13. input         clk      ;  
  14. input         rst_n    ;  
  15.   
  16. output        vga_hys    ;  
  17. output        vga_vys    ;  
  18. output [DATA_W-1:0]  vga_rgb    ;  
  19.   
  20. reg             vga_hys;  
  21. reg             vga_vys;  
  22. reg     [DATA_W-1:0]vga_rgb;  
  23.   
  24. reg     [9:0]   cnt_hys;  
  25. reg     [9:0]   cnt_vys;  
  26. reg      [19:0] distance;  
  27. reg             green_area;  
  28. reg             valid_area;  
  29.   
  30. wire            add_cnt_hys;  
  31. wire            end_cnt_hys;  
  32. wire            add_cnt_vys;  
  33. wire            end_cnt_vys;  
  34. wire                 vga_clk;  
  35.   
  36. VGA_PLL U0(  
  37.     .inclk0 (clk),  
  38.     .c0     (vga_clk)  
  39. );  
  40.   
  41.   
  42. always @(posedge vga_clk or negedge rst_n)begin  
  43.     if(!rst_n)begin  
  44.         cnt_hys <= 0;  
  45.     end  
  46.     else if(add_cnt_hys)begin  
  47.         if(end_cnt_hys)  
  48.             cnt_hys <= 0;  
  49.         else  
  50.             cnt_hys <= cnt_hys + 1;  
  51.     end  
  52. end  
  53.   
  54. assign add_cnt_hys = 1;         
  55. assign end_cnt_hys = add_cnt_hys && cnt_hys== 800-1;     
  56.   
  57. always @(posedge vga_clk or negedge rst_n)begin  
  58.     if(!rst_n)begin  
  59.         cnt_vys <= 0;  
  60.     end  
  61.     else if(add_cnt_vys)begin  
  62.         if(end_cnt_vys)  
  63.             cnt_vys <= 0;  
  64.         else  
  65.             cnt_vys <= cnt_vys + 1;  
  66.     end  
  67. end  
  68.   
  69. assign add_cnt_vys = end_cnt_hys;         
  70. assign end_cnt_vys = add_cnt_vys && cnt_vys==525-1 ;     
  71.   
  72. always  @(posedge vga_clk or negedge rst_n)begin  
  73.     if(rst_n==1'b0)begin  
  74.         vga_hys <= 0;  
  75.     end  
  76.     else if(add_cnt_hys && cnt_hys == 96-1)begin  
  77.         vga_hys <= 1;  
  78.     end  
  79.     else if(end_cnt_hys)begin  
  80.         vga_hys <= 0;  
  81.     end  
  82. end  
  83.   
  84. always  @(posedge vga_clk or negedge rst_n)begin  
  85.     if(rst_n==1'b0)begin  
  86.         vga_vys <= 0;  
  87.     end  
  88.     else if(add_cnt_vys && cnt_vys == 2-1)begin  
  89.         vga_vys <= 1;  
  90.     end  
  91.     else if(end_cnt_vys)begin  
  92.         vga_vys <= 0;  
  93.     end  
  94. end  
  95.   
  96. always  @(*)begin  
  97.     distance = ((cnt_hys-96-48-320)*(cnt_hys-96-48-320))+((cnt_vys-2-33-240)*(cnt_vys-2-33-240));  
  98. end  
  99.   
  100. always  @(*)begin  
  101.     green_area = distance < 2500;  
  102. end  
  103.   
  104. always  @(*)begin  
  105.     valid_area = cnt_hys >= (96+48)&&cnt_hys <(96+48+640) && cnt_vys >= (2+33)&&cnt_vys<(2+33+480);  
  106. end  
  107.   
  108. always  @(posedge vga_clk or negedge rst_n)begin  
  109.     if(rst_n==1'b0)begin  
  110.         vga_rgb <= 16'h0;  
  111.     end  
  112.     else if(valid_area)  
  113.         begin  
  114.             if(green_area)  
  115.                 begin  
  116.                     vga_rgb <= LCD_GREEN;  
  117.                 end  
  118.             else begin  
  119.                     vga_rgb <= LCD_WHITE;  
  120.                 end  
  121.         end  
  122.     else begin  
  123.             vga_rgb <= 0;  
  124.         end  
  125. end  
  126.   
  127. endmodule
  128. 显示效果如下图
  129. 中间调试的过程中出现过错误,错误的显示效果是:
  130. 经过排查发现问题出在distance定义的长度上,给distance赋值比自身长度大的数据,导致数据丢失就会产生这样的结果,同样的修改distance的长度反而有意外收获。

猜你喜欢

转载自www.cnblogs.com/Librarian/p/10091944.html
VGA