Thiết kế đồng hồ thời gian thực dùng vi điều khiển PicoBlaze

Một phần của tài liệu Nghiên cứu tìm hiểu công nghệ FPGA trong thiết kế mạch điện tử (Trang 88 - 97)

Trong phần này em sử dụng tài nguyên trên Kit Spartan 3E để tạo ra một đồng hồ thời gian thực với nội dung:

- Giao tiếp với bộ LCD: Hiển thị thông số về đồng hồ: ngày, tháng, năm, giờ, phút, giây.

- Giao tiếp nút xoay: đọc nút bấm và xoay để điều chỉnh thời gian. Mã thiết kế nh− sau: --- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity picoblaze_real_time_clock is

Port ( led : out std_logic_vector(7 downto 0); strataflash_oe : out std_logic;

strataflash_ce : out std_logic; strataflash_we : out std_logic;

switch : in std_logic_vector(3 downto 0); btn_north : in std_logic;

btn_east : in std_logic; btn_south : in std_logic; btn_west : in std_logic;

lcd_d : inout std_logic_vector(7 downto 4); lcd_rs : out std_logic;

lcd_rw : out std_logic; lcd_e : out std_logic; rotary_a : in std_logic; rotary_b : in std_logic; rotary_press : in std_logic; clk : in std_logic); end picoblaze_real_time_clock; --- component kcpsm3

Port ( address : out std_logic_vector(9 downto 0); instruction : in std_logic_vector(17 downto 0);

port_id : out std_logic_vector(7 downto 0); write_strobe : out std_logic;

out_port : out std_logic_vector(7 downto 0); read_strobe : out std_logic;

in_port : in std_logic_vector(7 downto 0); interrupt : in std_logic;

interrupt_ack : out std_logic; reset : in std_logic; clk : in std_logic); end component;

-- declaration of program ROM-- component control

Port ( address : in std_logic_vector(9 downto 0); instruction : out std_logic_vector(17 downto 0); clk : in std_logic);

end component;

--- -- Signals used to connect KCPSM3 to program ROM and I/O logic-- signal address : std_logic_vector(9 downto 0);

signal instruction : std_logic_vector(17 downto 0); signal port_id : std_logic_vector(7 downto 0); signal out_port : std_logic_vector(7 downto 0); signal in_port : std_logic_vector(7 downto 0); signal write_strobe : std_logic;

signal read_strobe : std_logic; signal interrupt : std_logic :='0'; signal interrupt_ack : std_logic; signal kcpsm3_reset : std_logic; - Signals for LCD operation-- signal lcd_rw_control : std_logic;

signal lcd_output_data : std_logic_vector(7 downto 4); signal lcd_drive : std_logic;

-- Signals used to interface to rotary encoder-- signal rotary_a_in : std_logic;

signal rotary_b_in : std_logic; signal rotary_press_in : std_logic;

signal rotary_in : std_logic_vector(1 downto 0); signal rotary_q1 : std_logic;

signal rotary_q2 : std_logic; signal delay_rotary_q1 : std_logic;

signal rotary_event : std_logic; signal rotary_left : std_logic; signal ck1us:std_logic; signal ck50us:std_logic; signal ck2_5ms:std_logic; signal ck62_5ms:std_logic; signal ck1s:std_logic; signal ck_tmp:std_logic; signal ck_flag:std_logic; signal rotary_tmp:std_logic; signal rotary_flag:std_logic;

signal ck25m_cnt:std_logic_vector(1 downto 0); signal ck25m:std_logic;

signal cnt1us:std_logic_vector (5 downto 0); signal cnt50us:std_logic_vector (5 downto 0); signal cnt2_5ms:std_logic_vector (5 downto 0); signal cnt62_5ms:std_logic_vector (4 downto 0); signal cnt1s:std_logic_vector (8 downto 0);

signal port_id1 : std_logic_vector(7 downto 0);

--- -- Start of circuit description--

begin

strataflash_oe <= '1'; strataflash_ce <= '1'; strataflash_we <= '1';

-- KCPSM3 and the program memory -- processor: kcpsm3

port map( address => address, instruction => instruction, port_id => port_id, write_strobe => write_strobe, out_port => out_port, read_strobe => read_strobe, in_port => in_port, interrupt => interrupt, interrupt_ack => interrupt_ack, reset => kcpsm3_reset, clk => clk); program_rom: control

instruction => instruction,

