02 การใช้งานพอร์ทอนุกรม

บล็อกไดอะแกรม

บอร์ด MOJO ใช้ชิป ATmega32u4 (3.3V, 8MHz) โดยทำหน้าที่หลักเป็นตัวโปรแกรมชิป FPGA และสามารถเชื่อมต่อผ่านขา Tx/Rx และ SPI กับ FPGA ได้

โมดูลสำหรับการเชื่อมต่อระหว่าง FPGA กับ ATmega32u4 คือ avr_interface ซึ่งอยู่ในตัวอย่าโปรแกรม Mojo-Base-VHDL-1.1.zip จาก http://sourceforge.net/projects/mojovhdl/

avr_interface มีรายละเอียดดังบล็อกไดอะแกรมตามรูป

avr_interface ประกอบด้วยโมดูลย่่อยๆ

  • spi_slave

  • serial_tx

  • serial_rx

  • cclk_detector

ทั้งนี้ให้ลองสังเกต การเรียกใช้โมดูลย่อยเหล่านี้ของภาษา VHDL รุ่นนี้ไม่ได้ใช้คำสั่ง component แต่ใช้การเรียกใช้จาก library work และบอกการเชื่อมต่อสัญญาณพร้อมเลย

avr_interface : entity work.avr_interface

port map (........

........

........

);

ดังนั้นเราสามารถรับ-ส่งข้อมูลระหว่าง FPGA กับ PC ผ่านทางพอร์ทอนุกรมได้

การทดลองใช้พอร์ทอนุกรม

  1. ให้ไป ดาวน์โหลดโปรแกรม Mojo-Base-VHDL-1.1.zip จาก http://sourceforge.net/projects/mojovhdl/

    1. ขยายไฟล์ จะได้โฟลด์เดอร์ Mojo-Base-VHDL

    2. ให้ดับเบิลคลิกไฟล์ Mojo-Base-VHDL.xise ใน sub flodder Mojo-Base-VHDL\ise_files เพื่อรัน ise

    3. ทำการแปลโปรแกรมจนได้ mojo_top.bin แล้วนำไปโปรแรมลงชิพ FPGA บนบอร์ด MOJO ด้วยโปรแกรม Mojoloader

    4. รันโปรแกรม terminal (ในตัวอย่างนี้ใช้โปรแกรม Serial Monitor ของโปรแกรม Arduino 1.6.2 ) เพื่อทดลองการทำงาน

การทำงาน

  • เมื่อพิมพ์ตัวอักษรอะไรลงในช่องเพื่อส่งข้อมูลแล้วกด Enter

  • ข้อมูลจะถูกส่งออกจาก PC ผ่านพอร์อนุกรม (USB) เข้าสู่บอร์ด Mojo ผ่านชิพ AVR เข้าสู่ FPGA

  • FPGA รับข้อมูลแล้วส่งข้อมูลนั้นกลับออกทางพอร์ทอนุกรม คืนสู่ PC ออกแสดงผลที่โปรแกรม Terminal

อธิบายโปรแกรม (บางส่วน)

โปรแกรมทั้งหมดเก็บอยู่ใน โฟลดเดอร์ Mojo-Base-VHDL\src

โปรแกรมหลักคือ mojo_top.vhd

----------------------------------------------------------------------------------

-- Mojo_top VHDL

-- Translated from Mojo-base Verilog project @ http://embeddedmicro.com/frontend/files/userfiles/files/Mojo-Base.zip

-- by Xark

--

----------------------------------------------------------------------------------

library IEEE;

use IEEE.STD_LOGIC_1164.all;

use IEEE.NUMERIC_STD.all;

กำหนดขาสัญญาณ

---------------------------------------------------------------------------------

entity mojo_top is

