打印

求助哪位大大有FPGA控制DA的例程

[复制链接]
2720|5
手机看帖
扫描二维码
随时随地手机跟帖
沙发
6673663king|  楼主 | 2011-4-11 17:17 | 只看该作者
咋米人呢,哎,好急啊

使用特权

评论回复
板凳
sxhhhjicbb| | 2011-4-11 19:31 | 只看该作者
直接求程序的比较难..自已研究后再问,讨论的人会多些.论谈差不多就这样.

使用特权

评论回复
地板
lwq030736| | 2011-4-11 20:23 | 只看该作者
教材上不是有吗?用有限状态机就可以了,书上是控制DAC0809的。不过道理一样的,根据DA的数据手册来控制就行了。

使用特权

评论回复
5
viatuzi| | 2011-4-27 20:30 | 只看该作者
这个是多年前初学verilog的时候写的DAC7731的控制程序,当时是做DDS的输出频率控制的,中间涉及到一些DDS的东西,可以参考一下。
有几个地方要注意:
   1. 同时用了时钟的正沿和负沿做触发,这个不是好习惯,在设计中尽量避免。
   2.只是针对DAC7731的控制时序,采用计数器计数的方式来生成各种控制逻辑,通用性比较差,可以改用状态机。
      3. 当时做功率信号发生器的,输出频率比较低,所以整个系统的控制随便写就都满足要求了。如果想要运行在比较高的频率下,代码要做进一步的优化。
      
module fre_da_ptos(
                   sout_permission_0,clk,rst,fr_da_clk,flash_data,
                   dds_foot_length,flash_ce,flash_oe,flash_add,
                   fr_da_cs,fr_da_sclk,fr_da_data,fr_da_ldac,fr_da_rst
                   );

input sout_permission_0;         //数据输出允许信号,高电平有效,系统初始化时为低电平              
input clk;                       //FPGA系统时钟20MHz      
input rst;                       //复位信号
input fr_da_clk;                 //频率DA输出刷新频率控制时钟
input [15:0] flash_data;         //FLASH存储器数据输入接口
input [21:0] dds_foot_length;    //DDS步长控制输入

output flash_ce;                 //FLASH存储器控制,片选信号,低电平有效
output flash_oe;                 //FLASH存储器控制,读允许信号,低电平有效
output [19:0] flash_add;         //FLASH存储器地址输出接口
output fr_da_cs;                 //频率DA控制,片选信号,低电平有效
output fr_da_sclk;               //频率DA控制,时钟信号,有效时频率等于FPGA系统时钟,20MHz
output fr_da_data;               //频率DA控制,数据信号
output fr_da_ldac;               //频率DA控制,DA输出允许信号,上升沿有效
output fr_da_rst;                //频率DA控制,复位信号

reg flash_ce;                    
reg flash_oe;
reg fr_da_cs;
reg fr_da_data;
reg fr_da_ldac;
reg fr_da_rst;
wire fr_da_sclk;


reg [19:0] flash_add;
reg [21:0] flash_add_temp;    //地址寄存器1,存储真实地址
reg [19:0] flash_add_temp2;   //地址寄存器2,存储经处理后的地址
reg [15:0] flash_data_temp;  //FLASH输入数据寄存器,先从FLASH读取数据存入该寄存器,然后转换为串行数据
reg [5:0] s_clk_counter;  //时钟周期计数器,控制FLASH数据读取和数据转换

wire da_clk_mark;         //时钟标记
reg da_clk_mark_temp1;    //DA时钟标记1,当系统复位后,其值为1,在da_clk_fre的上升沿,变为相反的值
reg da_clk_mark_temp2;    //DA时钟标记2