-- proc_reset => kcpsm3_reset, --JTAG Loader version clk => clk);

kcpsm3_reset <= '0'; --When using normal program ROM ck_25m: process(clk)

begin

if clk'event and clk='1' then

ck25m_cnt<=ck25m_cnt+1; end if; end process ck_25m; rd: process(read_strobe) begin if read_strobe='1' then port_id1<=port_id; end if; end process rd; ck25m<=ck25m_cnt(1); ck_1us: process(clk) begin

if clk'event and clk='1' then

if cnt1us="110001" then cnt1us<="000000";--0--49

else

cnt1us<=cnt1us+1; end if;

if cnt1us<"011000" then ck1us<='0';---0--24/25--49

else

ck1us<='1'; end if; end if;

end process ck_1us; ck_50us: process(ck1us) begin

if ck1us'event and ck1us='1' then

if cnt50us="110001" then cnt50us<="000000";--0--49

else

cnt50us<=cnt50us+1; end if;

if cnt50us<"011000" then ck50us<='0';---0--24/25--49

ck50us<='1'; end if; end if;

end process ck_50us; ck_2_5ms: process(ck50us) begin

if ck50us'event and ck50us='1' then

if cnt2_5ms="110001" then cnt2_5ms<="000000";--0--49 else cnt2_5ms<=cnt2_5ms+1; end if; end if; end process ck_2_5ms; process(clk) begin

if clk 'event and clk='1' then

if cnt2_5ms<"011000" then ck2_5ms<='0';---0--24/25--49 else ck2_5ms<='1'; end if; end if; end process; ck_1s: process(ck2_5ms) begin

if ck2_5ms'event and ck2_5ms='1' then

if cnt1s="011000111" then cnt1s<="000000000";--0--24 else cnt1s<=cnt1s+1; end if; end if; end process ck_1s; process(clk) begin

if clk 'event and clk='1' then

if cnt1s<"001100011" then ck1s<='0';---0--24/25--49

else

ck1s<='1'; end if;

end if;

end process; -- Interrupt --

interrupt_control: process(ck1us) begin

if write_strobe='1' and port_id(5)='1' and (out_port(6)='1' or out_port(7)='1') then interrupt <= '0';

elsif ck1us'event and ck1us='1' then interrupt <= rotary_flag or ck_flag; end if;

end process interrupt_control; interrupt_source0:process(ck1us) begin

if ck1us'event and ck1us='1' then ck_tmp<=ck2_5ms; rotary_tmp<=rotary_q1; end if;

end process interrupt_source0; interrupt_flag0:process(ck1us) begin

if write_strobe='1' and port_id(5)='1' and out_port(7)='1' then ck_flag <='0';

elsif ck1us'event and ck1us='1' then

if ck_tmp='0' and ck2_5ms='1' then ck_flag <='1';

end if;

end if;

end process interrupt_flag0; interrupt_flag1:process(ck1us) begin

if write_strobe='1' and port_id(5)='1' and out_port(6)='1' then rotary_flag <= '0';

elsif ck1us'event and ck1us='1' then

if rotary_q1='1' and rotary_tmp='0' then

rotary_flag <='1';

end if; end if;

end process interrupt_flag1;

--- -- KCPSM3 input ports --

input_ports: process(clk) begin

if clk'event and clk='1' then case port_id(1 downto 0) is

-- read simple toggle switches and buttons at address 00 hex

when "00" => in_port <= btn_west & btn_north & btn_south & btn_east & switch;

-- when "00" => in_port <= cnt1s(3 downto 0)& cnt1s(0) & cnt1s(1)& cnt1s(2)& cnt1s(3);

-- read rotary control signals at address 01 hex

when "01" => in_port <= ck_flag & rotary_flag & "XXXX" & rotary_press_in & rotary_left;

-- read LCD data at address 02 hex

when "10" => in_port <= lcd_d & "XXXX";

-- Don't care used for all other addresses to ensure minimum logic implementation

when others => in_port <= "XXXXXXXX"; end case;

end if;

end process input_ports; -- KCPSM3 output ports -- output_ports: process(clk) begin

if clk'event and clk='1' then if write_strobe='1' then

-- Write to LEDs at address 80 hex. if port_id(7)='1' then

led <= out_port; end if;

-- LCD data output and controls at address 40 hex. if port_id(6)='1' then

