ADS7830 FPGA实现

PCB设计的一般原则

Xilinx学习心得1-管脚约束

ADS7830 FPGA实现

2012-05-11 11:18:12|  分类: 工作笔记 |  标签: |字号大中小 订阅

ADS7830是TI的一款8bit,8channel AD转换芯片,对应通过I2c接口进行配置和读;以下是我用verilog编写的程序,已经验证过了,完全ok,输入的时钟是125MHz。经过分频成200Khz,采用的I2c接口时钟是100Khz模式;这里为了给上层模块应用,将inout类型的Sda在上层模块处理了;

module I2c_ADS7830 #(parameter DIV_PARA = 625)(  input clk,  input rst_n,  input AD_req,  input[2:0] AD_channel,    output reg dout_valid,  output reg [7:0] dout,   // output reg flag0,    output reg scl,  input sda_in,  output reg sda_out,  output reg en  ); localparam HARD_ADDR = 8‘b1001_0000;   localparam I2C_IDLE = 4‘d0,I2C_START = 4‘d1,I2C_HADDR = 4‘d2,I2C_HADDR_ACK = 4‘d3,     I2C_CMD = 4‘d4,I2C_CMD_ACK = 4‘d5,I2C_RESTART = 4‘d6,I2C_WRADDR = 4‘d7,     I2C_WRADDR_ACK = 4‘d8,I2C_RDATA = 4‘d9,I2C_NACK = 4‘d10,I2C_STOP = 4‘d11;

reg[3:0] current_state;  reg[2:0] AD_channel_buf; reg[7:0] databuf; reg[7:0] doutbuf;

reg i2c_clk; reg[9:0] div_cnt; reg[3:0] i2c_cnt;

reg start_AD; reg ack_AD; reg finish_AD; reg finish_AD_reg0,finish_AD_reg1;

//[email protected](posedge clk or negedge rst_n) //if(~rst_n) // flag0 <= 1‘b0; //else if(finish_AD) // flag0 <= 1‘b1;   //reg en; //reg sda_reg; // //assign sda  = en ? sda_reg : 1‘bz;

[email protected](posedge clk or negedge rst_n) if(~rst_n)  i2c_clk <= 1‘b0; else if(div_cnt==DIV_PARA-1)  i2c_clk <= ~i2c_clk;

[email protected](posedge clk or negedge rst_n) if(~rst_n)  div_cnt <= 10‘d0; else if(div_cnt==DIV_PARA-1)  div_cnt <= 10‘d0; else  div_cnt <= div_cnt + 10‘d1;

[email protected](posedge clk or negedge rst_n) if(~rst_n)  AD_channel_buf <= 3‘d0; else if(AD_req)  AD_channel_buf <= AD_channel;

[email protected](posedge clk or negedge rst_n) if(~rst_n)  start_AD <= 1‘b0; else if(AD_req)  start_AD <= 1‘b1; else if(ack_AD)  start_AD <= 1‘b0;

[email protected](posedge clk or negedge rst_n) if(~rst_n)  begin  finish_AD_reg0 <= 1‘b0;  finish_AD_reg1 <= 1‘b0;  end else  begin  finish_AD_reg0 <= finish_AD;  finish_AD_reg1 <= finish_AD_reg0;  end

[email protected](posedge clk or negedge rst_n) if(~rst_n)  dout_valid <= 1‘b0; else if(finish_AD_reg0 & !finish_AD_reg1)  dout_valid <= 1‘b1; else  dout_valid <= 1‘b0;

[email protected](posedge clk or negedge rst_n) if(~rst_n)  dout <= 8‘d0; else if(dout_valid)  dout <= doutbuf;

