共6条
1/1 1 跳转至页
交一下LM75作业
/****************************************************************************** *Engineer: superdian *Create Date: 2014/9/7 *Design Name: *Module Name: LM75A *Project Name: *Target Devices: EP3CE5E144C8 *Tool versions: *Description: * *Dependencies: * *Revision: *Revision 0.01 - File Created *Additional Comments: 开发板晶振为20MHZ,部分参数会与大家的开发板(50MHZ)不同。 ******************************************************************************/ module LM75A(sys_clk,sys_rstn,scl,sda,cs,seg); input sys_clk,sys_rstn;//复位信号低电平有效,时钟50mhz output scl;//I2C时钟,250KHZ,时钟周期4US inout sda; //i2c数据端口 output [3:0] cs;//数码管片选 output [7:0] seg;//数码管段选 wire done;//i2c读取完一个数据完毕,更新数码管段选寄存器 wire [15:0] data ;//温度数据 I2C_READ I2C_READ(.sys_clk(sys_clk), .sys_rstn(sys_rstn), .scl(scl), .sda(sda), .data(data), ); SEG_D SEG_D(.sys_clk(sys_clk), .sys_rstn(sys_rstn), .cs(cs), .seg(seg), .data(data), ); endmodule
/****************************************************************************** *Engineer: superdian *Create Date: 2014/9/7 *Design Name: *Module Name: SMG_D *Project Name: *Target Devices: EP3CE5E144C8 *Tool versions: *Description: * *Dependencies: * *Revision: *Revision 0.01 - File Created *Additional Comments: 开发板晶振为20MHZ,部分参数会与大家的开发板(50MHZ)不同。 ******************************************************************************/ module SEG_D(sys_clk,sys_rstn,seg,data,cs); input sys_clk; input sys_rstn; input [15:0]data;//显示数据 output [7:0] seg; output [3:0] cs; reg [7:0] seg; reg [3:0] cs; reg [4:0] dataout_buf; reg [1:0] disp_dat; reg [15:0] delay_cnt; always@(posedge sys_clk,negedge sys_rstn) begin if(!sys_rstn) delay_cnt<=16'd0; else if(delay_cnt==16'd19999) delay_cnt<=16'd0; else delay_cnt<=delay_cnt +1; end always@(posedge sys_clk,negedge sys_rstn) begin if(!sys_rstn) disp_dat<=2'd0; else if(delay_cnt==16'd19999) disp_dat<=disp_dat+1'b1; else disp_dat<=disp_dat; end always@(disp_dat) begin case(disp_dat) 2'b00: cs=4'b1110; 2'b01: cs=4'b1101; 2'b10: cs=4'b1011; default cs=4'b1111; endcase end always@(cs) begin case(cs) 4'b1110:dataout_buf=data[8:5]; 4'b1101:dataout_buf=data[12:9]; 4'b1011:dataout_buf={1'b0,data[15:13]}; default dataout_buf=0; endcase end always@(dataout_buf) begin case(dataout_buf) 4'h0 : seg = 8'hc0; //0 4'h1 : seg = 8'hf9; //1 4'h2 : seg = 8'ha4; //2 4'h3 : seg = 8'hb0; //3 4'h4 : seg = 8'h99; //4 4'h5 : seg = 8'h92; //5 4'h6 : seg = 8'h82; //6 4'h7 : seg = 8'hf8; //7 4'h8 : seg = 8'h80; //8 4'h9 : seg = 8'h90; //9 4'ha : seg = 8'h88; //a 4'hb : seg = 8'h83; //b 4'hc : seg = 8'hc6; //c 4'hd : seg = 8'ha1; //d 4'he : seg = 8'h86; //e 4'hf : seg = 8'h8e; //f default : seg =8'hc0; //0 endcase end endmodule
/****************************************************************************** *Engineer: superdian *Create Date: 2014/9/7 *Design Name: *Module Name: I2C_READ *Project Name: *Target Devices: EP3CE5E144C8 *Tool versions: *Description: * *Dependencies: * *Revision: *Revision 0.01 - File Created *Additional Comments: 开发板晶振为20MHZ,部分参数会与大家的开发板(50MHZ)不同。 ******************************************************************************/ module I2C_READ(sys_clk,sys_rstn,scl,sda,data); input sys_clk; //20MHZ input sys_rstn; //复位信号,低有效 output scl;//LM75的时钟端口 inout sda;//LM75A的数据端口 output [15:0] data ;//数码管显示的数据 reg[15:0] read_data; //读出LM75A温度数据的寄存器 reg scl_r;//时钟脉冲寄存器 reg sda_r;//输出数据状态寄存器 reg sda_link;//输出数据sda信号inout方向控制位 reg [2:0] cnt ;//cnt =0:scl 上升沿,cnt=1:scl高电平中间,cnt=2:scl下降沿,cnt=3:scl 低电平中间 reg [7:0] cnt_delay; //200循环计数,产生IIC所需的时钟,250KHZ。 reg [25:0] til;//每隔1s读一次温度 reg [3:0] num;// reg [7:0] db_r; //在IIC上传送的数据寄存器 reg [3:0] state;//状态寄存器 always@(posedge sys_clk,negedge sys_rstn) begin if(!sys_rstn) cnt_delay <= 8'd0; else if (cnt_delay == 8'd79) cnt_delay <= 8'd0;//计数倒4US为scl的周期,即250KHZ else cnt_delay <= cnt_delay + 1'b1; // 时钟计数 end always @(posedge sys_clk,negedge sys_rstn) begin if(!sys_rstn) cnt <= 3'd5; else begin case (cnt_delay) 9'd19: cnt <= 3'd1;//cnt =1:scl 处于高电平中间,用于数据采样 9'd39: cnt <= 3'd2;//cnt =2:scl 下降沿 9'd59: cnt <= 3'd3;//cnt =3:scl 处于低电平中间,用于数据 变化 9'd79: 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 低电平中间,用于数据变化 //`define 是非下边的按键 always@(posedge sys_clk,negedge sys_rstn) if(!sys_rstn) 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所需的时钟 `define DEVICE_READ 8'b1001_0001 //读操作器件地址 parameter IDLE = 4'd0; parameter START1 = 4'd1; parameter ADD1 = 4'd2; parameter ACK1 = 4'd3; parameter DATA1 = 4'd4; parameter ACK2 = 4'd5; parameter DATA2 = 4'd6; parameter NACK = 4'd7; parameter STOP = 4'd8; //每隔1S读取一个数据 always@(posedge sys_clk,negedge sys_rstn) begin if(!sys_rstn) til <= 26'd0; else if(til == 26'd1999999) til <= 26'd0; else til<=til +1'b1; end //读写时序 always@(posedge sys_clk, negedge sys_rstn) begin if(!sys_rstn) begin state <= IDLE; sda_r <= 1'b1; sda_link <= 1'd0; num <= 4'd0; read_data<= 16'd0; end else case(state) IDLE:begin sda_link <= 1'b1;//数据线sda为output sda_r <= 1'b1; if(til[25]) //计时时间到读数据 begin db_r <= `DEVICE_READ; //送器件地址(读操作) state <= START1; end else state <= IDLE;//时间没到 end START1:begin if(`SCL_HIG)//scl为高电平期间 begin sda_link <= 1'b1;//数据线sda为输出 sda_r <= 1'b0;//拉低数据线sda,产生起始信号 state <= ADD1; num <= 4'd0;//num技术清零 end else state <= START1;//等待sclg高电平中间位置到来 end ADD1:begin if(`SCL_LOW) begin if(num == 4'd8) begin num <= 4'd0;//num 计数清零 sda_r <= 1'b1; sda_link <= 1'b0;//sda为高阻态输入 state<= ACK1; end end else begin state <= ADD1; num <= num + 1'b1; case(num) 4'd0: sda_r <= db_r[7]; 4'd1: sda_r <= db_r[6]; 4'd2: sda_r <= db_r[5]; 4'd3: sda_r <= db_r[4]; 4'd4: sda_r <= db_r[3]; 4'd5: sda_r <= db_r[2]; 4'd6: sda_r <= db_r[1]; 4'd7: sda_r <= db_r[0]; default : ; endcase//送器件地址从高位开始 end
end else state <=ADD1; end ACK1:begin if(!sda_r && `SCL_HIG) //lm75A产生应答信号 state <=DATA1;//读数据 else if(`SCL_NEG) //未产生应答信号,忽略 state<=DATA1;//读数据 else state <=ACK1;//等待从机响应 end DATA1:begin if(`SCL_HIG) begin num<=num+1'b1; case(num) 4'd0:read_data[15] <= sda; 4'd1:read_data[14] <= sda; 4'd2:read_data[13] <= sda; 4'd3:read_data[12] <= sda; 4'd4:read_data[11] <= sda; 4'd5:read_data[10] <= sda; 4'd6:read_data[9] <= sda; 4'd7:read_data[8] <=sda; default :; endcase //读高字节 end else if((`SCL_NEG)&&(num==4'd8)) begin num<=4'd0;//num计数器清零 sda_link<=1'b1;//sda数据线为OUTPUT sda_r<=1'b1;//sda拉高,以便产生低电平 state <= ACK2; end else state<= DATA1; end ACK2:begin if(`SCL_LOW) begin sda_r<=1'b0;//从机应答 end else if(`SCL_NEG) begin state<=DATA2; sda_link<=1'b0;//sda置为高阻态input sda_r<=1'b1; end else state <=ACK2; end DATA2:begin if(`SCL_HIG) begin num<=num+1'b1; case (num) 4'd0:read_data[7] <= sda; 4'd1:read_data[6] <= sda; 4'd2:read_data[5] <= sda; 4'd3:read_data[4] <= sda; 4'd4:read_data[3] <= sda; 4'd5:read_data[2] <= sda; 4'd6:read_data[1] <= sda; 4'd7:read_data[0] <= sda; default :; endcase //读字节 end else if((`SCL_LOW)&&(num==4'd8)) begin num<=4'd0;//NUM计数清零 sda_link<=1'b1;//数据线sda为output sda_r<=1'b1;//产生非应答信号 state<=NACK; end else state <= DATA2; end NACK: begin if(`SCL_LOW) begin sda_r<=1'b0;//主句非应答 state <=STOP; end else state<= NACK ; end STOP: begin if(`SCL_HIG) begin sda_r<=1'b1; state<= IDLE; end else state<=STOP; end default : state <=IDLE; endcase end assign sda = sda_link? sda_r : 1'bz ; assign data = read_data; endmodule
共6条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |