参照anmkoADC程序里边对时序的使用,折腾了下DAC。
只弄有一路输出,只需要改变DAC寄存器里边的数据即可让其他路输出。
思路是这样的:
分频一个2M的计数器。使用这个计数器产生ADC的时钟信号、控制信号并进行输出。
还有不完善的地方,以后在改.
程序在下边:
/*************************************************
* Module Name : TLC5602DAC实验
* Engineer : hanshuyujifen
* Target Device : EP2C5Q208C8
* Tool versions : QII12
* Create Date : 2012-12-12
* Revision : v1.0
* Description : 控制1路DAC输出
**************************************************/
module mydac(sys_clk,sys_rstn,keys,dac_data,dac_clk,dac_ldac,dac_load);
input sys_clk,sys_rstn;
input [7:0] keys;
output dac_data,dac_clk,dac_ldac,dac_load;
reg dac_data;
wire dac_clk;
assign dac_ldac = 1'b0;
assign dac_load = (div_cnt>=0)&&(div_cnt <=21)|| (div_cnt>26);
//时钟
assign dac_clk = (div_cnt>=0 &&div_cnt < 1)||(div_cnt>=2 &&div_cnt < 3)||
(div_cnt>=4 &&div_cnt < 5)||(div_cnt>=6 &&div_cnt < 7)||
(div_cnt>=8 &&div_cnt < 9)||(div_cnt>=10 &&div_cnt < 11)||
(div_cnt>=12 &&div_cnt < 13)||(div_cnt>=14 &&div_cnt < 15)||
(div_cnt>=16 &&div_cnt < 17)||(div_cnt>=18 &&div_cnt < 19)||
(div_cnt>=20 &&div_cnt < 21);
//分频得到2MHZ时钟
reg [5:0] delay_cnt;
always @(posedge sys_clk,negedge sys_rstn)
begin
if(!sys_rstn)
begin
delay_cnt<= 6'b0;
end
else
begin
if(delay_cnt == 6'd24)
delay_cnt <= 6'd0;
else
delay_cnt <= delay_cnt + 1'b1;
end
end
reg [7:0] div_cnt;
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
div_cnt <= 8'd0;
else
begin
if(div_cnt == 8'd31)
div_cnt <= 8'd0;
else if(delay_cnt == 6'd24)
div_cnt <= div_cnt + 1'b1;
else
div_cnt <= div_cnt;
end
end
//向DAC发送数据
reg [10:0] data_r = 11'b11010101010; //要发送的数据
always @(posedge sys_clk,negedge sys_rstn)
if(!sys_rstn)
begin
dac_data <= 1'bz;
end
else
begin
case(div_cnt)
11'd0 : dac_data <= data_r[10];
11'd2 : dac_data <= data_r[9];
11'd4 : dac_data <= data_r[8];
11'd6 : dac_data <= data_r[7];
11'd8 : dac_data <= data_r[6];
11'd10 : dac_data <= data_r[5];
11'd12: dac_data <= data_r[4];
11'd14: dac_data <= data_r[3];
11'd16: dac_data <= data_r[2];
11'd18: dac_data <= data_r[1];
11'd20 : dac_data <= data_r[0];
default : dac_data <= dac_data;
endcase
end
endmodule





25楼
今天是世界末日,我在拯救了地球之后抽了点时间玩板子。
连着几天弄12864失败,对俺的信心打击很大。决定搞点简单的实验找找信心。
参考anmko进程贴,试玩PLL。
实验过程是这样的:
将ALT的PLL加入到工程,分别产生三个频率输出: c0 50M,c1 100M ,c2 150M。
对输出的频率分别计数25000000次,计满之后控制3个LED反转。同时将晶振输入进行25000000计数并控制LED反转。
观察实验现象,可看见是个led的频率差异。c1、c2控制的led闪烁明显要快些.
实验中同时使用了Y1晶振来作为PLL2的输入激励。可是我没焊接Y1晶振。于是PLL2输出所控制的LED保持常亮。
代码参考anmko进程贴:http://forum.eepw.com.cn/thread/221172/16#158
视频正在上传
连着几天弄12864失败,对俺的信心打击很大。决定搞点简单的实验找找信心。
参考anmko进程贴,试玩PLL。
实验过程是这样的:
将ALT的PLL加入到工程,分别产生三个频率输出: c0 50M,c1 100M ,c2 150M。
对输出的频率分别计数25000000次,计满之后控制3个LED反转。同时将晶振输入进行25000000计数并控制LED反转。
观察实验现象,可看见是个led的频率差异。c1、c2控制的led闪烁明显要快些.
实验中同时使用了Y1晶振来作为PLL2的输入激励。可是我没焊接Y1晶振。于是PLL2输出所控制的LED保持常亮。
代码参考anmko进程贴:http://forum.eepw.com.cn/thread/221172/16#158
视频正在上传

26楼
在折腾了几天驱动并失败之后,我觉得还是从基础实验做起吧。写点简单的程序,练习Verilog。
因为写驱动实在是太麻烦了,有时候一整天一行代码都写不出。根本谈不上练习Verilog了
于是今天晚上就做了几个。
第一个是简单的计数器,
/*************************************************
* Module Name : 计数器
* Engineer : hanshuyujifen
* Target Device : EP2C5Q208C8
* Tool versions :
* Create Date :
* Revision : v1.0
* Description :
**************************************************/
module COUNTER_EN(en,clk,rst,out);
parameter Width = 8; //参数,位宽
parameter U_DLY = 1;
input en,clk,rst;
output [Width-1:0] out;
reg [Width-1:0] out;
always @(posedge clk or negedge rst)
begin
if(!rst)
out <= 8'b0;
else
out<= #U_DLY out +1'b1; //这里的#U_DLY 不知道是什么意思
end
endmodule
第二个实验是练习加减乘除运算符的使用:
/*************************************************
* Module Name : 算数操作
* Engineer : hanshuyujifen
* Target Device : EP2C5Q208C8
* Tool versions : QII12
* Create Date : 2012-12-23
* Revision : v1.0
* Description : 加减乘除运算
**************************************************/
module ARTITHMETIC(A,B,Q1,Q2,Q3,Q4);
input [3:0] A,B; //输入
output [4:0] Q1; //加法输出
output [3:0] Q2; //减法输出
output [3:0] Q3; //除法
output [7:0] Q4; //乘法
reg [4:0] Q1;
reg [3:0] Q2;
reg [3:0] Q3;
reg [7:0] Q4;
always @(A or B)
begin
Q1 = A+B;
Q2 = A-B;
Q3 = A/2;
Q4 = A*B;
end
endmodule
最后一个,关系运算符练习:
module relational(A,B,Q1,Q2,Q3,Q4);
input [3:0] A,B;
output Q1,Q2,Q3,Q4;
reg Q1,Q2,Q3,Q4;
//电平触发
always@(A or B)
begin
Q1 = A>B;
Q2 = A<B;
Q3 = A>=B;
if(A<=B)
Q4 = 1;
else
Q4 = 0;
end
endmodule
这些模块都单独放置在一个文件里边,另建一个文件top.v,使用信号映射法调用这些模块:
module top(A,B,Q1,Q2,Q3,Q4);
input [3:0] A,B;
output Q1,Q2,Q3,Q4;
relational r1(
.A(A),
.B(B),
.Q1(Q1),
.Q2(Q2),
.Q3(Q3),
.Q4(Q4)
);
endmodule
因为写驱动实在是太麻烦了,有时候一整天一行代码都写不出。根本谈不上练习Verilog了
于是今天晚上就做了几个。
第一个是简单的计数器,
/*************************************************
* Module Name : 计数器
* Engineer : hanshuyujifen
* Target Device : EP2C5Q208C8
* Tool versions :
* Create Date :
* Revision : v1.0
* Description :
**************************************************/
module COUNTER_EN(en,clk,rst,out);
parameter Width = 8; //参数,位宽
parameter U_DLY = 1;
input en,clk,rst;
output [Width-1:0] out;
reg [Width-1:0] out;
always @(posedge clk or negedge rst)
begin
if(!rst)
out <= 8'b0;
else
out<= #U_DLY out +1'b1; //这里的#U_DLY 不知道是什么意思
end
endmodule
第二个实验是练习加减乘除运算符的使用:
/*************************************************
* Module Name : 算数操作
* Engineer : hanshuyujifen
* Target Device : EP2C5Q208C8
* Tool versions : QII12
* Create Date : 2012-12-23
* Revision : v1.0
* Description : 加减乘除运算
**************************************************/
module ARTITHMETIC(A,B,Q1,Q2,Q3,Q4);
input [3:0] A,B; //输入
output [4:0] Q1; //加法输出
output [3:0] Q2; //减法输出
output [3:0] Q3; //除法
output [7:0] Q4; //乘法
reg [4:0] Q1;
reg [3:0] Q2;
reg [3:0] Q3;
reg [7:0] Q4;
always @(A or B)
begin
Q1 = A+B;
Q2 = A-B;
Q3 = A/2;
Q4 = A*B;
end
endmodule
最后一个,关系运算符练习:
module relational(A,B,Q1,Q2,Q3,Q4);
input [3:0] A,B;
output Q1,Q2,Q3,Q4;
reg Q1,Q2,Q3,Q4;
//电平触发
always@(A or B)
begin
Q1 = A>B;
Q2 = A<B;
Q3 = A>=B;
if(A<=B)
Q4 = 1;
else
Q4 = 0;
end
endmodule
这些模块都单独放置在一个文件里边,另建一个文件top.v,使用信号映射法调用这些模块:
module top(A,B,Q1,Q2,Q3,Q4);
input [3:0] A,B;
output Q1,Q2,Q3,Q4;
relational r1(
.A(A),
.B(B),
.Q1(Q1),
.Q2(Q2),
.Q3(Q3),
.Q4(Q4)
);
endmodule

27楼
移位运算符>>和<<使用
module shifter(Data,Q1,Q2);
input [3:0] Data;
output [3:0] Q1,Q2;
parameter B = 2;
reg [3:0] Q1,Q2;
always @(Data)
begin
Q1 = Data<<B;
Q2 = Data>>B;
end
endmodule
试验了移位操作。
以下是参数化调用这个方法,因为模块里边有个参数B。
一种是使用#,一种是使用关键字defparam.路径的方法
module top(Data1,Data2,Q1,Q2,Q3,Q4);
input [3:0] Data1,Data2;
output Q1,Q2,Q3,Q4;
wire [3:0] Data;
reg [3:0] databuf1,databuf2;
//参数传递的方法1
shifter#(5) S1(
.Data(Data1),
.Q1(Q1),
.Q2(Q2)
);
//参数传递方法2
shifter S2(
.Data(Data2),
.Q1(Q3),
.Q2(Q4)
);
defparam S2.B = 3;
endmodule
module shifter(Data,Q1,Q2);
input [3:0] Data;
output [3:0] Q1,Q2;
parameter B = 2;
reg [3:0] Q1,Q2;
always @(Data)
begin
Q1 = Data<<B;
Q2 = Data>>B;
end
endmodule
试验了移位操作。
以下是参数化调用这个方法,因为模块里边有个参数B。
一种是使用#,一种是使用关键字defparam.路径的方法
module top(Data1,Data2,Q1,Q2,Q3,Q4);
input [3:0] Data1,Data2;
output Q1,Q2,Q3,Q4;
wire [3:0] Data;
reg [3:0] databuf1,databuf2;
//参数传递的方法1
shifter#(5) S1(
.Data(Data1),
.Q1(Q1),
.Q2(Q2)
);
//参数传递方法2
shifter S2(
.Data(Data2),
.Q1(Q3),
.Q2(Q4)
);
defparam S2.B = 3;
endmodule

28楼
体会下什么叫同步什么叫异步。感觉同步就应该是信号来了马上变化,异步就是信号来了等到下一个时钟才变化。
同步复位器是这样的:
module dff_sync_rst(clk,rst,data,q);
input clk,rst,data;
output q;
parameter U_DLY = 1;
reg q;
always @(posedge clk)
begin
if(!rst)
q<= #U_DLY 1'b0;
else
q<= #U_DLY data;
end
endmodule
顶层模块调用:
module top(clk,rst,data,q);
input clk,rst,data;
output q;
dff_sync_rst dff1(
.clk(clk),
.rst(rst),
.data(data),
.q(q)
);
defparam dff1.U_DLY = 2;
endmodule
这个U_DLY不知道神干什么的,应该是仿真时候用的吧?因为RTL View里边没没看见什么效果。求解
同步复位器是这样的:
module dff_sync_rst(clk,rst,data,q);
input clk,rst,data;
output q;
parameter U_DLY = 1;
reg q;
always @(posedge clk)
begin
if(!rst)
q<= #U_DLY 1'b0;
else
q<= #U_DLY data;
end
endmodule
顶层模块调用:
module top(clk,rst,data,q);
input clk,rst,data;
output q;
dff_sync_rst dff1(
.clk(clk),
.rst(rst),
.data(data),
.q(q)
);
defparam dff1.U_DLY = 2;
endmodule
这个U_DLY不知道神干什么的,应该是仿真时候用的吧?因为RTL View里边没没看见什么效果。求解

29楼
使能信号en控制输出
module dff_ck_en(clk,rst,en,data,q);
input clk,rst,en,data;
output q;
parameter U_DLY = 1;
reg q;
always @(posedge clk or negedge rst)
begin
if(!rst)
q <= 1'b0;
else if(en)
q <= #U_DLY data;
else
q<= #U_DLY 1;
end
endmodule
顶层调用,信号映射法:
module top(clk,rst,en,data,q);
input clk,rst,en,data;
output q;
dff_ck_en dce(
.clk(clk),
.rst(rst),
.en(en),
.data(data),
.q(q)
);
endmodule
module dff_ck_en(clk,rst,en,data,q);
input clk,rst,en,data;
output q;
parameter U_DLY = 1;
reg q;
always @(posedge clk or negedge rst)
begin
if(!rst)
q <= 1'b0;
else if(en)
q <= #U_DLY data;
else
q<= #U_DLY 1;
end
endmodule
顶层调用,信号映射法:
module top(clk,rst,en,data,q);
input clk,rst,en,data;
output q;
dff_ck_en dce(
.clk(clk),
.rst(rst),
.en(en),
.data(data),
.q(q)
);
endmodule

30楼
vga显示使用了模块化设计,将整个模块分为VGA控制模块和视频同步模块。
下边是VGA同步模块及注释
根据anmko进程贴里边的说明,50MHZ晶振选择使用860×600×60HZ显示效果最好。
这个模块控制产生VGA显示所需的行同步和场同步信号。
同时产生当前行是否在有效显示区域信号、当前显示的行地址和列地址。
VGA显示时序分析可参考anmko进程贴,贴图太麻烦了。俺懒
/*************************************************
* Module Name : sync_module
* Engineer : hanshuyujifen
* Target Device : EP2C5Q208C8
* Tool versions :
* Create Date :
* Revision : v1.0
* Description : VGA显示同步控制模块
**************************************************/
//sys_clk 50MHZ时钟
module sync_module(sys_clk,sys_rstn,vga_hsync,vga_vsync,isReady,Colum_add_sig,Row_add_sig);
input sys_clk,sys_rstn;
output vga_hsync,vga_vsync,isReady;
output [10:0] Colum_add_sig;
output [9:0] Row_add_sig;
reg [10:0] h_cnt;
reg [9:0] v_cnt;
reg isReady;
//产生vga_hsync信号
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
h_cnt <= 11'd0;
else
begin
if(h_cnt == 11'd1039)
h_cnt<=11'd0;
else
h_cnt<=h_cnt+1'b1;
end
end
assign vga_hsync = ~((h_cnt>=0)&&(h_cnt<120)); //产生行同步信号
//产生vga_vsync信号
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
v_cnt <= 10'd0;
else
begin
if(v_cnt == 10'd665)
v_cnt <= 10'd0;
else if(h_cnt == 11'd1039)
v_cnt <= v_cnt+1'b1;
else
v_cnt <= v_cnt;
end
end
assign vga_vsync = (v_cnt>=0)&&(v_cnt<6); //场同步信号
//输出是否在有效区域
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
isReady <= 1'b0;
else
isReady <= (h_cnt>=180 && h_cnt<986) &&(v_cnt>= 27 && v_cnt< 631);
end
//输出当前地址(x,y)
assign Colum_add_sig = isReady ? h_cnt-11'd181 : 11'd0;
assign Row_add_sig = isReady ?v_cnt - 10'd27 : 10'd0;
endmodule
回复
有奖活动 | |
---|---|
【EEPW电子工程师创研计划】技术变现通道已开启~ | |
发原创文章 【每月瓜分千元赏金 凭实力攒钱买好礼~】 | |
【EEPW在线】E起听工程师的声音! | |
“我踩过的那些坑”主题活动——第001期 | |
高校联络员开始招募啦!有惊喜!! | |
【工程师专属福利】每天30秒,积分轻松拿!EEPW宠粉打卡计划启动! | |
送您一块开发板,2025年“我要开发板活动”又开始了! | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
【我踩过的那些坑】接线错误导致测试数据异常被打赏40分 | |
stm32f103驱动舵机被打赏20分 | |
汽车+汽车电子电阻解释与分析被打赏5分 | |
STM32F103的I2C驱动OLED动态显示被打赏30分 | |
分享汽车通信和多媒体总线结构被打赏20分 | |
【我踩过的那些坑】结构堵孔导致的喇叭无声问题被打赏50分 | |
NUCLEO-U083RC学习历程38+串口通过队列的方式输出两个字符串被打赏20分 | |
【我踩过的那些坑】分享一下调试一款AD芯片的遇到的“坑”被打赏50分 | |
电流检测模块MAX4080S被打赏10分 | |
【我踩过的那些坑】calloc和malloc错误使用导致跑飞问题排查被打赏50分 |