[email protected](posedge i2c_clk or negedge rst_n) if(~rst_n)  ack_AD <= 1‘b0; else if(start_AD)  ack_AD <= 1‘b1; else  ack_AD <= 1‘b0;   [email protected](posedge i2c_clk or negedge rst_n) if(~rst_n)  finish_AD <= 1‘b0; else if(current_state == I2C_STOP)  finish_AD <= 1‘b1; else  finish_AD <= 1‘b0;   [email protected](posedge i2c_clk or negedge rst_n) if(~rst_n)  i2c_cnt <= 4‘d0; else
 case(current_state)  I2C_HADDR,I2C_CMD,  I2C_WRADDR,I2C_RDATA:   begin   if(i2c_cnt==4‘d15)    i2c_cnt <= 4‘d0;   else    i2c_cnt <= i2c_cnt + 4‘d1;   end  I2C_START,I2C_HADDR_ACK,I2C_CMD_ACK,  I2C_WRADDR_ACK,I2C_NACK,I2C_STOP:   begin   if(i2c_cnt==4‘d1)    i2c_cnt <= 4‘d0;   else    i2c_cnt <= i2c_cnt + 4‘d1;   end  I2C_RESTART:   begin   if(i2c_cnt==4‘d2)    i2c_cnt <= 4‘d0;   else    i2c_cnt <= i2c_cnt + 4‘d1;   end  default:i2c_cnt <= 4‘d0;  endcase

[email protected](posedge i2c_clk or negedge rst_n) if(~rst_n)  current_state <= I2C_IDLE; else  case(current_state)  I2C_IDLE:   begin   if(start_AD)    current_state <= I2C_START;   end  I2C_START:   begin   if(i2c_cnt==4‘d1)    current_state <= I2C_HADDR;   end  I2C_HADDR:   begin   if(i2c_cnt==4‘d15)    current_state <= I2C_HADDR_ACK;   end  I2C_HADDR_ACK:   begin   if(scl && !sda_in)    current_state <= I2C_CMD;   else if(scl && sda_in)    current_state <= I2C_IDLE; //   if(scl) //      current_state <= I2C_CMD;   end  I2C_CMD:   begin   if(i2c_cnt==4‘d15)    current_state <= I2C_CMD_ACK;   end  I2C_CMD_ACK:   begin   if(scl && !sda_in)    current_state <= I2C_RESTART;   else if(scl && sda_in)    current_state <= I2C_IDLE; //   if(scl) //     current_state <= I2C_RESTART;   end  I2C_RESTART:   begin   if(i2c_cnt==4‘d2)    current_state <= I2C_WRADDR;   end  I2C_WRADDR:   begin   if(i2c_cnt==4‘d15)    current_state <= I2C_WRADDR_ACK;   end  I2C_WRADDR_ACK:   begin   if(scl && !sda_in)    current_state <= I2C_RDATA;   else if(scl && sda_in)    current_state <= I2C_IDLE; //   if(scl) //     current_state <= I2C_RDATA;   end  I2C_RDATA:   begin   if(i2c_cnt==4‘d15)    current_state <= I2C_NACK;   end  I2C_NACK:   begin   if(i2c_cnt==4‘d1)    current_state <= I2C_STOP;   end  I2C_STOP:   begin   if(i2c_cnt==4‘d1)    current_state <= I2C_IDLE;   end  default:current_state <= I2C_IDLE;  endcase     [email protected](posedge i2c_clk or negedge rst_n) if(~rst_n)  begin  scl <= 1‘b0;  en <= 1‘b0;  sda_out <= 1‘b0;  databuf <= 8‘d0;  doutbuf <= 8‘d0;  end else  case(current_state)  I2C_IDLE:   begin   scl <= 1‘b1;   sda_out <= 1‘b1;   en <= 1‘b1;   end  I2C_START:   begin   if(i2c_cnt==4‘d0)     begin     scl <= 1‘b1;     sda_out <= 1‘b0;     end   else     scl <= 1‘b0;   databuf <= HARD_ADDR;   end  I2C_HADDR:   begin   scl <= ~scl;   if(!scl)    begin    sda_out <= databuf[7];    databuf <= {databuf[6:0],1‘b0};    end   end  I2C_HADDR_ACK:   begin   en <= 1‘b0;   scl <= ~scl;   databuf <= {1‘b1,AD_channel_buf,4‘b0100};   end  I2C_CMD:   begin   en <= 1‘b1;   scl <= ~scl;   if(!scl)    begin    sda_out <= databuf[7];    databuf <= {databuf[6:0],1‘b0};    end   end  I2C_CMD_ACK:   begin   en <= 1‘b0;   scl <= ~scl;   databuf <= HARD_ADDR + 1‘b1;   end  I2C_RESTART:   begin   en <= 1‘b1;   if(i2c_cnt==4‘d0)    begin    scl <= 1‘b1;    sda_out <= 1‘b1;    end   else if(i2c_cnt==4‘d1)    begin    sda_out <= 1‘b0;    scl <= 1‘b1;    end   else    scl <= 1‘b0;   databuf <= HARD_ADDR + 1‘b1;   end  I2C_WRADDR:   begin   scl <= ~scl;   if(!scl)    begin    sda_out <= databuf[7];    databuf <= {databuf[6:0],1‘b0};    end   end  I2C_WRADDR_ACK:   begin   en <= 1‘b0;   scl <= ~scl;   end  I2C_RDATA:   begin   en <= 1‘b0;   scl <= ~scl;   if(!scl)    doutbuf <= {doutbuf[6:0],sda_in};   end  I2C_NACK:   begin   en <= 1‘b0;   scl <= ~scl;   end  I2C_STOP:   begin   en <= 1‘b1;   scl <= 1‘b1;   if(i2c_cnt==4‘d0)    sda_out <= 1‘b0;   else    sda_out <= 1‘b1;   end  default:;  endcase