assign fr_da_sclk =  (s_clk_counter >= 6'd10 && s_clk_counter <=25) ? clk : 1'b0 ;
assign da_clk_mark = da_clk_mark_temp1 ^ da_clk_mark_temp2;  //标记1与标记2异或运算,得到时钟标记

always @ (posedge fr_da_clk or negedge rst)
   begin
                   if(!rst)
                           da_clk_mark_temp1 <=1'b0;
                   else
                           da_clk_mark_temp1 <= ~da_clk_mark_temp1;
   end
   
always @(posedge clk or negedge rst)
     begin
         if(!rst)
            begin
                flash_oe <= 1'b0;
                fr_da_rst <= 1'b0;
                fr_da_ldac <= 1'b1;
                da_clk_mark_temp2 <= 1'b0;
                s_clk_counter <= 6'b00_0000;
                flash_add <= 20'b0000_0000_0000_0000_0000;
                flash_add_temp <= 22'b00_0000_0000_0000_0000_0000;
                flash_add_temp2 <= 20'b0000_0000_0000_0000_0000;
            end
        else
           if(da_clk_mark === 1'b0 && sout_permission_0 === 1'b1)
           case(s_clk_counter)
           6'd0:
              begin
                  //判断是否是直流信号输出,如果是直流信号的话,将基地址
                  //初始化为262144,即频率生成DA保持10V输出。
                  if(dds_foot_length === 22'b00_0000_0000_0000_0000_0000)
                     flash_add_temp2 <= 20'd262144;
                  s_clk_counter <= s_clk_counter + 1'b1;
                  if(fr_da_rst != 1'b1)
                      fr_da_rst <= 1'b1;
              end
           6'd1:
                  s_clk_counter <= s_clk_counter + 1'b1;
           6'd2:
              begin
                 flash_add <= flash_add_temp2;
                 s_clk_counter <= s_clk_counter + 1'b1;
              end
           6'd3:
              begin
                  s_clk_counter <= s_clk_counter + 1'b1;
              end
           6'd4:
               begin
                flash_data_temp <= flash_data;
               s_clk_counter <= s_clk_counter + 1'b1;
               end
           6'd5:
              begin
                  s_clk_counter <= s_clk_counter + 1'b1;
              end
           6'd6:
              begin
                  flash_add <= 20'bzzzz_zzzz_zzzz_zzzz_zzzz;
                  s_clk_counter <= s_clk_counter + 1'b1;
              end
           6'd7:
              begin
                 s_clk_counter <= s_clk_counter + 1'b1;
              end     
           6'd8:
              begin
                  
                  s_clk_counter <= s_clk_counter + 1'b1;
              end
          6'd9,6'd10,6'd11,6'd12,6'd13,6'd14,6'd15,6'd16,6'd17,6'd18,6'd19,6'd20,6'd21,
          6'd22,6'd23 :
                  s_clk_counter <= s_clk_counter + 1'b1;
           6'd24:
                           begin
                  s_clk_counter <= s_clk_counter + 1'b1;
                  fr_da_ldac <= 1'b0;
              end
           6'd25:
              begin
                  s_clk_counter <= s_clk_counter + 1'b1;
                  fr_da_ldac <= 1'b1;  
              end
           6'd26:      
                  s_clk_counter <= s_clk_counter + 1'b1;
           6'd27:
                  s_clk_counter <= s_clk_counter + 1'b1;  
           6'd28:
              begin
                  s_clk_counter <= s_clk_counter + 1'b1;
                 
                  flash_add_temp <= flash_add_temp + dds_foot_length;
              end
           6'd29:
                  s_clk_counter <= s_clk_counter + 1'b1;
           6'd30:
              begin
                   flash_add_temp2 <= flash_add_temp[19:0];
                  s_clk_counter <= 6'b00_0000;
                  da_clk_mark_temp2 <= ~da_clk_mark_temp2;     
            end
        endcase
                end

always @(negedge clk or negedge rst)
   begin
            if(!rst)
              begin
                fr_da_cs <= 1'b0;
            flash_ce <= 1'b0;
               end
        else
         begin  
                     if(s_clk_counter === 6'd8)
                         begin
                           fr_da_data <= flash_data_temp[15];
                         end
                     else if (s_clk_counter >6'd9 && s_clk_counter <6'd24)
                            fr_da_data <= flash_data_temp[6'd24 - s_clk_counter];
          end
    end
endmodule

使用特权

评论回复
6
tear086| | 2011-4-29 10:43 | 只看该作者

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

100

主题

129

帖子

1

粉丝