原创 【博客大赛】数模转换----束手就擒吧

2014-9-4 21:10 1813 6 12 分类: 通信 文集: FPGA设计经验

 

AD5641为2.7V---5.5V供电,14位内部数字寄存器;输出模拟信号可达rail_to_rail,在+5V供电的情况下,其输出范围为-5V---+5V。AD5641管脚及功能说明见下表。

表1 AD5641管脚及功能说明

信号名字

信号功能

SYNC

帧同步信号(低电平有效),当SYNC变为低电平时,使能了内部的移位寄存器,在接下来的串行时钟的下降沿,将输入锁存入内部的移位寄存器。

SCLK

串行时钟输入管脚,在其下降沿,将串行数据锁存入内部移位寄存器,时钟最高30Mhz。

DIN

串行输入管脚。芯片内有16位移位寄存器,在串行时钟的下降沿将该管脚上的信号锁存进内部移位寄存器。

Vout

模拟信号输出,其为rail_to_rail方式。

VDD

电源信号,供电范围为2.7V~3.6V。

GND

地信号。

 

AD5641的写时序图参见图1,具体时序参数见表2。

 

da_1.jpg
图1
表2
da_2.jpg
状态转移图见图2
da_3.jpg
图2
程序代码如下:

module spi_da(

        clk,

        rst,

        data_par,

        spi_syn,

        spi_clk,

        spi_simo);

input clk;//16Mhz系统时钟;

input rst;//低电平有效的复位信号;

input [15:0] data_par;//待发送的16位并行数据;

 

output reg spi_syn;

//SPI接口的同步信号,低电平有效;

output reg spi_clk;

//SPI接口的串行时钟,下降沿将数据写入DA的内部移位寄存器;

output reg spi_simo;

//SPI接口的串行输入数据;

 

reg [3:0] p_count;//上电后一直自加的计数器;

reg [3:0] wait_count;//等待状态的计数器;

reg [6:0] conv_count;//转换状态的计数器;

reg [15:0] data_reg;//锁存的16位寄存器;

 

parameter IDLE =3'b001;

parameter CONV =3'b010;

parameter WAIT  =3'b100;

 

reg [2:0] cstate;

reg [2:0] nstate;

 

always @ (posedge clk or negedge rst)

    if(rst==0)

        p_count<=4'b0;

    else

        p_count<=p_count+1;

//上电后一直自加的计数器;

         

always @ (posedge clk or negedge rst)

    if(rst==0)

        wait_count<=4'b0;

    else if(cstate==WAIT || nstate==WAIT)

        wait_count<=wait_count+1;

    else

        wait_count<=4'b0;

//等待状态的计数器;

           

always @ (posedge clk or negedge rst)

    if(rst==0)

        conv_count<=7'b0;

    else if(cstate==CONV || nstate==CONV)

        conv_count<=conv_count+1;

    else

        conv_count<=7'b0;

//转换状态的计数器;

 

always @ (posedge clk or negedge rst)

    if(rst==1'b0)

        cstate<=IDLE;

    else

        cstate<=nstate;

//当前状态等于下一状态

       

always @ (cstate,p_count,conv_count,wait_count)

    begin

        nstate=IDLE;

        case(cstate)

            IDLE:

                begin

                    if(p_count==4'hE)

                        nstate=WAIT;

                    else

                        nstate=IDLE;

                end

            WAIT:

                begin

                    if(wait_count==4'hE)

                        nstate=CONV;

                    else

                        nstate=WAIT;

                end

            CONV:

                begin

                    if(conv_count==7'd32)

                        nstate=WAIT;

                    else

                        nstate=CONV;

                end        

            default:

                begin

                end

        endcase

    end

//产生下一状态

   

always @ (posedge clk or negedge rst)

    begin

        if(rst==1'b0)

            begin

                spi_syn<=1'b1;

                spi_simo<=1'b0;

                data_reg<=16'b0;

                spi_clk<=1'b1;

            end

        else

            begin

                case(nstate)

                    IDLE:

                        begin

                            spi_syn<=1'b1;

                            spi_simo<=1'b0;

                            data_reg<=16'b0;

                            spi_clk<=1'b1;

                        end

                    WAIT:

                        begin

                            spi_syn<=1'b1;

                            spi_simo<=1'b0;

                            spi_clk<=1'b1;

                            if(wait_count==4'h6)

                                begin

                                    data_reg<=data_par;

                                end

                            else

                                begin

                                    data_reg<=data_reg;

                                end

                        end

                    CONV:

                        begin

                            spi_syn<=1'b0;

                            spi_simo<=data_reg[15];

                            if(conv_count==7'd0)

                                begin

                                    spi_clk<=1'b1;

                                end

                            else

                                begin

                                    spi_clk<=!spi_clk;

                                end

                            if(conv_count[0]==1'b1)

                                begin

                                    data_reg<={data_reg[14:0],1'b0};

                                end

                            else

                                begin

                                    data_reg<=data_reg;

                                end

                        end                

                    default:

                        begin

                            spi_syn<=1'b1;

                            spi_simo<=1'b0;

                            data_reg<=data_reg;

                            spi_clk<=1'b1;

                        end

                endcase

                   

            end

    end

//输出SPI接口的3个信号:同步信号、串行时钟、串行数据。

 

endmodule

 

 

DA模块的仿真波形图见图3,波形图中发送的数据为55AA。

 

da_4.jpg
图3

文章评论6条评论)

登录后参与讨论

hot.summer_2010_438634915 2014-9-22 21:07

在考虑11月份左右出一套开发板。

用户1779611 2014-9-22 11:43

支持博主出一套开发板。

hot.summer_2010_438634915 2014-9-10 06:26

现在还没有,如果网友需要相应配套的开发板,我可以一套。看大家反映吧

用户1779611 2014-9-9 20:55

请问你有相关的开发板出售么?

hot.summer_2010_438634915 2014-9-9 13:06

我博客中所以的程序都是在电路板上调试通过,长期运行没问题的。

用户1779611 2014-9-8 06:26

请问你的这个程序上板调试了么?
相关推荐阅读
快乐的践行者 2018-02-23 17:22
回来了
一晃好几年没来这儿了。心麻木了,干什么都没动力。...
快乐的践行者 2015-05-14 10:56
【博客大赛】《FPGA项目开发实战讲解》目录
《FPGA项目开发实战讲解》目录 第1章 FPGA介绍 1.1 FPGA的优势  1.2 FPGA典型结构图  1.3 LUT原理  1.4 FPGA上电配置过程时序图  1....
快乐的践行者 2015-05-07 06:17
【博客大赛】ACTEL的FPGA使用心得
和XILINX和ALTERA相比,ACTEL的使用人群就少多了。 ACTEL的缺点是运行速度不如xilinx的快,开发环境不如ISE灵活方便,文档也没有xilinx的丰富。 优点是其大部分...
我要评论
6
6
关闭 站长推荐上一条 /2 下一条