共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 跳转至页
回复
| 有奖活动 | |
|---|---|
| 硬核工程师专属补给计划——填盲盒 | |
| “我踩过的那些坑”主题活动——第002期 | |
| 【EEPW电子工程师创研计划】技术变现通道已开启~ | |
| 发原创文章 【每月瓜分千元赏金 凭实力攒钱买好礼~】 | |
| 【EEPW在线】E起听工程师的声音! | |
| 高校联络员开始招募啦!有惊喜!! | |
| 【工程师专属福利】每天30秒,积分轻松拿!EEPW宠粉打卡计划启动! | |
| 送您一块开发板,2025年“我要开发板活动”又开始了! | |
我要赚赏金
