Интерфейс RS232 или UART прием и передача на VHDL
Тема UART или интерфейса RS232 на VHDL уже подымалась на нашем ресурсе. Данный пост это развитие темы UART VHDL в более продвинутой манере кодирования на VHDL. Приведенный далее код приемника и передатчика RS232 работает, можно сказать, безупречно в широком диапазоне скоростей вплоть до 115200 бод/сек. Код найден на просторах глобальной сети, немного доработан, просимулирован в Modelsim, протестирован и используется в реально действующих проектах. В конце поста имеется ссылка для загрузки полного проекта UART для Quartus11.0.
Проект содержит полный рабочий код RS232 приемника, передатчика и верхнеуровневого модуля для проверки их работоспособности на симуляторе Modelsim 6.6d. На картинке ниже представлена диаграмма работы RS232 на передачу и на прием на скоростях 115200 и 57600 бод/сек соответственно. На вход передатчика (din) поступают побайтно данные 0х55, 0хAA, 0x01 которые затем последовательно выводятся на выход (tx). На вход приемника (rx) поступают последовательные данные 0х55, 0хAA, 0x02 которые последовательно появляются на выходе (dout).
Все то же самое можно просмотреть непосредственно из проекта Uart_Quartus110. Для этого достаточно его открыть в среде Quartus11.0 и затем выполнить простейшую операцию по запуску временного симулирования в ModelSim6.6d. Все подробно описано в посте о временной симуляции в Quartus+ModelSim. Если коротко то из главного меню Quartus необходимо выполнить команду EDA Gate Level Simulation...
Все необходимые установки для данного вида симуляции уже выполнены, файл тестбенча Uart.vht подготовлен. Далее можно поварьировать скоростями в тестбенче, не забывая при этом поменять соответствующие установочные скорости UART приемника и передатчика в верхнеуровневом файле Uart.vhd в картах соединений компонентов исходя из того что исходная частота бод в верхнеуровневом модуле выставлена 115200 бод/сек. Например, для того, чтобы изменить частоту бод для RS232 приемника в сторону уменьшения можно в generic map записать BAUDRATE => BAUDRATE/3. В этом случае UART приемник будет работать на частоте 115200/3 - 38400 бод/сек.
Соответственно в файле тестбенча, который представлен ниже по тексту изменить участок кода связанный с частотой бод.
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY Uart_vhd_tst IS
END Uart_vhd_tst;
ARCHITECTURE Uart_arch OF Uart_vhd_tst IS
-- constants
constant clk_period : time := 20.00 ns;
-- 115200 Гц
constant bod_period : time := 8680 ns;
constant rx_data0 : STD_LOGIC_VECTOR(7 DOWNTO 0):= X"55";
constant rx_data1 : STD_LOGIC_VECTOR(7 DOWNTO 0):= X"AA";
constant rx_data2 : STD_LOGIC_VECTOR(7 DOWNTO 0):= X"02";
-- signals
SIGNAL clk : STD_LOGIC;
SIGNAL reset : STD_LOGIC;
SIGNAL din : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL tx_en : STD_LOGIC;
SIGNAL tx : STD_LOGIC;
SIGNAL tx_done_tick : STD_LOGIC;
SIGNAL rx : STD_LOGIC;
SIGNAL rx_done_tick : STD_LOGIC;
SIGNAL dout : STD_LOGIC_VECTOR(7 DOWNTO 0);
subtype tresh_test is std_logic_vector(7 downto 0);
type memory_tresh_test is array(7 downto 0) of tresh_test;
signal s_tresh_test : memory_tresh_test;
COMPONENT Uart
PORT (
clk : IN STD_LOGIC;
dout : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
din : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
reset : IN STD_LOGIC;
rx : IN STD_LOGIC;
tx : OUT STD_LOGIC;
rx_done_tick : OUT STD_LOGIC;
tx_done_tick : OUT STD_LOGIC;
tx_en : IN STD_LOGIC
);
END COMPONENT;
BEGIN
i1 : Uart
PORT MAP (
clk => clk,
dout => dout,
din => din,
reset => reset,
rx => rx,
tx => tx,
rx_done_tick => rx_done_tick,
tx_done_tick => tx_done_tick,
tx_en => tx_en
);
-- системный сброс
init : PROCESS
BEGIN
reset <= '0', '1' after 2*clk_period;
WAIT;
END PROCESS init;
-- тактовая
always : PROCESS
BEGIN
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
END PROCESS always;
-- процесс на входе com
comrx : process
begin
rx <= '1';
tx_en <= '0';
wait for 5us;
-- данные на передатчик
tx_en <= '1';
din <= X"55";
wait for bod_period*9;
din <= X"AA";
wait for bod_period*9;
din <= X"01";
wait for bod_period*9;
tx_en <= '0';
wait for bod_period*9;
wait for 10us;
-- данные на вход приемника
for j in 0 to 2 loop
if j = 0 then
s_tresh_test(j) <= rx_data0;
elsif j = 1 then
s_tresh_test(j) <= rx_data1;
elsif j = 2 then
s_tresh_test(j) <= rx_data2;
end if;
-- старт бит
rx <= '0';
wait for bod_period*2;
-- передача байта
for i in 0 to 7 loop
rx <= s_tresh_test(j)(i); wait for bod_period*2;
end loop;
-- стоп бит
rx <= '1';
wait for bod_period*2;
end loop;
wait;
end process comrx;
END Uart_arch;
Тоесть в участке кода ниже текста "-- данные на вход приемника" вместо bod_period*2 необходимо записать bod_period*3. Примерно так-же можно варьировать скоростью и для RS232 передатчика. При этом может также понадобиться увеличить время симуляции в файле Uart_ms.do до 2...3ms. Ну, как-то так. Дерзайте.
Ps. Полезный ресурс где представлен альтернативный вариант RS232 на Verilog.
Электроника :
- Техника электроника (11)
- Полезная электроника (4)
- Электроника для всех (5)
- Техника для дома (6)
- Cхемотехника ПЛИС (11)
- Пректирование PCAD (4)
Программирование :
- Микроконтроллеры (9)
- ПЛИС VHDL Verilog (29)
- C++ Builder (7)
- Visual Studio C++ C# (7)
- Java programming (7)
- Matlab programming (4)
Сайтостроение :
- Сайтостроение HTML (5)
- Сайтостроение PHP (8)
- PHP CMS на файлах (3)
- Web инструменты (9)
- Полезное вебмастеру (11)
- SEO раскрутка сайта (4)
- PHP скрипты (3)
Реклама :
Книги и учебники :
- Шаблоны сайтов (6)
- Книги и учебники (2)
Компьютер и интернет :
Поиск по сайту :
Реклама :
Облако меток :
Бесплатная подписка :
Статистика :
- Популярность (3)
- Посещаемость (3)
- Поисковые запросы (3)