純記錄
module IOT_Bridge(
output [7:0] seg,
output [3:0] dig,
output reg [3:0] led,
input clock,
input [3:0] sw,
inout dht22_sda
);
// variables of clocks
wire ck1Mhz;
wire ck1KHz;
wire ck1Hz;
CLK_1MHZ clk_1MHz(clock, ck1Mhz);
CLK_1KHZ clk_1KHz(clock, ck1Khz);
CLK_1HZ clk_1Hz(clock, ck1Hz);
// variables of 7-seg LED
wire [3:0] D3;
wire [3:0] D2;
wire [3:0] D1;
wire [3:0] D0;
wire [15:0] number; // number to display
BIN2BCD bin2bcd(number, D3, D2, D1, D0);
Seg7 seg7(seg, dig, ck1Khz, D3, D2, D1, D0);
//DHT22 variables
reg dht22_reset;
reg dht22_get;
reg dht22_select; //1=humidity, 0=temperature
wire [39:0] dht22_data;
DHT22 dht22(ck1Mhz, dht22_reset, dht22_get, dht22_sda, dht22_data);
assign number[15:0] = dht22_select ? dht22_data[39:24]:dht22_data[23:8];
// clock
reg [9:0] clock_counter;
// initial
initial
begin
dht22_reset = 0;
dht22_get = 1;
dht22_select = 1;
clock_counter = 0;
led[3:0]= 4'b1111; //LED off
end
// select to show humidity or temperture
always @ (posedge sw[0])
begin
dht22_select = ~dht22_select;
end
always @ (posedge ck1Khz)
begin
if (dht22_reset==0)
begin
dht22_reset = 1;
dht22_get = 0; //start to read DHT22
end
led[3] = dht22_get;
clock_counter = clock_counter + 1'b1;
if(clock_counter==10'd1000)
begin
clock_counter = 0;
dht22_reset = 0;
end
if(clock_counter==10'd10)
begin
dht22_get = 1; //stop read DHT22
end
end
endmodule
|
/*
DHT22.v : read DHT22 data
source: https://github.com/evrinoma/AM2302
Modify: Ghosty Guo
Date: 2019/06/10
*/
module DHT22(
input wire clk,
input wire reset,
input wire get,
inout sda,
output reg [39:0] outdata
);
reg lastSda = 0;
reg wdata = 0;
reg rw = 1;
reg [39:0] data;
reg [9:0] address;
reg [3:0] state;
reg [9:0] count;
reg [3:0] trace;
reg [9:0] countTrace;
localparam STATE_IDLE = 0;
localparam STATE_START = 1;
localparam STATE_RELEASE = 2;
localparam STATE_RESPONSE_LOW = 3;
localparam STATE_RESPONSE_HIGH = 4;
localparam STATE_DATA_LOW = 5;
localparam STATE_DATA_HIGH = 6;
localparam STATE_STOP = 7;
localparam STATE_HALT = 8;
localparam DELAY_HALT = 2;
assign sda = (rw)? 1'bz : wdata;
initial
begin
outdata[39:0] = 40'd0;
end
always@(posedge clk)
begin
if (!reset)
begin
state <= STATE_IDLE;
rw <= 1;
count <= 10'd0;
address <= 10'd39;
data <= 40'd0;
lastSda <= 0;
end
else
begin
case (state)
STATE_IDLE : begin //0
if (!get)
state <= STATE_START;
else
state <= STATE_IDLE;
rw <= 1;
count <= 10'd0;
address <= 10'd39;
end
STATE_START : begin //1
if (count == 1000) //1ms
begin
state <= STATE_RELEASE;
count <= 10'd0;
end
else
begin
state <= STATE_START;
count <= count + 10'd1;
end
wdata <= 0;
rw <= 0;
end
STATE_RELEASE : begin //2
if (count == 30) //30us
begin
state <= STATE_RESPONSE_LOW;
count <= 10'd0;
rw <= 1;
end
else
begin
state <= STATE_RELEASE;
count <= count + 10'd1;
rw <= 0;
end
wdata <= 1;
end
STATE_RESPONSE_LOW : begin //3
if (trace != STATE_HALT )
begin
if (count == 40) //80us/2
begin
if (sda && !lastSda)
begin
state <= STATE_RESPONSE_HIGH;
count <= 10'd0;
end
else
begin
state <= STATE_RESPONSE_LOW;
end
end
else
begin
count <= count + 10'd1;
end
rw <= 1;
lastSda <= sda;
end
else
begin
state <= STATE_IDLE;
end
end
STATE_RESPONSE_HIGH : begin //4
if (trace != STATE_HALT )
begin
if (count == 40) //80us/2
begin
if (!sda && lastSda)
begin
state <= STATE_DATA_LOW;
count <= 10'd0;
end
else
begin
state <= STATE_RESPONSE_HIGH;
end
end
else
begin
count <= count + 10'd1;
end
rw <= 1;
lastSda <= sda;
end
else
begin
state <= STATE_IDLE;
end
end
STATE_DATA_LOW : begin //5
if (trace != STATE_HALT )
begin
if (sda)
begin
state <= STATE_DATA_HIGH;
end
else
begin
state <= STATE_DATA_LOW;
end
rw <= 1;
end
else
begin
state <= STATE_IDLE;
end
end
STATE_DATA_HIGH : begin //6
if (trace != STATE_HALT )
begin
if (sda)
begin
count <= count + 10'd1;
state <= STATE_DATA_HIGH;
end
else
begin
if (count < 30)
begin
data[address] = 1'b0;
end
else
begin
data[address] = 1'b1;
end
if (address)
begin
address = address - 10'd1;
state <= STATE_DATA_LOW;
count <= 10'd0;
end
else
begin
// get all 40 bits
address <= 10'd39;
state <= STATE_STOP;
outdata[39:0] <= data[39:0];
end
end
rw <= 1;
end
else
begin
state <= STATE_IDLE;
end
end
STATE_STOP : begin //7
if (trace != STATE_HALT )
begin
if (sda)
begin
state <= STATE_IDLE;
end
else
begin
state <= STATE_STOP;
end
rw <= 1;
end
else
begin
state <= STATE_IDLE;
end
end
endcase
end
end
always@(posedge clk)
begin
if (!reset)
begin
trace <= STATE_IDLE;
countTrace <= 10'd0;
end
else
begin
case (trace)
STATE_IDLE, STATE_START,STATE_RELEASE : begin //0, 1, 2
trace <= state;
countTrace <= 10'd0;
end
STATE_RESPONSE_LOW,STATE_RESPONSE_HIGH,STATE_DATA_LOW,STATE_DATA_HIGH,STATE_STOP : begin //3, 4, 5, 6, 7
if (state == trace)
if (countTrace > 85 ) //85us - max time for Responce period
begin
trace <= STATE_HALT;
countTrace <= 10'd0;
end
else
begin
countTrace <= countTrace + 10'd1;
end
else
begin
trace <= state;
countTrace <= 10'd0;
end
end
STATE_HALT : begin //8
if (countTrace == DELAY_HALT)
begin
trace <= STATE_IDLE;
countTrace <= 10'd0;
end
else
begin
countTrace <= countTrace + 10'd1;
end
end
endcase
end
end
endmodule
|
module CLK_1KHZ(
input clk_in,
output reg clk_out
);
reg [14:0] clk_count;
// initial
initial
begin
clk_count = 0;
clk_out = 0;
end
// clock counts
always @ (posedge clk_in)
begin
clk_count = clk_count + 1'b1;
if(clk_count==25000) //50Mhz
begin
clk_count = 0;
clk_out = ~clk_out;
end
end
endmodule
|
module CLK_1MHZ(
input clk_in,
output reg clk_out
);
reg [4:0] clk_count;
// initial
initial
begin
clk_count = 0;
clk_out = 0;
end
// clock counts
always @ (posedge clk_in)
begin
clk_count = clk_count + 1'b1;
if(clk_count==25) //50Mhz
begin
clk_count = 0;
clk_out = ~clk_out;
end
end
endmodule
|
module CLK_1MHZ(
input clk_in,
output reg clk_out
);
reg [4:0] clk_count;
// initial
initial
begin
clk_count = 0;
clk_out = 0;
end
// clock counts
always @ (posedge clk_in)
begin
clk_count = clk_count + 1'b1;
if(clk_count==25) //50Mhz
begin
clk_count = 0;
clk_out = ~clk_out;
end
end
endmodule
|
/*
Bin2BCD: Convert binary to 4 BCDs
ref: http://alex9ufoexploer.blogspot.com/2013/12/binary-to-bcd-conversion-algorithm.html
*/
module BIN2BCD(
input [15:0] binary,
output reg [3:0] BCD3,
output reg [3:0] BCD2,
output reg [3:0] BCD1,
output reg [3:0] BCD0
);
integer i;
always@(binary)
begin
BCD3 = 4'd0;
BCD2 = 4'd0;
BCD1 = 4'd0;
BCD0 = 4'd0;
for (i=14; i>=0; i=i-1)
begin
if (BCD3>=4'd5)
BCD3 = BCD3 + 4'd3;
if (BCD2>=4'd5)
BCD2 = BCD2 + 4'd3;
if (BCD1>=4'd5)
BCD1 = BCD1 + 4'd3;
if (BCD0>=4'd5)
BCD0 = BCD0 + 4'd3;
BCD3 = BCD3 << 1;
BCD3[0] = BCD2[3];
BCD2 = BCD2 << 1;
BCD2[0] = BCD1[3];
BCD1 = BCD1 << 1;
BCD1[0] = BCD0[3];
BCD0 = BCD0 << 1;
BCD0[0] = binary[i];
end
end
endmodule
|
沒有留言:
張貼留言