完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
本帖最后由 小雨也倾盆 于 2015-4-7 16:45 编辑
module ad_ctr( clk,rst_n,adc_in1,adc_in2, scl,sda,sys_rddata, ); input clk; // 50MHz input rst_n; //复位信号,低有效 output scl; inout sda; output[7:0] sys_rddata; //总线读取数据 input adc_in1; input adc_in2; //-------------------------------------------- //--------------------------------------------- //分频部分 reg[2:0] cnt; // cnt=0:scl上升沿,cnt=1:scl高电平中间,cnt=2:scl下降沿,cnt=3:scl低电平中间 reg[8:0] cnt_delay; //500循环计数,产生iic所需要的时钟 reg scl_r; //时钟脉冲寄存器 always @ (posedge clk or negedge rst_n) if(!rst_n) cnt_delay <= 9'd0; else if(cnt_delay == 9'd499) cnt_delay <= 9'd0; //计数到10us为scl的周期,即100KHz else cnt_delay <= cnt_delay+1'b1; //时钟计数 always @ (posedge clk or negedge rst_n) begin if(!rst_n) cnt <= 3'd5; else begin case (cnt_delay) 9'd124: cnt <= 3'd1; //cnt=1:scl高电平中间,用于数据采样 9'd249: cnt <= 3'd2; //cnt=2:scl下降沿 9'd374: cnt <= 3'd3; //cnt=3:scl低电平中间,用于数据变化 9'd499: cnt <= 3'd0; //cnt=0:scl上升沿 default: cnt <= 3'd5; endcase end end `define SCL_POS (cnt==3'd0) //cnt=0:scl上升沿 `define SCL_HIG (cnt==3'd1) //cnt=1:scl高电平中间,用于数据采样 `define SCL_NEG (cnt==3'd2) //cnt=2:scl下降沿 `define SCL_LOW (cnt==3'd3) //cnt=3:scl低电平中间,用于数据变化 always @ (posedge clk or negedge rst_n) if(!rst_n) scl_r <= 1'b0; else if(cnt==3'd0) scl_r <= 1'b1; //scl信号上升沿 else if(cnt==3'd2) scl_r <= 1'b0; //scl信号下降沿 assign scl = scl_r; //产生iic所需要的时钟 //--------------------------------------------- //需要写入24C02的地址和数据 `define ADDRESS1 8'b1001_0000 //被寻址器件地址(写操作) `define CONTROLBYTE 8'b0100_0101 //控制字 `define ADDRESS2 8'b1001_0001 //被寻址器件地址(读操作) reg[7:0] adc_din; reg[4:0] cstate; reg[4:0] nstate; reg[2:0] bitnum; //采样数据位寄存器7-0 //数据锁存 always @(posedge clk or negedge rst_n) if(!rst_n) adc_din <= 8'h00; else if (nstate == DATA1) sys_rddata[bitnum] <= adc_in1; //数据锁存 always @(posedge clk or negedge rst_n) if(!rst_n) adc_din <= 8'h00; else if(nstate == DATA2) sys_rddata[bitnum] <= adc_in2; //数据锁存 reg[7:0] db_r; reg[7:0] adc_data; //模数转换数据寄存器 reg[7:0] CONTROLBYTE; //reg[7:0] DATA11; //reg[7:0] DATA22; //--------------------------------------------- //读、写时序 parameter IDLE = 4'd0; parameter START1 = 4'd1; parameter ADD1 = 4'd2; parameter ACK1 = 4'd3; parameter CONTROL= 4'd4; parameter ACK2 = 4'd5; parameter STOP1 = 4'd6; parameter START2 = 4'd7; parameter ADD2 = 4'd8; parameter ACK3 = 4'd9; parameter DATA1 = 4'd10; parameter ACK4 = 4'd11; parameter DATA2 = 4'd12; parameter ACK5 = 4'd13; parameter STOP2 = 4'd14; reg sda_r; //输出数据寄存器 reg sda_link; //输出数据sda信号inout方向控制位 //reg[3:0] num; // always @(posedge clk or negedge rst_n) if(!rst_n) cstate <= IDLE; else cstate <= nstate; //IIC状态转换控制 always @(cstate or `SCL_HIG or `SCL_LOW or bcnt) begin case(cstate) IDLE: if(!rst_n) nstate <= IDLE; else nstate <= START1; START1: if(`SCL_HIG) nstate <= ADD1; else nstate <= START; ADD1: if(`SCL_LOW && bcnt == 3'd0) nstate <= ACK1; else nstate <= ADDR; ACK1: if(`SCL_LOW) nstate <= CONTROL; else nstate <= ACK1; CONTROL: if(`SCL_LOW && bcnt == 3'd0) nstate <= ACK2; else nstate <= CONTROL; ACK2: if(`SCL_LOW) nstate <= STOP1; else nstate <= ACK2; STOP1: if(`SCL_HIG) nstate <= START2; else nstate <= STOP1; START2: if(`SCL_LOW) nstate <= ADD2; else nstate <= START2; ADD2: if(`SCL_LOW) nstate <= ACK3; else nstate <= ADD2; ACK3: if(`SCL_LOW) nstate <= ADTA1; else nstate <= ACK3; DATA1: if (`SCL_LOW && bcnt == 3'd0) nstate <= ACK4; else nstate <= DATA1; ACK4: if(`SCL_LOW) nstate <=DATA2; else natate <= ACK4; DATA2: if(`SCL_LOW && bcnt == 3'd0) nstate <= ACK5; else nstate <= DATA2; ACK5: if(`SCL_LOW) nstate <= STOP2; else nstate <= ACK5; STOP2: if(`SCL_HIG) nstate <= IDLE; else nstate <= STOP2; default: nstate <= IDLE; endcase end always @ (posedge clk or negedge rst_n) if(!rst_n) begin sdar = 1'b1; sdlink = 1'b1; end else begin case (cstate) IDLE: begin sda_link <= 1'b1; //数据线sda为output sda_r <= 1'b1; end START1: if(`SCL_HIG) begin //scl为高电平期间 sda_link <= 1'b1; //数据线sda为output sda_r <= 1'b0; //拉低数据线sda,产生起始位信号 end ADD1: //自我感觉这里不对,应该是 if(`SCL_LOW) begin sda_r <= ADD1[bcut]; sda_link <= 1'b1; //数据线sda为output end ACK1: begin if(`SCL_LOW) begin sda_r <= 1'b0; sda_link <= 1'b0; //数据线sda为input end CONTROL: if(`SCL_LOW) begin sdar <= CONTROLBYTE[bcnt]; //依次发送地址bit7-0 sdlink <= 1'b1; //sda输出 end ACK2: if(`SCL_LOW) begin sda_r <= 1'b0; sda_link <= 1'b0; //数据线sda为input end STOP1: if(`SCL_HIG) begin sda_link <= 1'b1; sda_r <= 1'b1; end START2: if(`SCL_HIG) begin //scl为高电平期间 sda_link <= 1'b1; //数据线sda为output sda_r <= 1'b0; //拉低数据线sda,产生起始位信号 end ADD2: if(`SCL_LOW) begin sda_r <= ADD2[bcut]; sda_link <= 1'b1; //数据线sda为output end ACK3: if(`SCL_LOW) begin sda_r <= 1'b0; sda_link <= 1'b0; //数据线sda为input end DATA1: if(scl_low) begin sdar <= sys_rddata[bcnt]; // sdlink <= 1'b0; //sda输入 end ACK4: if(scl_low) begin sdar <= 1'b0; sdlink <= 1'b0; //sda输入input end DATA2: if(scl_low) begin sdar <= sys_rddata[bcnt]; //送LSB/invalid字节 sdlink <= 1'b0; //sda输入 end ACK5: if(scl_low) begin sdar <= 1'b0; sdlink <= 1'b0; //sda输入 end STOP2: if(`SCL_HIG) begin sdar <= 1'b1; sdlink <= 1'b1; //sda输出 end default: ; endcase end always @(posedge clk or negedge rst_n) if(!rst_n) bcnt <= 3'd0; else begin case(cstate) ADD1,ADD2,CONTROL,DATA1,DATA2: begin if(scl_low) bcnt <= bcnt-1'b1; //bit7-0 else ; end default: bcnt <= 3'd7; endcase end assign sda = sdlink ? sdar : 1'bz ; //SDA输入输出控制逻辑 1为输出 0为输入 endmodule
|
|
相关推荐
4个回答
|
|
10170应该就是相应的那语句句有问题
|
|
|
|
|
|
|
|
一时半会读懂你的程序也挺难的,那应该是那语句或者语句之前的几句,因为在编译时,机器是读完相应的语句之后才知道这个语句有没有错误,所以报错是,找报错的语句或者之前的几句 |
|
|
|
Error (10112): Ignored design unit "ad_ctr" at ad_ctr.v(1) due to previous errors 显示的是之前的有错误 Error (10170): Verilog HDL syntax error at ad_ctr.v(220) near text "default"; expecting "end" 大神 看看这句应该怎么改吧 前边的状态转换我在从新写一下 |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
浏览过的版块 |
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-10-12 17:05 , Processed in 0.591578 second(s), Total 50, Slave 41 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号