port (

clk : in std_logic; -- 50Mhz clock

rst_n : in std_logic; -- "reset" button input (negative logic)

cclk : in std_logic; -- configuration clock (?) from AVR (to detect when AVR ready)

led : out std_logic_vector(7 downto 0); -- 8 LEDs on Mojo board

spi_sck : in std_logic; -- SPI clock to from AVR

spi_ss : in std_logic; -- SPI slave select from AVR

spi_mosi : in std_logic; -- SPI serial data master out, slave in (AVR -> FPGA)

spi_miso : out std_logic; -- SPI serial data master in, slave out (AVR <- FPGA)

spi_channel : out std_logic_vector(3 downto 0); -- analog read channel (input to AVR service task)

avr_tx : in std_logic; -- serial data transmited from AVR/USB (FPGA recieve)

avr_rx : out std_logic; -- serial data for AVR/USB to receive (FPGA transmit)

avr_rx_busy : in std_logic -- AVR/USB buffer full (don't send data when true)

);

end mojo_top;

---------------------------------------------------------------------------------

architecture RTL of mojo_top is

signal rst : std_logic; -- reset signal (rst_n inverted for postive logic)

-- signals for avr_interface

signal channel : std_logic_vector(3 downto 0);

signal sample : std_logic_vector(9 downto 0);

signal sample_channel : std_logic_vector(3 downto 0);

signal new_sample : std_logic;

signal tx_data : std_logic_vector(7 downto 0);

signal rx_data : std_logic_vector(7 downto 0);

signal new_tx_data : std_logic;

signal new_rx_data : std_logic;

signal tx_busy : std_logic;

-- signals for UART echo test

signal uart_data : std_logic_vector(7 downto 0); -- data buffer for UART (holds last recieved/sent byte)

signal data_to_send : std_logic; -- indicates data to send in uart_data

-- signals for sample test

signal last_sample : std_logic_vector(9 downto 0);

begin

rst <= NOT rst_n; -- generate non-inverted reset signal from rst_n button

-- NOTE: If you are not using the avr_interface component, then you should uncomment the

-- following lines to keep the AVR output lines in a high-impeadence state. When

-- using the avr_interface, this will be done automatically and these lines should

-- be commented out (or else "multiple signals connected to output" errors).

--spi_miso <= 'Z'; -- keep AVR output lines high-Z

--avr_rx <= 'Z'; -- keep AVR output lines high-Z

--spi_channel <= "ZZZZ"; -- keep AVR output lines high-Z

-- instantiate the avr_interface (to handle USB UART and analog sampling, etc.)

เรียกใช้โมดูล avr_interface และทำการเชื่อมต่อสัญญาณเข้ากับระบบ

---------------------------------------------------------------------------------

avr_interface : entity work.avr_interface

port map (

clk => clk, -- 50Mhz clock

rst => rst, -- reset signal

-- AVR MCU pin connections (that will be managed)

cclk => cclk,

spi_miso => spi_miso,

spi_mosi => spi_mosi,

spi_sck => spi_sck,

spi_ss => spi_ss,

spi_channel => spi_channel,

tx => avr_rx,

tx_block => avr_rx_busy,

rx => avr_tx,

-- analog sample interface

channel => channel, -- set this to channel to sample (0, 1, 4, 5, 6, 7, 8, or 9)

new_sample => new_sample, -- indicates when new sample available

sample_channel => sample_channel, -- channel number of sample (only when new_sample = '1')

sample => sample, -- 10 bit sample value (only when new_sample = '1')

-- USB UART tx interface

new_tx_data => new_tx_data, -- set to set data in tx_data (only when tx_busy = '0')

tx_data => tx_data, -- data to send

tx_busy => tx_busy, -- indicates AVR is not ready to send data

-- USB UART rx interface

new_rx_data => new_rx_data, -- set when new data is received

rx_data => rx_data -- received data (only when new_tx_data = '1')

);

---------------------------------------------------------------------------------

-- The following is simple test that will transmit any bytes received on UART and show upper 8-bits of analog 0 sample on LEDs

echo: process(clk, rst)

begin

if rst = '1' then -- set signals to default on reset

tx_data <= (others => '0');

uart_data <= (others => '0');

data_to_send <= '0';

new_tx_data <= '0';

channel <= "0000"; -- use channel 0 for this test

last_sample <= (others => '0');

led <= "11111111"; -- flash LEDs on reset

elsif rising_edge(clk) then

if data_to_send = '1' and tx_busy = '0' then -- if there is data to send and UART is not busy then

tx_data <= uart_data; -- set tx_data input

new_tx_data <= '1'; -- signal there is data to tx

data_to_send <= '0'; -- clear our send flag

else

new_tx_data <= '0'; -- else, we have no new tx data

end if;

if new_rx_data = '1' then -- if there is new received data then

uart_data <= rx_data; -- put it into uart_data register

data_to_send <= '1'; -- set flag that we have data to send

end if;


if new_sample = '1' then -- if there is a new sample available then

last_sample <= sample; -- put it into last_sample register

end if;


led <= last_sample(9 downto 2); -- display upper 8-bits of last 10-bit analog sample reading

end if;

end process echo;

end RTL;

หมายเหตุ

โปรแกรมที่เป็นสีแดงคือส่วนที่ใช้ติดต่อกับพอร์ทอนุกรม

โปรแกรมสีน้ำเงิน ใช้ติดต่อกับพอร์ทอนาลอก

เราสามารถใช้โปรแกรมนี้ (mojo_top.vhd) เป็นโปรแกรมหลักสำหรับทำงานอื่นๆได้ โดยการ copy ทั้งโปรเจค (เอาเฉพาะ source ที่ยังไม่ได้แปล ไปแก้ไขเพื่อให้ทำงานอื่นๆได้ ดังตัวอย่างที่จะเขียนต่อไป

โปรดติดตาม