今天开始AD转换试验。
刚开始的思路是这样的:
TL549的一些极限参数:Fioclk = 1.1M,tsu = 1.4us,twh = 17us。
所以确定的应用参数是这样的:Fioclk = 1M(tioclk = 1us),tsu = 1.5us,twh = 17us。
需要弄出来三个分频器,分别产生周期1us、1.5us和17us的波形。
后来参考anmko的程序,发现这样真的很麻烦。anmko简直将时序用到了极致,真的很佩服。
于是就仔细研究了他的程序,然后自己动手按照他的思路来写程序。弄了一晚上,到现在还没出来。明天接着弄。
又学了一招,挺好。
23楼
继续AD试验
参考原理图,调节电位计R63,AD输入电压应在0到2.5V之间变化。
今天完成AD转换数据的数码管显示部分。
完全没有进行滤波,得到的数据跳变很严重。
/*************************************************
* Module Name : TL549 AD转换数码管显示
* Engineer : hanshuyujifen
* Target Device : EP2C5Q208C8
* Tool versions : QII12
* Create Date : 2012.12.10
* Revision : v1.0
* Description : TL549AD转换并用数码管显示
**************************************************/
module mytl549(
sys_clk,
sys_rstn,
ad_clk,
ad_data,
ad_csn,
seg,
smbit);
input sys_clk,sys_rstn;
input ad_data;
output ad_csn,ad_clk;
output [7:0] seg,smbit;
reg ad_csn;
reg ad_clk ;
reg [7:0] seg;
reg [7:0] smbit;
wire cs_n_read;
wire cs_high;
wire convert;
reg [10:0] div_cnt;
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
div_cnt <=11'b0;
else if(div_cnt == 11'd1350)
div_cnt <= 11'b0;
else
div_cnt <= div_cnt+1'b1;
end
//产生cs信号
assign cs_n_read = (div_cnt>11'd74) &&(div_cnt<=11'd425); //读取AD数据
assign cs_high = (div_cnt>11'd425) && (div_cnt<= 11'd1325); //AD数据准备
assign convert = (div_cnt == 11'd425) ? 1 :0; //AD开始转换标志
//CS信号
always @(posedge sys_clk,negedge sys_rstn)
begin
if(!sys_rstn)
begin
ad_csn <= 1'b1;
end
else
begin
if(cs_high)
ad_csn <= 1'b1;
else
ad_csn <= 1'b0;
end
end
//产生IO时钟信号
reg [10:0] delay_cnt;
always @(posedge sys_clk,negedge sys_rstn)
begin
if(!sys_rstn)
begin
delay_cnt<= 11'b0;
ad_clk <=1'b0;
end
else
begin
if(cs_n_read)
begin
if(delay_cnt == 11'd49)
delay_cnt <= 11'd0;
else
begin
delay_cnt <= delay_cnt + 1'b1;
end
if(delay_cnt>=11'd0 && delay_cnt< 11'd25)
ad_clk <= 1'b0;
else if(delay_cnt>=11'd25 && delay_cnt<11'd50)
ad_clk <= 1'b1;
else
ad_clk <= 1'b0;
end
end
end
//读数据
reg [7:0] read_data;
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
read_data <= 8'b0;
else
if(div_cnt == 11'd75)
read_data[7] <= ad_data;
else if(div_cnt == 11'd125)
read_data[6] <= ad_data;
else if(div_cnt == 11'd175)
read_data[5] <= ad_data;
else if(div_cnt == 11'd225)
read_data[4] <= ad_data;
else if(div_cnt == 11'd275)
read_data[3] <= ad_data;
else if(div_cnt == 11'd325)
read_data[2] <= ad_data;
else if(div_cnt == 11'd375)
read_data[1] <= ad_data;
else if(div_cnt == 11'd425)
read_data[0] <= ad_data;
end
//扫描定时器
reg [15:0] delay_cnt1; //扫描周期,1ms
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
delay_cnt1 <= 16'd0;
else
begin
if(delay_cnt1 == 16'd49999)
delay_cnt1 <= 16'd0;
else
delay_cnt1 <= delay_cnt1 +1'b1;
end
end
//扫描部分,周期1ms。先设置段码再设置位码。
reg [7:0] databuf1;
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
smbit <= 8'b11111110;
else
begin
if(delay_cnt1 == 16'd49999)
begin
if(smbit == 8'b11111110)
begin //十位
databuf1 <= read_data/10;
smbit <= 8'b11111101;
end
else if(smbit == 8'b11111101)
begin //百位
databuf1 <= read_data/100;
smbit <= 8'b11111011;
end
else if(smbit == 8'b11111011)
begin //个位
databuf1 <= read_data%10;
smbit <= 8'b11111110;
end
end
end
end
//显示部分,相当于译码器
always @(databuf1)
begin
case(databuf1)
4'h0 :seg = 8'hc0;
4'h1 :seg = 8'hf9;
4'h2 :seg = 8'ha4;
4'h3 :seg = 8'hb0;
4'h4 :seg = 8'h99;
4'h5 :seg = 8'h92;
4'h6 :seg = 8'h82;
4'h7 :seg = 8'hf8;
4'h8 :seg = 8'h80;
4'h9 :seg = 8'h90;
4'hA :seg = 8'h88;
4'hB :seg = 8'h83;
4'hC :seg = 8'hc6;
4'hD :seg = 8'ha1;
4'hE :seg = 8'h86;
4'hF :seg = 8'h8e;
endcase
end
endmodule
参考原理图,调节电位计R63,AD输入电压应在0到2.5V之间变化。
今天完成AD转换数据的数码管显示部分。
完全没有进行滤波,得到的数据跳变很严重。
/*************************************************
* Module Name : TL549 AD转换数码管显示
* Engineer : hanshuyujifen
* Target Device : EP2C5Q208C8
* Tool versions : QII12
* Create Date : 2012.12.10
* Revision : v1.0
* Description : TL549AD转换并用数码管显示
**************************************************/
module mytl549(
sys_clk,
sys_rstn,
ad_clk,
ad_data,
ad_csn,
seg,
smbit);
input sys_clk,sys_rstn;
input ad_data;
output ad_csn,ad_clk;
output [7:0] seg,smbit;
reg ad_csn;
reg ad_clk ;
reg [7:0] seg;
reg [7:0] smbit;
wire cs_n_read;
wire cs_high;
wire convert;
reg [10:0] div_cnt;
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
div_cnt <=11'b0;
else if(div_cnt == 11'd1350)
div_cnt <= 11'b0;
else
div_cnt <= div_cnt+1'b1;
end
//产生cs信号
assign cs_n_read = (div_cnt>11'd74) &&(div_cnt<=11'd425); //读取AD数据
assign cs_high = (div_cnt>11'd425) && (div_cnt<= 11'd1325); //AD数据准备
assign convert = (div_cnt == 11'd425) ? 1 :0; //AD开始转换标志
//CS信号
always @(posedge sys_clk,negedge sys_rstn)
begin
if(!sys_rstn)
begin
ad_csn <= 1'b1;
end
else
begin
if(cs_high)
ad_csn <= 1'b1;
else
ad_csn <= 1'b0;
end
end
//产生IO时钟信号
reg [10:0] delay_cnt;
always @(posedge sys_clk,negedge sys_rstn)
begin
if(!sys_rstn)
begin
delay_cnt<= 11'b0;
ad_clk <=1'b0;
end
else
begin
if(cs_n_read)
begin
if(delay_cnt == 11'd49)
delay_cnt <= 11'd0;
else
begin
delay_cnt <= delay_cnt + 1'b1;
end
if(delay_cnt>=11'd0 && delay_cnt< 11'd25)
ad_clk <= 1'b0;
else if(delay_cnt>=11'd25 && delay_cnt<11'd50)
ad_clk <= 1'b1;
else
ad_clk <= 1'b0;
end
end
end
//读数据
reg [7:0] read_data;
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
read_data <= 8'b0;
else
if(div_cnt == 11'd75)
read_data[7] <= ad_data;
else if(div_cnt == 11'd125)
read_data[6] <= ad_data;
else if(div_cnt == 11'd175)
read_data[5] <= ad_data;
else if(div_cnt == 11'd225)
read_data[4] <= ad_data;
else if(div_cnt == 11'd275)
read_data[3] <= ad_data;
else if(div_cnt == 11'd325)
read_data[2] <= ad_data;
else if(div_cnt == 11'd375)
read_data[1] <= ad_data;
else if(div_cnt == 11'd425)
read_data[0] <= ad_data;
end
//扫描定时器
reg [15:0] delay_cnt1; //扫描周期,1ms
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
delay_cnt1 <= 16'd0;
else
begin
if(delay_cnt1 == 16'd49999)
delay_cnt1 <= 16'd0;
else
delay_cnt1 <= delay_cnt1 +1'b1;
end
end
//扫描部分,周期1ms。先设置段码再设置位码。
reg [7:0] databuf1;
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
smbit <= 8'b11111110;
else
begin
if(delay_cnt1 == 16'd49999)
begin
if(smbit == 8'b11111110)
begin //十位
databuf1 <= read_data/10;
smbit <= 8'b11111101;
end
else if(smbit == 8'b11111101)
begin //百位
databuf1 <= read_data/100;
smbit <= 8'b11111011;
end
else if(smbit == 8'b11111011)
begin //个位
databuf1 <= read_data%10;
smbit <= 8'b11111110;
end
end
end
end
//显示部分,相当于译码器
always @(databuf1)
begin
case(databuf1)
4'h0 :seg = 8'hc0;
4'h1 :seg = 8'hf9;
4'h2 :seg = 8'ha4;
4'h3 :seg = 8'hb0;
4'h4 :seg = 8'h99;
4'h5 :seg = 8'h92;
4'h6 :seg = 8'h82;
4'h7 :seg = 8'hf8;
4'h8 :seg = 8'h80;
4'h9 :seg = 8'h90;
4'hA :seg = 8'h88;
4'hB :seg = 8'h83;
4'hC :seg = 8'hc6;
4'hD :seg = 8'ha1;
4'hE :seg = 8'h86;
4'hF :seg = 8'h8e;
endcase
end
endmodule
24楼
DAC折腾失败,原因是频率计算错误。
分频得到2M的时钟,任何计数输出CLK data和 ldac
计数时候使用的竟然是系统时钟。。。。
示波器看看,发现完全不对,才找到原因的。真是太马虎了
分频得到2M的时钟,任何计数输出CLK data和 ldac
计数时候使用的竟然是系统时钟。。。。
示波器看看,发现完全不对,才找到原因的。真是太马虎了
25楼
参照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
只弄有一路输出,只需要改变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
27楼
51FPGA用的那个12864LCD是带汉字库、SPI接口的LCD模块,这次DIY的接口板PCB布线只能使用他的那种LCD模块。我用通用的12864LCD根本就动不了。如果你的LCD模块跟我的一样,不是使用跟51FPGA一样带字库的,就死心别试了,硬件完全不兼容的。
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
vscode+cmake搭建雅特力AT32L021开发环境被打赏30分 | |
【换取逻辑分析仪】自制底板并驱动ArduinoNanoRP2040ConnectLCD扩展板被打赏47分 | |
【分享评测,赢取加热台】RISC-V GCC 内嵌汇编使用被打赏38分 | |
【换取逻辑分析仪】-基于ADI单片机MAX78000的简易MP3音乐播放器被打赏48分 | |
我想要一部加热台+树莓派PICO驱动AHT10被打赏38分 | |
【换取逻辑分析仪】-硬件SPI驱动OLED屏幕被打赏36分 | |
换逻辑分析仪+上下拉与多路选择器被打赏29分 | |
Let'sdo第3期任务合集被打赏50分 | |
换逻辑分析仪+Verilog三态门被打赏27分 | |
换逻辑分析仪+Verilog多输出门被打赏24分 |