lcd_output_data <= out_port(7 downto 4); lcd_drive <= out_port(3); lcd_rs <= out_port(2); lcd_rw_control <= out_port(1); lcd_e <= out_port(0); end if; end if; end if;

end process output_ports; rotary_filter: process(clk) begin

if clk'event and clk='1' then rotary_a_in <= rotary_a; rotary_b_in <= rotary_b;

rotary_press_in <= rotary_press;

rotary_in <= rotary_b_in & rotary_a_in; case rotary_in is

when "00" => rotary_q1 <= '0'; rotary_q2 <= rotary_q2;

when "01" => rotary_q1 <= rotary_q1; rotary_q2 <= '0';

when "10" => rotary_q1 <= rotary_q1; rotary_q2 <= '1';

when "11" => rotary_q1 <= '1'; rotary_q2 <= rotary_q2;

when others => rotary_q1 <= rotary_q1; rotary_q2 <= rotary_q2;

end case; end if;

end process rotary_filter; direction: process(clk) begin

if clk'event and clk='1' then delay_rotary_q1 <= rotary_q1;

if rotary_q1='1' and delay_rotary_q1='0' then rotary_event <= '1'; rotary_left <= rotary_q2; else rotary_event <= '0'; rotary_left <= rotary_left; end if; end if;

end process direction; end Behavioral;

Kết luận

Sau thời gian nghiên cứu và tìm hiểu về các linh kiện logic lập trình đ−ợc mà cụ thể là FPGA của hãng Xilinx, em đã thu đ−ợc một số kết quả sau:

- Nắm đ−ợc ph−ơng pháp thiết kế mới cho các linh kiện logic lập trình đ−ợc. - Có kỹ năng sử dụng ngôn ngữ mô tả phần cứng HDL mà cụ thể là VHDL .

- Tìm hiểu đ−ợc cấu trúc, nguyên lý hoạt động của Kit Xilinx Spartan 3E và sử dụng cho việc thiết kế một số ứng dụng cơ bản.

- Thiết kế thành công một số mạch ứng dụng đơn giản và đồng hồ thời gian thực dùng vi điều khiển nhúng PicoBlaze.

Với mục đích nghiên cứu tìm hiểu công nghệ FPGA phục vụ cho công tác giảng dạy nghiên cứu của bản thân tại tr−ờng Cao đẳng Công nghiệp Nam Định nên sản phẩm thiết kế mới chỉ dừng lại ở một số ứng dụng nhỏ. Tuy nhiên với những kết quả đã đạt đ−ợc trong thời gian làm luận văn vừa qua đã giúp em làm chủ đ−ợc việc thiết kế với FPGA và CPLD của hãng Xilinx cũng nh− các linh kiện logic lập trình khác. Hy vọng luận văn này sẽ giúp ích cho ng−ời bắt đầu tìm hiểu về lĩnh vực này phần nào.

Em xin chân thành cảm ơn TS Nguyễn Nam Quân, ng−ời đã trực tiếp h−ớng dẫn em trong quá trình làm luận văn này. Tập thể các thầy cô trong Khoa Điện tử -Viễn thông tr−ờng, Viện đào tạo sau đại học tr−ờng Đại học Bách Khoa Hà Nội,các thầy cô giáo khoa Điện - Điện tử tr−ờng Cao đẳng Công nghiệp Nam Định đã giúp đỡ em về mặt thời gian cũng nh− sự động viên của bạn bè và ng−ời thân về mặt tinh thần trong thời gian thực hiện luận văn này.

Tài liệu tham khảo:

1.TS Nguyễn Nam Quân, Toán lôgic và kỹ thuật số, NXBKHKT,2006 2.TS Phạm Ngọc Nam, Embedded systems,2006

3.Xillinx, “ISE In-Depth Tutorial”, www.xilinx.com

4.Xilinx,”Spartan 3E Started Kit User Guide”, www.xilinx.com

5.Xilinx, “PicoBlaze8-bitEmbeddedMicrocontrollerUserGuide”, www.xilinx.com

6.Xilinx, “FrequencyGeneratorfor Spartan-3EStarterKit”, www.xilinx.com

7.Volnei A. Pedroni, Circuit Design with VHDL,MIT Press Cambridge, Massachusetts London, England, 2004.

Một phần của tài liệu Nghiên cứu tìm hiểu công nghệ FPGA trong thiết kế mạch điện tử (Trang 88 - 97)

Tải bản đầy đủ (PDF)

(97 trang)