基于fpga的方波发生器
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
@[TOC](文章目录)前言
基于fpga的方波发生器,原理是模拟stm32定时器输出占空比和频率可调的方波,并在RGB_LCD屏幕上显示。一、方波调节
reg [30:0] arr=20'd10000;
reg [30:0] ccr1=20'd5000;
reg [30:0] cnt=20'd0;
//计数器
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
cnt<=20'd0;
end
else begin
cnt<=cnt+1'd1;
if(cnt>=arr)
cnt<=1'd0;
end
end
always @(posedge sys_clk or negedge sys_rst_n)begin//
if(!sys_rst_n)
;
else begin
if(cnt<=ccr1)
dds_out<=1'd1;
else if(cnt>=ccr1)
dds_out<=1'd0;
end
end
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
duty_cycle<=20'd0;
frequency<=20'd0;
end
else begin
duty_cycle<=ccr1*10'd100/arr;
frequency<=20'd50000*10/arr;
end
end
-
fpga的工作频率为50Mhz,通过cnt计数器模拟32的定时器,当cnt的值低于ccr1时,输出为低电平, 当cnt的值高于ccr1时,输出为高电平,当计数器计到arr(自动重装载值), cnt值归零重新开始计数。方波的频率为50Mgz/arr值,arr为多少,就是把主频分多少。 方波的占空比为ccr1/arr值。
二、按键控制
//根据按键值控制arr基于ccr1值
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
flag<=1'd0;
end
else begin
if((key_data==4'b1110)&(flag==0))begin
arr<=arr+10'd1000;
flag<=1'd1;end
else if((key_data==4'b1101)&(flag==0))begin
arr<=arr-10'd1000;
flag<=1'd1;end
else if((key_data==4'b1011)&(flag==0))begin
ccr1<=ccr1+10'd1000;
flag<=1'd1;end
else if((key_data==4'b0111)&(flag==0))begin
ccr1<=ccr1-10'd1000;
flag<=1'd1;end
else if((key_data==4'b1111)&(flag==1))begin
flag<=1'd0;end
if(ccr1>=arr)
ccr1<=arr;
else if(ccr1<=1'd0)
ccr1<=1'd0;
if(arr<=1'd0)
arr<=1'd0;
end
end
通过四个按键控制arr值基于ccr1值的大小改变占空比和频率。
三,lcd显示
always @(posedge lcd_pclk or negedge rst_n) begin
if(!rst_n)
pixel_data <= BLACK;
else begin
if((pixel_xpos >= 11'd0) && (pixel_xpos <=h_disp/5*1))begin
if((pixel_xpos >= 11'd0) && (pixel_xpos <duty))begin
if((pixel_ypos<v_disp/4)&&(pixel_ypos>(v_disp/4-5)))//高电平
pixel_data<= WHITE;
else
pixel_data<= BLACK;
end
else if(pixel_xpos==duty)
if((pixel_ypos>v_disp/4)&&(pixel_ypos<v_disp/4*3))//下降沿
pixel_data<= WHITE;
else
pixel_data<= BLACK;
else if((pixel_xpos< h_disp/5*1) && (pixel_xpos>duty))
if((pixel_ypos<v_disp/4*3)&&(pixel_ypos>(v_disp/4*3-5)))//低电平
pixel_data<= WHITE;
else
pixel_data<= BLACK;
else if(pixel_xpos==h_disp/5*1)
if((pixel_ypos>v_disp/4)&&(pixel_ypos<v_disp/4*3))//上升沿
pixel_data<= WHITE;
else
pixel_data<= BLACK;
end
else if((pixel_xpos > h_disp/5*1) && (pixel_xpos <=h_disp/5*2))begin
if((pixel_xpos > h_disp/5*1) && (pixel_xpos <(h_disp/5*1+duty)))
if((pixel_ypos<v_disp/4)&&(pixel_ypos>(v_disp/4-5)))
pixel_data<= WHITE;
else
pixel_data<= BLACK;
else if(pixel_xpos==h_disp/5*1+duty)
if((pixel_ypos>v_disp/4)&&(pixel_ypos<v_disp/4*3))
pixel_data<= WHITE;
else
pixel_data<= BLACK;
else if((pixel_xpos< h_disp/5*2) && (pixel_xpos>(h_disp/5*1+duty)))
if((pixel_ypos<v_disp/4*3)&&(pixel_ypos>(v_disp/4*3-5)))
pixel_data<= WHITE;
else
pixel_data<= BLACK;
else if(pixel_xpos==h_disp/5*2)
if((pixel_ypos>v_disp/4)&&(pixel_ypos<v_disp/4*3))
pixel_data<= WHITE;
else
pixel_data<= BLACK;
end
else if((pixel_xpos > h_disp/5*2) && (pixel_xpos <=h_disp/5*3))begin
if((pixel_xpos > h_disp/5*2) && (pixel_xpos <(h_disp/5*2+duty)))
if((pixel_ypos<v_disp/4)&&(pixel_ypos>(v_disp/4-5)))
pixel_data<= WHITE;
else
pixel_data<= BLACK;
else if(pixel_xpos==h_disp/5*2+duty)
if((pixel_ypos>v_disp/4)&&(pixel_ypos<v_disp/4*3))
pixel_data<= WHITE;
else
pixel_data<= BLACK;
else if((pixel_xpos< h_disp/5*3) && (pixel_xpos>(h_disp/5*2+duty)))
if((pixel_ypos<v_disp/4*3)&&(pixel_ypos>(v_disp/4*3-5)))
pixel_data<= WHITE;
else
pixel_data<= BLACK;
else if(pixel_xpos==h_disp/5*3)
if((pixel_ypos>v_disp/4)&&(pixel_ypos<v_disp/4*3))
pixel_data<= WHITE;
else
pixel_data<= BLACK;
end
else if((pixel_xpos > h_disp/5*3) && (pixel_xpos <=h_disp/5*4))begin
if((pixel_xpos > h_disp/5*3) && (pixel_xpos <(h_disp/5*3+duty)))
if((pixel_ypos<v_disp/4)&&(pixel_ypos>(v_disp/4-5)))
pixel_data<= WHITE;
else
pixel_data<= BLACK;
else if(pixel_xpos==h_disp/5*3+duty)
if((pixel_ypos>v_disp/4)&&(pixel_ypos<v_disp/4*3))
pixel_data<= WHITE;
else
pixel_data<= BLACK;
else if((pixel_xpos< h_disp/5*4) && (pixel_xpos>(h_disp/5*3+duty)))
if((pixel_ypos<v_disp/4*3)&&(pixel_ypos>(v_disp/4*3-5)))
pixel_data<= WHITE;
else
pixel_data<= BLACK;
else if(pixel_xpos==h_disp/5*4)
if((pixel_ypos>v_disp/4)&&(pixel_ypos<v_disp/4*3))
pixel_data<=WHITE;
else
pixel_data<= BLACK;
end
else if((pixel_xpos > h_disp/5*4) && (pixel_xpos <=h_disp/5*5))begin
if((pixel_xpos > h_disp/5*4) && (pixel_xpos <(h_disp/5*4+duty)))
if((pixel_ypos<v_disp/4)&&(pixel_ypos>(v_disp/4-5)))
pixel_data<= WHITE;
else
pixel_data<= BLACK;
else if(pixel_xpos==h_disp/5*4+duty)
if((pixel_ypos>v_disp/4)&&(pixel_ypos<v_disp/4*3))
pixel_data<= WHITE;
else
pixel_data<= BLACK;
else if((pixel_xpos< h_disp/5*5) && (pixel_xpos>(h_disp/5*4+duty)))
if((pixel_ypos<v_disp/4*3)&&(pixel_ypos>(v_disp/4*3-5)))
pixel_data<= WHITE;
else
pixel_data<= BLACK;
else if(pixel_xpos==h_disp/5*5)
if((pixel_ypos>v_disp/4)&&(pixel_ypos<v_disp/4*3))
pixel_data<= WHITE;
else
pixel_data<= BLACK;
end
end
-
将lcd屏幕测垂直分辨率五等分,每等分的部分显示一个周期的方波, 当垂直像素和水平像素达到固定位置时显示该像素点为白色,其余为黑色。