endmodule

时间: 2024-10-13 16:15:26

ADS7830 FPGA实现的相关文章

实验箱FPGA部分测试报告及A8与FPGA链接测试报告

其实,我一开始还以为实验箱不会有什么问题只是让我们多学习东西才做这个测试的,结果发现还真的有不少问题. 1.实验准备部分 安装驱动时,win10系统无法正确安装usb-blaster Windows 8及以上的系统无法正常安装USB-Blaster驱动,在网上查找后发现了相关的解决办法 按部就班完成工作后,就可以安装USB-Blaster驱动了. 2.各实验情况 实验一:拨码开关程序设计 运行结果:失败. 在程序编译.管脚分配.接线连接都没错的情况下,无法显示结果.准确情况,无论拨哪一个开关,l

ASIC,DSP,MCU,ARM,FPGA 等网上牛人的一些理解

MPU是微机中的中央处理器(CPU)称为微处理器(MPU) MCU又称单片微型计算机(Single Chip Microcomputer)或者单片机,是指随着大规模集成电路的出现及其发展,将计算机的CPU.RAM.ROM.定时计数器和多种I/O接口集成在一片芯片上,形成芯片级的计算机,为不同的应用场合做不同组合控制. DSP是一种独特的CPU,是以数字信号来处理大量信息的器件.其实时运行速度可达每秒数以千万条复杂指令程序,远远超过通用微处理器(MPU),它的强大数据处理能力和高运行速度,是最值得

xilinx和altera的fpga的不同之处!----如果不知道,你将为之付出代价! --转载

本人从2004年接触fpga开始,至今已经8年了.开发过altera的flex系列和cyclone3系列:开发过xilinx的vii和v5系列.下面谈谈本人对二者的一些不同,以便引起开发者对一些细节上的注意,免得为之付出代价,再走弯路!(1)altera的任意一个管脚都可以连接到这样的sig信号上always @ (posedge(sig)) ……:但是xilinx的fpga不能,只有clk信号才能够分配这样的信号.本人最早使用a公司flex系列的fpga,当fpga和dsp的emif连接时,为

FPGA的FIR抽取滤波器设计

