Q01 - การใช้งาน TPIC6B595 – POWER LOGIC 8
Step 1 : โมดูลสร้าง 2000Hz จาก 50MHz
`timescale 1ns / 1ps
module Clk_2000Hz (
input Clk_In,
output Clk_Out );
reg Clk_Out = 1'b0;
reg [27:0] Counter;
always@(posedge Clk_In) begin
Counter <= Counter + 1;
if ( Counter == 12_500) begin
Counter <= 0;
Clk_Out <= ~Clk_Out;
end
end
endmodule
Step 2 : โมดูลสร้าง 1Hz จาก 50MHz
`timescale 1ns / 1ps
module Clk_1Hz(
input Clk_In,
output Clk_Out
);
reg Clk_Out = 1'b0;
reg [27:0] Counter;
always@(posedge Clk_In) begin
Counter <= Counter + 1;
if ( Counter == 25_000_000) begin
Counter <= 0;
Clk_Out <= ~Clk_Out;
end
end
endmodule
Step 3 : Pin Input-Output File
NET "Clk_50MHz" LOC = P56 | IOSTANDARD = LVTTL;
NET "xCount<0>" LOC = P134 | IOSTANDARD = LVTTL;
NET "xCount<1>" LOC = P133 | IOSTANDARD = LVTTL;
NET "xCount<2>" LOC = P132 | IOSTANDARD = LVTTL;
NET "xCount<3>" LOC = P131 | IOSTANDARD = LVTTL;
NET "xCount<4>" LOC = P127 | IOSTANDARD = LVTTL;
NET "xCount<5>" LOC = P126 | IOSTANDARD = LVTTL;
NET "xCount<6>" LOC = P124 | IOSTANDARD = LVTTL;
NET "xCount<7>" LOC = P123 | IOSTANDARD = LVTTL;
NET "zData" LOC = P51 | IOSTANDARD = LVTTL ;
NET "zClock" LOC = P41 | IOSTANDARD = LVTTL ;
NET "zLatch" LOC = P35 | IOSTANDARD = LVTTL ;
Step 4 : Driver_595 Verilog Module
`timescale 1ns / 1ps
module Drive_74595(Clock, Data_In, Shift, Latch, Data_Out);
//----------------------------CONTROL SIGNALS-----------------------------------
input Clock;
input [7:0] Data_In; // 8-bit input data
output Shift; // Register CLK, pushes the FIFO data to the driver outputs
output Latch; // Positive Edge Triggered Shift Register CLK
output Data_Out; // The serial data output
reg [7:0] Clk_Count;
reg R_Shift, R_Latch, R_DataO;
//=====================================================
always @ ( posedge Clock )
begin
Clk_Count <= Clk_Count + 1;
if( Clk_Count > 20 ) begin
Clk_Count <= 0;
end
//----------------------------------------------
if(Clk_Count == 0) begin
R_Shift <= 0;
R_Latch <= 0;
R_DataO <= Data_In[0];
end
if(Clk_Count == 1) begin
R_Shift <= 1;
R_Latch <= 0;
R_DataO <= Data_In[0];
end
//----------------------------------------------
if(Clk_Count == 2) begin
R_Shift <= 0;
R_Latch <= 0;
R_DataO <= Data_In[1];
end
if(Clk_Count == 3) begin
R_Shift <= 1;
R_Latch <= 0;
R_DataO <= Data_In[1];
end
//----------------------------------------------
if(Clk_Count == 4) begin
R_Shift <= 0;
R_Latch <= 0;
R_DataO <= Data_In[2];
end
if(Clk_Count == 5) begin
R_Shift <= 1;
R_Latch <= 0;
R_DataO <= Data_In[2];
end
//----------------------------------------------
if(Clk_Count == 6) begin
R_Shift <= 0;
R_Latch <= 0;
R_DataO <= Data_In[3];
end
if(Clk_Count == 7) begin
R_Shift <= 1;
R_Latch <= 0;
R_DataO <= Data_In[3];
end
//----------------------------------------------
if(Clk_Count == 8) begin
R_Shift <= 0;
R_Latch <= 0;
R_DataO <= Data_In[4];
end
if(Clk_Count == 9) begin
R_Shift <= 1;
R_Latch <= 0;
R_DataO <= Data_In[4];
end
//----------------------------------------------
if(Clk_Count == 10) begin
R_Shift <= 0;
R_Latch <= 0;
R_DataO <= Data_In[5];
end
if(Clk_Count == 11) begin
R_Shift <= 1;
R_Latch <= 0;
R_DataO <= Data_In[5];
end
//----------------------------------------------
if(Clk_Count == 12) begin
R_Shift <= 0;
R_Latch <= 0;
R_DataO <= Data_In[6];
end
if(Clk_Count == 13) begin
R_Shift <= 1;
R_Latch <= 0;
R_DataO <= Data_In[6];
end
//----------------------------------------------
if(Clk_Count == 14) begin
R_Shift <= 0;
R_Latch <= 0;
R_DataO <= Data_In[7];
end
if(Clk_Count == 15) begin
R_Shift <= 1;
R_Latch <= 0;
R_DataO <= Data_In[7];
end
//----------------------------------------------
if(Clk_Count == 16) begin
R_Shift <= 0;
R_Latch <= 0;
R_DataO <= 0;
end
if(Clk_Count == 17) begin
R_Shift <= 0;
R_Latch <= 1;
R_DataO <= 0;
end
//----------------------------------------------
end
assign Shift = R_Shift;
assign Latch = R_Latch;
assign Data_Out = R_DataO;
endmodule
Step 5 : ต่อวงจรตามรูป
Step 6 : อัพลงบอร์ด MOJO
ผลลัพท์จะได้ไฟวิ่ง นับขึ้น 8 บิต
Q2 - การใช้งาน TPIC6B595 – POWER LOGIC 8
Step 1 : โมดูลสร้าง 2000Hz จาก 50MHz
`timescale 1ns / 1ps
module Clk_2000Hz (
input Clk_In,
output Clk_Out );
reg Clk_Out = 1'b0;
reg [27:0] Counter;
always@(posedge Clk_In) begin
Counter <= Counter + 1;
if ( Counter == 12_500) begin
Counter <= 0;
Clk_Out <= ~Clk_Out;
end
end
endmodule
Step 2 : โมดูลสร้าง 1Hz จาก 50MHz
`timescale 1ns / 1ps
module Clk_1Hz(
input Clk_In,
output Clk_Out
);
reg Clk_Out = 1'b0;
reg [27:0] Counter;
always@(posedge Clk_In) begin
Counter <= Counter + 1;
if ( Counter == 25_000_000) begin
Counter <= 0;
Clk_Out <= ~Clk_Out;
end
end
endmodule
Step 3 : Pin Input-Output File
Step 2 : Code verilog (add16to32)
NET "Clk_50MHz" LOC = P56 | IOSTANDARD = LVTTL;
NET "xCount<0>" LOC = P134 | IOSTANDARD = LVTTL;
NET "xCount<1>" LOC = P133 | IOSTANDARD = LVTTL;
NET "xCount<2>" LOC = P132 | IOSTANDARD = LVTTL;
NET "xCount<3>" LOC = P131 | IOSTANDARD = LVTTL;
NET "xCount<4>" LOC = P127 | IOSTANDARD = LVTTL;
NET "xCount<5>" LOC = P126 | IOSTANDARD = LVTTL;
NET "xCount<6>" LOC = P124 | IOSTANDARD = LVTTL;
NET "xCount<7>" LOC = P123 | IOSTANDARD = LVTTL;
NET "zData" LOC = P51 | IOSTANDARD = LVTTL ;
NET "zClock" LOC = P41 | IOSTANDARD = LVTTL ;
NET "zLatch" LOC = P35 | IOSTANDARD = LVTTL ;
Step 4 : Driver_595 Verilog Module
`timescale 1ns / 1ps
module Drive_74595(Clock, DPH_In, DPL_In, Shift, Latch, Data_Out);
//----------------------------CONTROL SIGNALS-----------------------------------
input Clock;
input [7:0] DPH_In; // 8-bit input data H-Byte
input [7:0] DPL_In; // 8-bit input data L-Byte
output Shift; // Shift -> Register CLK in FIFO Buffer
output Latch; // Latch --> Shift Register CLK
output Data_Out; // The serial data output
parameter nBit = 16; // Using (2*nBit+4) Input_Clock
reg [7:0] Clk_Count; // Maximum 256 Input_Clock
reg R_Shift, R_Latch, R_DataO;
reg [nBit-1:0] Data_In;
//=======================================================
always @* begin
Data_In = { DPH_In, DPL_In };
end
//=======================================================
always @ ( posedge Clock ) begin
Clk_Count <= Clk_Count + 1;
if( Clk_Count > (2*nBit + 4)) begin
Clk_Count <= 0;
end
//--- Shift Process ----------------------------------------
if((Clk_Count < 2*nBit) && ((Clk_Count%2) == 0)) begin
R_Shift <= 0;
R_Latch <= 0;
R_DataO <= Data_In[Clk_Count/2];
end
if((Clk_Count < 2*nBit) && ((Clk_Count%2) == 1)) begin
R_Shift <= 1;
R_Latch <= 0;
R_DataO <= Data_In[Clk_Count/2];
end
//--- Latch Process ----------------------------------------
if(Clk_Count == (2*nBit)) begin
R_Shift <= 0;
R_Latch <= 0;
R_DataO <= 0;
end
if(Clk_Count == (2*nBit+1)) begin
R_Shift <= 0;
R_Latch <= 1;
R_DataO <= 0;
end
//------------------------------------------------------
end
assign Shift = R_Shift;
assign Latch = R_Latch;
assign Data_Out = R_DataO;
endmodule
Step 5 : ต่อวงจรตามรูป
Step 6 : อัพลงบอร์ด MOJO
Step 7 : ต่อวงจรตามรูป
ผลลัพท์จะได้ไฟวิ่ง นับขึ้น 16 บิต
Q4 - การใช้งาน 74165 - PARALLEL LOAD SHIFT REGIST
Step 1 : code verilog (Read16bit_shiftter)
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 15:44:19 06/10/2019
// Design Name:
// Module Name: Read16bit_shiftter
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module Read16bit_shiftter(Ser_I, Clk_I, Clk_O, SH_LD, Parl_O);
input Clk_I, Ser_I;
output Clk_O, SH_LD;
output [15:0] Parl_O;
reg [7:0] Clk_Count; // Maximum 256 Input_Clockreg [7:0] tmp;
parameter nBit = 16; // Using (nBit+4) Input_Clock
reg [nBit-1:0] R_Parl_O, temp_Parl_O;
reg R_ShiftLoad;
always @(posedge Clk_I) begin
Clk_Count <= Clk_Count + 1;
if( Clk_Count > (nBit+4)) begin // Over Reset Counter
Clk_Count <= 0;
R_ShiftLoad <= 0;
end
if(Clk_Count==0) R_ShiftLoad <= 0; // Load
if(Clk_Count==1) R_ShiftLoad <= 1; // no Load
if((Clk_Count>=2)&&(Clk_Count<=(nBit+1))) begin // Shift
temp_Parl_O <= temp_Parl_O << 1;
temp_Parl_O[0] <= Ser_I;
end
if(Clk_Count==(nBit+2)) R_Parl_O <= temp_Parl_O; // Save
end
assign Parl_O = R_Parl_O;
assign Clk_O = Clk_I;
assign SH_LD = R_ShiftLoad;
endmodule
Step 2 : code verilog (Gen2000Hz)
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 13:59:37 06/10/2019
// Design Name:
// Module Name: Gen2000Hz
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module Gen2000Hz(
input Clk_In,
output Clk_Out
);
reg Clk_Out = 1'b0;
reg [27:0] Counter;
always@(posedge Clk_In) begin
Counter <= Counter + 1;
if ( Counter == 12_500) begin
Counter <= 0;
Clk_Out <= ~Clk_Out;
end
end
endmodule
Step 3 : port pin
NET "Clk_50MHz" LOC = P56 | IOSTANDARD = LVTTL;
NET "xCount<4>" LOC = P134 | IOSTANDARD = LVTTL;
NET "xCount<5>" LOC = P133 | IOSTANDARD = LVTTL;
NET "xCount<6>" LOC = P132 | IOSTANDARD = LVTTL;
NET "xCount<7>" LOC = P131 | IOSTANDARD = LVTTL;
NET "xCount<8>" LOC = P127 | IOSTANDARD = LVTTL;
NET "xCount<9>" LOC = P126 | IOSTANDARD = LVTTL;
NET "xCount<10>" LOC = P124 | IOSTANDARD = LVTTL;
NET "xCount<11>" LOC = P123 | IOSTANDARD = LVTTL;
NET "Data_Input" LOC = P51 | IOSTANDARD = LVTTL ;
NET "Clk_Out" LOC = P41 | IOSTANDARD = LVTTL ;
NET "Shift_Load" LOC = P35 | IOSTANDARD = LVTTL ;
Step 4 : ต่อวงจร Schematic ตามรูป
Step 5 : ผลลัพท์จะได้ สามารถควบคุมไฟได้ 16 Bit
Q5 - FPGA READ FROM 74165 AND SEND TO TPIC6B595
Step 1 : โมดูลสร้างความถี่
// Test Data
`timescale 1ns / 1ps
module test_Data(input Clk_50MHz, rstCount, output [31:0] oData);
reg [31:0] cCounter;
reg [31:0] roData;
always@(posedge Clk_50MHz or negedge rstCount) begin
if(rstCount==0)
roData <= 0;
else begin
cCounter <= cCounter + 1'b1;
if ( cCounter == 1_250_000) begin
cCounter <= 0;
roData <= roData + 1'b1;
end
end
end
assign oData = roData;
endmodule
Step 2 : โมดูลสร้าง drv_MAX7219
-- ###########################################################
-- Driver for MAX7219 with 8 digit 7-segment display
-- http://stevenmerrifield.com/max7219/M7219.vhdl
-- sjm 15 May 2017
-- ###########################################################
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity drv_MAX7219 is
port (
clk : in std_logic;
parallel : in std_logic_vector(31 downto 0);
clk_out : out std_logic;
data_out : out std_logic;
load : out std_logic
);
end drv_MAX7219;
-- ###########################################################
architecture Behavioral of drv_MAX7219 is
attribute syn_encoding : string;
type state_machine is (init_1, init_2, init_3, init_4, read_data, dig_7, dig_6, dig_5,
dig_4, dig_3, dig_2, dig_1, dig_0);
attribute syn_encoding of state_machine : type is "safe";
signal state : state_machine := init_1;
type driver_machine is (idle, start, clk_data, clk_high, clk_low, finished);
attribute syn_encoding of driver_machine : type is "safe";
signal driver_state : driver_machine := idle;
signal command : std_logic_vector(15 downto 0) := x"0000";
signal driver_start : std_logic := '0';
-- -----------------------------------------------------------
function hex2seg(num : std_logic_vector(3 downto 0)) return std_logic_vector is
begin
case num is
when "0000" => return("01111110"); -- 0
when "0001" => return("00110000"); -- 1
when "0010" => return("01101101"); -- 2
when "0011" => return("01111001"); -- 3
when "0100" => return("00110011"); -- 4
when "0101" => return("01011011"); -- 5
when "0110" => return("01011111"); -- 6
when "0111" => return("01110000"); -- 7
when "1000" => return("01111111"); -- 8
when "1001" => return("01111011"); -- 9
when "1010" => return("01110111"); -- A
when "1011" => return("00011111"); -- b
when "1100" => return("00001101"); -- c
when "1101" => return("00111101"); -- d
when "1110" => return("01001111"); -- E
when "1111" => return("01000111"); -- F
when others => return("00000000");
end case;
end hex2seg;
-- -----------------------------------------------------------
-- ###########################################################
begin -- of Behavioral
process
variable counter : integer := 0;
variable clk_counter : integer := 0;
variable latch_in : std_logic_vector(31 downto 0) := x"00000000";
variable dig0_data : std_logic_vector(7 downto 0) := x"00";
variable dig1_data : std_logic_vector(7 downto 0) := x"00";
variable dig2_data : std_logic_vector(7 downto 0) := x"00";
variable dig3_data : std_logic_vector(7 downto 0) := x"00";
variable dig4_data : std_logic_vector(7 downto 0) := x"00";
variable dig5_data : std_logic_vector(7 downto 0) := x"00";
variable dig6_data : std_logic_vector(7 downto 0) := x"00";
variable dig7_data : std_logic_vector(7 downto 0) := x"00";
-- ===========================================================
begin -- of process
-- -----------------------------------------------------------
wait until rising_edge(clk);
-- -----------------------------------------------------------
case state is
when init_1 =>
if (driver_state = idle) then
command <= x"0c01"; -- shutdown / normal operation
driver_state <= start;
state <= init_2;
end if;
when init_2 =>
if (driver_state = idle) then
command <= x"0900"; -- decode mode
driver_state <= start;
state <= init_3;
end if;
when init_3 =>
if (driver_state = idle) then
command <= x"0A04"; -- intensity
driver_state <= start;
state <= init_4;
end if;
when init_4 =>
if (driver_state = idle) then
command <= x"0B07"; -- scan limit
driver_state <= start;
state <= read_data;
end if;
when read_data =>
latch_in := parallel;
dig7_data := hex2seg(latch_in(31 downto 28));
dig6_data := hex2seg(latch_in(27 downto 24));
dig5_data := hex2seg(latch_in(23 downto 20));
dig4_data := hex2seg(latch_in(19 downto 16));
dig3_data := hex2seg(latch_in(15 downto 12));
dig2_data := hex2seg(latch_in(11 downto 8));
dig1_data := hex2seg(latch_in(7 downto 4));
dig0_data := hex2seg(latch_in(3 downto 0));
state <= dig_7;
when dig_7 =>
if (driver_state = idle) then
command <= x"08" & dig7_data;
driver_state <= start;
state <= dig_6;
end if;
when dig_6 =>
if (driver_state = idle) then
command <= x"07" & dig6_data;
driver_state <= start;
state <= dig_5;
end if;
when dig_5 =>
if (driver_state = idle) then
command <= x"06" & dig5_data;
driver_state <= start;
state <= dig_4;
end if;
when dig_4 =>
if (driver_state = idle) then
command <= x"05" & dig4_data;
driver_state <= start;
state <= dig_3;
end if;
when dig_3 =>
if (driver_state = idle) then
command <= x"04" & dig3_data;
driver_state <= start;
state <= dig_2;
end if;
when dig_2 =>
if (driver_state = idle) then
command <= x"03" & dig2_data;
driver_state <= start;
state <= dig_1;
end if;
when dig_1 =>
if (driver_state = idle) then
command <= x"02" & dig1_data;
driver_state <= start;
state <= dig_0;
end if;
when dig_0 =>
if (driver_state = idle) then
command <= x"01" & dig0_data;
driver_state <= start;
state <= read_data;
end if;
when others => null;
end case;
-- -----------------------------------------------------------
if (clk_counter < 100) then
clk_counter := clk_counter + 1;
else
clk_counter := 0;
case driver_state is
when idle =>
load <= '1';
clk_out <= '0';
when start =>
load <= '0';
counter := 16;
driver_state <= clk_data;
when clk_data =>
counter := counter - 1;
data_out <= command(counter);
driver_state <= clk_high;
when clk_high =>
clk_out <= '1';
driver_state <= clk_low;
when clk_low =>
clk_out <= '0';
if (counter = 0) then
load <= '1';
driver_state <= finished;
else
driver_state <= clk_data;
end if;
when finished =>
driver_state <= idle;
when others => null;
end case;
end if; -- clk_counter
-- -----------------------------------------------------------
end process;
-- ===========================================================
end Behavioral;
-- ###########################################################
Step 3 : Pin Input-Output File
NET "Clk_50MHz" LOC = P56 | IOSTANDARD = LVTTL ;
NET "Onboard_Reset" LOC = P38 | IOSTANDARD = LVTTL ;
// NET "xMonitor<4>" LOC = P134 | IOSTANDARD = LVTTL;
// NET "xMonitor<5>" LOC = P133 | IOSTANDARD = LVTTL;
// NET "xMonitor<6>" LOC = P132 | IOSTANDARD = LVTTL;
// NET "xMonitor<7>" LOC = P131 | IOSTANDARD = LVTTL;
// NET "xMonitor<8>" LOC = P127 | IOSTANDARD = LVTTL;
// NET "xMonitor<9>" LOC = P126 | IOSTANDARD = LVTTL;
// NET "xMonitor<10>" LOC = P124 | IOSTANDARD = LVTTL;
// NET "xMonitor<11>" LOC = P123 | IOSTANDARD = LVTTL;
NET "DIN" LOC = P51 ;
NET "CLK" LOC = P41 ;
NET "CS" LOC = P35 ;
Step 5 : ผลลัพท์ จะได้นับเลขไปเรื่อยๆ
Q6 - ทดสอบการทำงานของเซ็นเซอร์ DS18B20 SENSOR
Step 1 : Code verilog (Ds1820)
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 17:29:56 06/10/2019
// Design Name:
// Module Name: Ds1820
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module Ds1820(
input clk,
input rst_n,
inout one_wire,
output [15:0] temperature );
reg [5:0] cnt;
always @ (posedge clk, negedge rst_n)
if (!rst_n)
cnt <= 0;
else
if (cnt == 49)
cnt <= 0;
else
cnt <= cnt + 1'b1;
reg clk_1us;
always @ (posedge clk, negedge rst_n)
if (!rst_n)
clk_1us <= 0;
else
if (cnt <= 24)
clk_1us <= 0;
else
clk_1us <= 1;
reg [19:0] cnt_1us;
reg cnt_1us_clear;
always @ (posedge clk_1us)
if (cnt_1us_clear)
cnt_1us <= 0;
else
cnt_1us <= cnt_1us + 1'b1;
parameter S00 = 5'h00;
parameter S0 = 5'h01;
parameter S1 = 5'h03;
parameter S2 = 5'h02;
parameter S3 = 5'h06;
parameter S4 = 5'h07;
parameter S5 = 5'h05;
parameter S6 = 5'h04;
parameter S7 = 5'h0C;
parameter WRITE0 = 5'h0D;
parameter WRITE1 = 5'h0F;
parameter WRITE00 = 5'h0E;
parameter WRITE01 = 5'h0A;
parameter READ0 = 5'h0B;
parameter READ1 = 5'h09;
parameter READ2 = 5'h08;
parameter READ3 = 5'h18;
reg [4:0] state;
reg one_wire_buf;
reg [15:0] temperature_buf;
reg [5:0] step;
reg [3:0] bit_valid;
always @(posedge clk_1us, negedge rst_n)
begin
if (!rst_n)
begin
one_wire_buf <= 1'bZ;
step <= 0;
state <= S00;
end
else
begin
case (state)
S00 : begin
temperature_buf <= 16'h001F;
state <= S0;
end
S0 : begin
cnt_1us_clear <= 1;
one_wire_buf <= 0;
state <= S1;
end
S1 : begin
cnt_1us_clear <= 0;
if (cnt_1us == 500)
begin
cnt_1us_clear <= 1;
one_wire_buf <= 1'bZ;
state <= S2;
end
end
S2 : begin
cnt_1us_clear <= 0;
if (cnt_1us == 100)
begin
cnt_1us_clear <= 1;
state <= S3;
end
end
S3 : if (~one_wire)
state <= S4;
else if (one_wire)
state <= S0;
S4 : begin
cnt_1us_clear <= 0;
if (cnt_1us == 400)
begin
cnt_1us_clear <= 1;
state <= S5;
end
end
S5 : begin
if (step == 0)
begin
step <= step + 1'b1;
state <= WRITE0;
end
else if (step == 1)
begin
step <= step + 1'b1;
state <= WRITE0;
end
else if (step == 2)
begin
one_wire_buf <= 0;
step <= step + 1'b1;
state <= WRITE01;
end
else if (step == 3)
begin
one_wire_buf <= 0;
step <= step + 1'b1;
state <= WRITE01;
end
else if (step == 4)
begin
step <= step + 1'b1;
state <= WRITE0;
end
else if (step == 5)
begin
step <= step + 1'b1;
state <= WRITE0;
end
else if (step == 6)
begin
one_wire_buf <= 0;
step <= step + 1'b1;
state <= WRITE01;
end
else if (step == 7)
begin
one_wire_buf <= 0;
step <= step + 1'b1;
state <= WRITE01;
end
else if (step == 8)
begin
step <= step + 1'b1;
state <= WRITE0;
end
else if (step == 9)
begin
step <= step + 1'b1;
state <= WRITE0;
end
else if (step == 10)
begin
one_wire_buf <= 0;
step <= step + 1'b1;
state <= WRITE01;
end
else if (step == 11)
begin
step <= step + 1'b1;
state <= WRITE0;
end
else if (step == 12)
begin
step <= step + 1'b1;
state <= WRITE0;
end
else if (step == 13)
begin
step <= step + 1'b1;
state <= WRITE0;
end
else if (step == 14)
begin
one_wire_buf <= 0;
step <= step + 1'b1;
state <= WRITE01;
end
else if (step == 15)
begin
step <= step + 1'b1;
state <= WRITE0;
end
else if (step == 16)
begin
one_wire_buf <= 1'bZ;
step <= step + 1'b1;
state <= S6;
end
else if (step == 17)
begin
step <= step + 1'b1;
state <= WRITE0;
end
else if (step == 18)
begin
step <= step + 1'b1;
state <= WRITE0;
end
else if (step == 19)
begin
one_wire_buf <= 0;
step <= step + 1'b1;
state <= WRITE01;
end
else if (step == 20)
begin
step <= step + 1'b1;
state <= WRITE01;
one_wire_buf <= 0;
end
else if (step == 21)
begin
step <= step + 1'b1;
state <= WRITE0;
end
else if (step == 22)
begin
step <= step + 1'b1;
state <= WRITE0;
end
else if (step == 23)
begin
one_wire_buf <= 0;
step <= step + 1'b1;
state <= WRITE01;
end
else if (step == 24)
begin
one_wire_buf <= 0;
step <= step + 1'b1;
state <= WRITE01;
end
else if (step == 25)
begin
step <= step + 1'b1;
state <= WRITE0;
end
else if (step == 26)
begin
one_wire_buf <= 0;
step <= step + 1'b1;
state <= WRITE01;
end
else if (step == 27)
begin
one_wire_buf <= 0;
step <= step + 1'b1;
state <= WRITE01;
end
else if (step == 28)
begin
one_wire_buf <= 0;
step <= step + 1'b1;
state <= WRITE01;
end
else if (step == 29)
begin
one_wire_buf <= 0;
step <= step + 1'b1;
state <= WRITE01;
end
else if (step == 30)
begin
one_wire_buf <= 0;
step <= step + 1'b1;
state <= WRITE01;
end
else if (step == 31)
begin
step <= step + 1'b1;
state <= WRITE0;
end
else if (step == 32)
begin
one_wire_buf <= 0;
step <= step + 1'b1;
state <= WRITE01;
end
else if (step == 33)
begin
step <= step + 1'b1;
state <= S7;
end
end
S6 : begin
cnt_1us_clear <= 0;
if (cnt_1us == 750000 | one_wire)
begin
cnt_1us_clear <= 1;
state <= S0;
end
end
S7 : begin
if (step == 34)
begin
bit_valid <= 0;
one_wire_buf <= 0;
step <= step + 1'b1;
state <= READ0;
end
else if (step == 35)
begin
bit_valid <= bit_valid + 1'b1;
one_wire_buf <= 0;
step <= step + 1'b1;
state <= READ0;
end
else if (step == 36)
begin
bit_valid <= bit_valid + 1'b1;
one_wire_buf <= 0;
step <= step + 1'b1;
state <= READ0;
end
else if (step == 37)
begin
bit_valid <= bit_valid + 1'b1;
one_wire_buf <= 0;
step <= step + 1'b1;
state <= READ0;
end
else if (step == 38)
begin
bit_valid <= bit_valid + 1'b1;
one_wire_buf <= 0;
step <= step + 1'b1;
state <= READ0;
end
else if (step == 39)
begin
bit_valid <= bit_valid + 1'b1;
one_wire_buf <= 0;
step <= step + 1'b1;
state <= READ0;
end
else if (step == 40)
begin
bit_valid <= bit_valid + 1'b1;
one_wire_buf <= 0;
step <= step + 1'b1;
state <= READ0;
end
else if (step == 41)
begin
bit_valid <= bit_valid + 1'b1;
one_wire_buf <= 0;
step <= step + 1'b1;
state <= READ0;
end
else if (step == 42)
begin
bit_valid <= bit_valid + 1'b1;
one_wire_buf <= 0;
step <= step + 1'b1;
state <= READ0;
end
else if (step == 43)
begin
bit_valid <= bit_valid + 1'b1;
one_wire_buf <= 0;
step <= step + 1'b1;
state <= READ0;
end
else if (step == 44)
begin
bit_valid <= bit_valid + 1'b1;
one_wire_buf <= 0;
step <= step + 1'b1;
state <= READ0;
end
else if (step == 45)
begin
bit_valid <= bit_valid + 1'b1;
one_wire_buf <= 0;
step <= step + 1'b1;
state <= READ0;
end
else if (step == 46)
begin
bit_valid <= bit_valid + 1'b1;
one_wire_buf <= 0;
step <= step + 1'b1;
state <= READ0;
end
else if (step == 47)
begin
bit_valid <= bit_valid + 1'b1;
one_wire_buf <= 0;
step <= step + 1'b1;
state <= READ0;
end
else if (step == 48)
begin
bit_valid <= bit_valid + 1'b1;
one_wire_buf <= 0;
step <= step + 1'b1;
state <= READ0;
end
else if (step == 49)
begin
bit_valid <= bit_valid + 1'b1;
one_wire_buf <= 0;
step <= step + 1'b1;
state <= READ0;
end
else if (step == 50)
begin
step <= 0;
state <= S0;
end
end
WRITE0 :
begin
cnt_1us_clear <= 0;
one_wire_buf <= 0;
if (cnt_1us == 80)
begin
cnt_1us_clear <= 1;
one_wire_buf <= 1'bZ;
state <= WRITE00;
end
end
WRITE00 :
state <= S5;
WRITE01 :
state <= WRITE1;
WRITE1 :
begin
cnt_1us_clear <= 0;
one_wire_buf <= 1'bZ;
if (cnt_1us == 80)
begin
cnt_1us_clear <= 1;
state <= S5;
end
end
READ0 : state <= READ1;
READ1 :
begin
cnt_1us_clear <= 0;
one_wire_buf <= 1'bZ;
if (cnt_1us == 10)
begin
cnt_1us_clear <= 1;
state <= READ2;
end
end
READ2 :
begin
temperature_buf[bit_valid] <= one_wire;
state <= READ3;
end
READ3 :
begin
cnt_1us_clear <= 0;
if (cnt_1us == 55)
begin
cnt_1us_clear <= 1;
state <= S7;
end
end
default : state <= S00;
endcase
end
end
assign one_wire = one_wire_buf;
wire [15:0] t_buf = temperature_buf & 16'h07FF;
assign temperature[3:0] = (t_buf[3:0] * 10) >> 4;
assign temperature[7:4] = (((t_buf[7:4] * 10) >> 4) >= 4'd10) ? (((t_buf[7:4] * 10) >> 4) - 'd10) : ((t_buf[7:4] * 10) >> 4);
assign temperature[11:8] = (((t_buf[7:4] * 10) >> 4) >= 4'd10) ? (((t_buf[11:8] * 10) >> 4) + 'd1) + 'd2 : ((t_buf[11:8] * 10)>> 4) + 'd2;
assign temperature[15:12] = temperature_buf[12] ? 1 : 0;
endmodule
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 16:40:53 06/10/2019
// Design Name:
// Module Name: add16to32
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module add16to32
(input[15:0] inData, output [31:0] oData);
assign oData[31:16] = 0;
assign oData[15:0] = inData;
endmodule
Step 3 : Code VHDL (drv_MAX7219)
--
-- Driver for MAX7219 with 8 digit 7-segment display
-- http://stevenmerrifield.com/max7219/M7219.vhdl
-- sjm 15 May 2017
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity drv_MAX7219 is
port (
clk : in std_logic;
parallel : in std_logic_vector(31 downto 0);
clk_out : out std_logic;
data_out : out std_logic;
load : out std_logic
);
end drv_MAX7219;
--
architecture Behavioral of drv_MAX7219 is
attribute syn_encoding : string;
type state_machine is (init_1, init_2, init_3, init_4, read_data, dig_7, dig_6, dig_5,
dig_4, dig_3, dig_2, dig_1, dig_0);
attribute syn_encoding of state_machine : type is "safe";
signal state : state_machine := init_1;
type driver_machine is (idle, start, clk_data, clk_high, clk_low, finished);
attribute syn_encoding of driver_machine : type is "safe";
signal driver_state : driver_machine := idle;
signal command : std_logic_vector(15 downto 0) := x"0000";
signal driver_start : std_logic := '0';
-- -----------------------------------------------------------
function hex2seg(num : std_logic_vector(3 downto 0)) return std_logic_vector is
begin
case num is
when "0000" => return("01111110"); -- 0
when "0001" => return("00110000"); -- 1
when "0010" => return("01101101"); -- 2
when "0011" => return("01111001"); -- 3
when "0100" => return("00110011"); -- 4
when "0101" => return("01011011"); -- 5
when "0110" => return("01011111"); -- 6
when "0111" => return("01110000"); -- 7
when "1000" => return("01111111"); -- 8
when "1001" => return("01111011"); -- 9
when "1010" => return("01110111"); -- A
when "1011" => return("00011111"); -- b
when "1100" => return("00001101"); -- c
when "1101" => return("00111101"); -- d
when "1110" => return("01001111"); -- E
when "1111" => return("01000111"); -- F
when others => return("00000000");
end case;
end hex2seg;
-- -----------------------------------------------------------
--
begin -- of Behavioral
process
variable counter : integer := 0;
variable clk_counter : integer := 0;
variable latch_in : std_logic_vector(31 downto 0) := x"00000000";
variable dig0_data : std_logic_vector(7 downto 0) := x"00";
variable dig1_data : std_logic_vector(7 downto 0) := x"00";
variable dig2_data : std_logic_vector(7 downto 0) := x"00";
variable dig3_data : std_logic_vector(7 downto 0) := x"00";
variable dig4_data : std_logic_vector(7 downto 0) := x"00";
variable dig5_data : std_logic_vector(7 downto 0) := x"00";
variable dig6_data : std_logic_vector(7 downto 0) := x"00";
variable dig7_data : std_logic_vector(7 downto 0) := x"00";
--
begin -- of process
-- -----------------------------------------------------------
wait until rising_edge(clk);
-- -----------------------------------------------------------
case state is
when init_1 =>
if (driver_state = idle) then
command <= x"0c01"; -- shutdown / normal operation
driver_state <= start;
state <= init_2;
end if;
when init_2 =>
if (driver_state = idle) then
command <= x"0900"; -- decode mode
driver_state <= start;
state <= init_3;
end if;
when init_3 =>
if (driver_state = idle) then
command <= x"0A04"; -- intensity
driver_state <= start;
state <= init_4;
end if;
when init_4 =>
if (driver_state = idle) then
command <= x"0B07"; -- scan limit
driver_state <= start;
state <= read_data;
end if;
when read_data =>
latch_in := parallel;
dig7_data := hex2seg(latch_in(31 downto 28)) and ("00000000");
dig6_data := hex2seg(latch_in(27 downto 24))and ("00000000");
dig5_data := hex2seg(latch_in(23 downto 20))and ("00000000");
dig4_data := hex2seg(latch_in(19 downto 16))and ("00000000");
dig3_data := hex2seg(latch_in(15 downto 12));
dig2_data := hex2seg(latch_in(11 downto 8));
dig1_data := hex2seg(latch_in(7 downto 4))or ("10000000");
dig0_data := hex2seg(latch_in(3 downto 0)) ;
state <= dig_7;
when dig_7 =>
if (driver_state = idle) then
command <= x"08" & dig7_data;
driver_state <= start;
state <= dig_6;
end if;
when dig_6 =>
if (driver_state = idle) then
command <= x"07" & dig6_data;
driver_state <= start;
state <= dig_5;
end if;
when dig_5 =>
if (driver_state = idle) then
command <= x"06" & dig5_data;
driver_state <= start;
state <= dig_4;
end if;
when dig_4 =>
if (driver_state = idle) then
command <= x"05" & dig4_data;
driver_state <= start;
state <= dig_3;
end if;
when dig_3 =>
if (driver_state = idle) then
command <= x"04" & dig3_data;
driver_state <= start;
state <= dig_2;
end if;
when dig_2 =>
if (driver_state = idle) then
command <= x"03" & dig2_data;
driver_state <= start;
state <= dig_1;
end if;
when dig_1 =>
if (driver_state = idle) then
command <= x"02" & dig1_data;
driver_state <= start;
state <= dig_0;
end if;
when dig_0 =>
if (driver_state = idle) then
command <= x"01" & dig0_data;
driver_state <= start;
state <= read_data;
end if;
when others => null;
end case;
if (clk_counter < 100) then
clk_counter := clk_counter + 1;
else
clk_counter := 0;
case driver_state is
when idle =>
load <= '1';
clk_out <= '0';
when start =>
load <= '0';
counter := 16;
driver_state <= clk_data;
when clk_data =>
counter := counter - 1;
data_out <= command(counter);
driver_state <= clk_high;
when clk_high =>
clk_out <= '1';
driver_state <= clk_low;
when clk_low =>
clk_out <= '0';
if (counter = 0) then
load <= '1';
driver_state <= finished;
else
driver_state <= clk_data;
end if;
when finished =>
driver_state <= idle;
when others => null;
end case;
end if; -- clk_counter
end process;
end Behavioral;
Step 4 : Code port pin
NET "CLOCK_50" LOC = P56 | IOSTANDARD = LVTTL ;
NET "Q_KEY" LOC = P38 | IOSTANDARD = LVTTL ;
NET "DS18B20" LOC = P24 ; // ต่อเข้ากับสายสีเหลือง
NET "DS18B20" PULLUP;
NET "DIN" LOC = P50 ;
NET "CLK" LOC = P34 ;
NET "CS" LOC = P40 ;
NET "xCount<4>" LOC = P134 | IOSTANDARD = LVTTL;
NET "xCount<5>" LOC = P133 | IOSTANDARD = LVTTL;
NET "xCount<6>" LOC = P132 | IOSTANDARD = LVTTL;
NET "xCount<7>" LOC = P131 | IOSTANDARD = LVTTL;
NET "xCount<8>" LOC = P127 | IOSTANDARD = LVTTL;
NET "xCount<9>" LOC = P126 | IOSTANDARD = LVTTL;
NET "xCount<10>" LOC = P124 | IOSTANDARD = LVTTL;
NET "xCount<11>" LOC = P123 | IOSTANDARD = LVTTL;
Step 5 : ต่อวงจร Schematic ตามรูป
Step 6 : ผลลัพท์จะได้ ค่าอุณหภูมิขณะนั้น