电子产品世界 » 论坛首页 » 电子DIY » FPGA DIY » anmko的进程贴:综合实验-基于DS1302的万年历LCD1602显示(最终版


共223条 11/23 |‹ 9 10 11 12 13 14 ›| 跳转至
专家
2012-10-18 15:16:02    评分
101楼
速度好快,关注中.

高工
2012-10-18 18:20:23    评分
102楼
帖子题目可以改?

高工
2012-10-18 19:48:18    评分
103楼
可以改的,在1楼有设置选项的

菜鸟
2012-10-18 21:06:57    评分
104楼

收藏了~NICE


助工
2012-10-19 11:14:34    评分
105楼
参考学习!呵呵

专家
2012-10-19 12:34:39    评分
106楼
楼主真是厉害啊~~
向楼主学习~~

助工
2012-10-19 14:24:46    评分
107楼
niu ren  ,我来看你了

高工
2012-10-19 22:48:58    评分
108楼

我都不好意思了。。


高工
2012-10-20 17:26:53    评分
109楼

15、TLC549AD转换时序详解(源代码注释)
       了解一个芯片的功能应该看它的参数,应用一个芯片你就得认真的去读懂它的时序图。
改进了上次的实验,加入了256的8位的缓存,并求平均。

          由图1、图2可知道 :
1、f(ioclk)max=1.1MHz。
2、t(su)min=1.4us。
3、t(wh)min=17us。
4、CS为低电平的时候读取数据;高电平的时候AD转换。
5、数据的读取需要8个ioclk,在ioclk上升沿的时候读取数据位。 
6、数据必须在CS置零1.4us后才能读取。 
  

                          图1: TLC549的信号时序图                                        

                                            图2: TLC549相关参数

在本次实验中参数如下选取
1、f(ioclk)=1MHz。
2、t(su)=1.5us。
3、t(wh)=17us。


因为FPGA的主时钟是50Mhz (t(sys)=0.02us)
所以t(ioclk)=50*t(sys);
       t(su)=1.5us=75*t(sys);
       t(wh)=17us=850*t(sys);

那么一次AD转换读取需要的时间为:
   t(su)+8*t(ioclk)+t(wh)=(75+8*50+850)*t(sys)=1325*t(sys)


module TLC549ADC
(
 input rst,
 input clk,
 input adc_data,
 output reg cs,
 output reg ioclk,
 output reg [7:0] led_out,
 output reg [3:0] V_H,
 output reg [3:0] V_L,
 output reg [3:0] Va_100,
 output reg [3:0] Va_10,
 output reg [3:0] Va_1
);
 integer k;
 reg signed [7:0] data_r [255:0]; //256个8位的数据缓存
  
 //clk计数器
 reg [11:0] clk_cnt;
 wire cs_n_read;
 wire cs_high;
 wire conover;
 
 //时钟计数器
 always @(posedge clk or negedge rst) begin
  if(!rst)
   clk_cnt <= 11'd0;
  else if(clk_cnt >=11'd1325)
   clk_cnt <= 11'b0;
  else
   clk_cnt <= clk_cnt + 1'b1;
 end
 // t(su)+8*t(ioclk)+t(wh)=(75+8*50+850)*t(sys)=1325*t(sys)
 assign cs_n_read = (clk_cnt > 11'd74)&&(clk_cnt <= 11'd475); //400个t(sys)
 assign cs_high  = (clk_cnt > 11'd475)&&(clk_cnt <= 11'd1325);//850个t(sys)
 assign conover = (clk_cnt == 11'd425) ? 1'b1 : 1'b0; //数据读取完后conover有一个上升沿
 
 //CS的时序;在AD转换的过程中CS为高电平,在数据读取的过程中CS为低电平。
 always @(posedge clk or negedge rst) begin
  if(!rst)
   cs <= 1'b1;
  else if(cs_high)
   cs <= 1'b1;
  else
   cs <= 1'b0;
 end
 
 //50分频;提供IOClk信号 
 reg [5:0] div_cnt;
 always @(posedge clk or negedge rst) begin
  if(!rst) begin
   div_cnt <= 6'd0;
   ioclk <= 1'b0;
   end
  else if(cs_n_read) begin   //从第75t(sys)到第475t(sys),这400个时钟里才有IOCLK信号,
             //才能读取数据,这样保证在0到第74t(sys)CS是低电平的。
   div_cnt <= div_cnt + 1'b1;  
   if(div_cnt < 6'd25)
    ioclk <= 1'b1;
   else if((div_cnt >= 6'd25)&&(div_cnt < 6'd50))
    ioclk <= 1'b0;
   else
    div_cnt <= 6'b0;
  end
 end
 
 //读取数据
 reg[7:0] radc_data;
 always @(posedge clk or negedge rst) begin
  if(!rst)
   radc_data <= 8'b0;
  else
  begin
   case(clk_cnt) //没50个t(sys)读取一个数据位
     11'd75: radc_data[7] <= adc_data;
     11'd125: radc_data[6] <= adc_data;
     11'd175: radc_data[5] <= adc_data;
     11'd225: radc_data[4] <= adc_data;
     11'd275: radc_data[3] <= adc_data;
     11'd325: radc_data[2] <= adc_data;
     11'd375: radc_data[1] <= adc_data;
     11'd425: radc_data[0] <= adc_data; 
     default: radc_data[0] <= 1'b0;
   endcase
  end
 end     
 
 //数据处理,conover
 reg [7:0] data_cnt;
 reg [15:0] Sum;
 always @(posedge conover or negedge rst) begin
  if(!rst)
  begin
   for(k=0;k<=255;k=k+1)
    data_r [k] = 8'b0;
    led_out <= 8'hx;
  end
  else
  begin
   data_r[data_cnt] <= radc_data;
   data_cnt <= data_cnt + 1'b1; //单个数据放入缓存
   if(data_cnt == 8'd255)
   begin      //写满256个缓存数据
    for(k=0;k<=255;k=k+1)
     Sum = Sum + data_r[k];
    Sum = Sum/255;   //求平均
    V_H = Sum[7:4];
    V_L = Sum[3:0];
    Sum = Sum*245/255; //换算成电压值
    led_out <= ~Sum[7:0];
    Va_100 <= Sum[7:0]/100;
    Va_10 <= Sum[7:0]/10%10;
    Va_1 <= Sum[7:0]%10; 
   end
  end
 end
  
endmodule

改进后效果明显比上次好一些


sof、pof下载:
时钟为Y1——回复可见内容——
时钟为Y2——回复可见内容——


工程师
2012-10-20 17:55:30    评分
110楼
我的也焊完了, 下个文件测试看一下

共223条 11/23 |‹ 9 10 11 12 13 14 ›| 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]