摘 要:本文介绍了FIR抽取滤波器的工作原理,重点阐述了用XC2V1000实现FIR抽取滤波器的方法,并给出了仿真波形和设计特点. 关键词:FIR抽取滤波器:流水线操作:FPGA 用FPGA实现抽取滤波器比较复杂,主要是因为在FPGA中缺乏实现乘法运算的有效结构,现在,FPGA中集成了硬件乘法器,使FPGA在数字信号处理方面有了长足的进步.本文介绍了一种采用Xilinx公司的XC2V1000实现FIR抽取滤波器的设计方法. 具体实现 结构设计 基于抽取滤波器的工作原理,本文采用XC2V1000实

FPGA编程技巧系列之输入输出偏移约束

1.   偏移约束的作用 偏移约束(Offset Constraint)用来定义一个外部时钟引脚(Pad)和数据输入输出引脚之间的时序关系,这种时序关系也被称为器件上的Pad-to-Setup或Clock-to-Out路径.这些约束对与外部元器件相连的接口十分重要,在这里,需要解释两个术语: Pad-to-Setup:也被称为OFFSET IN BEFORE约束,是用来保证外部输入时钟和外部输入数据的时序满足FPGA内部触发器的建立时间要求的.如下图TIN_BEFORE约束使得FPGA在进行DA

烦躁而无奈的一次调试-记fpga驱动ad9854

写这篇东西,主要还是要发泄心中之不爽,毕竟debug不出来很影响食欲和心情,也没心情陪妹纸了. 一个月前,师兄便开始带我fpga,先让我驱动个dds作为训练.由于暑假的原因,就停停放放的,在家先把VHDL简单过了一遍,又反复研究了一下AD9854的datasheet.什么寄存器啊,时序啊都了解的差不多了.一个星期前开始着手编. 但是菜鸟不会重头编啊,所以先拿了一个网上的驱动程序,根据板子的实际电路对程序作了修改.感觉不是很难吧,但示波器木有一丁点现象啊,芯片却在发热.然后我就开始一点一点的改啊,

梯形成形算法的FPGA实现

续上~~~梯形成形算法,上贴是原理仿真与软件实现,这一贴是硬件实现. 将系统函数分解为4个子模块: H(z)=H1(z)*H2(z)*H3(z)*H4(z) 式中: H1(z)=(1-qz-1)/(1-z-1); H2(z)=1-z-k; H3(z)=1-z-1; H4(z)=(1/ta)*(z-1)/(1-z-1) 4个子模块的级联存在顺序问题,要避免具有峰值增益的子系统发生溢出或将量化噪声扩大.所以把H1置于第一级; H4为积分单元,为了避免产生溢出,将其置于最后一级; H2.H3置于中间,

基于FPGA的跨时钟域信号处理——亚稳态(V3-FPGA学院)

(V3-FPGA学院教你学习FPGA) 基于FPGA的跨时钟域信号处理--亚稳态 基于FPGA的跨时钟域信号处理--亚稳态 什么是亚稳态? 所有数字器件(例如FPGA)的信号传输都会有一定的时序要求,从而保证每 个寄存器将捕获的输入信号正确输出.为了确保可靠的操作,输入寄存器的信号必须在时钟沿的某段时间(寄存器的建立时间Tsu)之前保持稳定,并且持续到时钟沿之后的某段时间(寄存器的保持时间Th)之后才能改变.而该寄存器的输入反映到输出则需要经过一定的延时(时钟到输出的时间Tco).如果数据信号的

v3学院带您一起学习FPGA

本文为原创,转载请注明! 课程名称:双buffer乒乓操作项目概况:使用FPGA内部ram作为缓冲器,实现对外部数据流的缓存:为了提升数据的传输及处理速度,在此节课中将用到两个ram进行乒乓操作.结构框图: 效果描述:本实验做到了使用低速模块处理高速数据流,可以将缓冲的数据在没有停顿的情况下送入到数据流处理模块进行处理.应用案例:在我们做FPGA开发时,为了能更好的处理一下数据流,会经常进行一些数据的缓存,在此节课中让学员能够建立一些数据缓存的概念:乒乓操作是一种经常使用的数据流处理技巧,可以在