UART передатчик на VHDL
Модуль передатчика UART на VHDL можно записать одной строкой. Для передатчика UART на VHDL нужен всего лишь простой сдвиговый регистр, куда по стробу записываются данные и сразу же начинается их сдвиг, например фронтом частоты бод, младшими разрядами вперед. Но для того, чтобы этот процесс был хорошо синхронизирован необходимо к сдвиговому регистру приклеить буфер, лучше двойной. Тоесть сначала данные загружаются в буфер, затем перегружаются в буфер для сдвига таким образом освобождая первый буфер для следующей загрузки.
В приведенном ниже VHDL коде выполнен такой передатчик. За его основу взят свободно распространяемый код UARTот Xilix. Кстати полезна будет также литература по VHDL Verilog.
library ieee ;
use ieee.std_logic_1164.all ;
use ieee.std_logic_arith.all ;
entity txmit is
generic
(
databytes : integer := 8 ; -- кол. бит данных (5,6,7,8)
stopbits : integer := 1 -- кол. стоп бит (1 или 2)
) ;
port
(
-- общий срос
rst : in std_logic ;
-- -- частота бод *16
clk16x : in std_logic ;
-- загрузка данных в буфер на передачу (falling edge)
wrn : in std_logic ;
-- входные данные
din : in std_logic_vector(databytes - 1 downto 0) ;
-- буфер передатчика пуст
tbre : out std_logic ;
-- выход передатчика
txd : out std_logic ;
-- выход сигнала rts (для rs485)
rts : out std_logic
);
end txmit ;
architecture v1 of txmit is
-- функция инвертирования данных
function revers_inv (iv_data : in std_logic_vector(databytes - 1 downto 0)) return std_logic_vector is
variable sv_return : std_logic_vector(databytes - 1 downto 0):=(others => '0');
begin
for i in 0 to databytes - 1
loop
sv_return(i):=iv_data(databytes - 1 - i);
end loop;
return sv_return;
end revers_inv;
-- разблокировка счетчика передатчика
signal clk1x_enable : std_logic ;
-- передающий буфер
signal tsr : std_logic_vector (databytes - 1 downto 0) ;
-- буфер для загрузки данных
signal tbr : std_logic_vector (databytes - 1 downto 0) ;
-- счетчик передатчика
signal clkdiv : unsigned (3 downto 0) ;
-- частота бод
signal clk1x : std_logic ;
-- счетчик состояний передатчика
signal no_bits_sent : unsigned (3 downto 0);
-- битовый буфер
signal wrn1 : std_logic ;
-- битовый буфер 2
signal wrn2 : std_logic ;
begin
-- старт передачи фрейма
process (rst,clk16x)
begin
if rst = '1' then
wrn1 <= '1' ;
wrn2 <= '1' ;
elsif clk16x'event and clk16x = '1' then
wrn2 <= wrn1 ;
wrn1 <= wrn ;
end if ;
end process ;
-- строб работы передатчика
process (rst,clk16x)
begin
if rst = '1' then
clk1x_enable <= '0' ;
tbre <= '0' ;
elsif clk16x'event and clk16x = '0' then
if wrn1 = '0' and wrn2 = '1' then
tbre <= '0' ;
clk1x_enable <= '1' ;
elsif conv_integer(no_bits_sent) = 2 then
tbre <= '1' ;
elsif conv_integer(no_bits_sent) = databytes + stopbits + 3 and clk1x = '0' then
clk1x_enable <= '0' ;
end if ;
end if ;
end process ;
rts <= clk1x_enable ;
-- загрузка данных в буфер tbr
process (rst,wrn,clk1x_enable)
begin
if rst = '1' then
tbr <= (others => '0') ;
elsif wrn'event and wrn = '0' then
tbr <= din;
-- tbr <= revers_inv(din);
end if ;
end process ;
-- формирование удвоенной частоты бод clk1x
process (rst,clk16x,clk1x_enable)
begin
if rst = '1' then
clkdiv <= "0000" ;
elsif clk16x'event and clk16x = '1' then
if clk1x_enable = '1' then
clkdiv <= clkdiv + "0001" ;
else
clkdiv <= "0000" ;
end if ;
end if ;
end process ;
clk1x <= clkdiv(3) ;
-- последовательная передача
process (rst,clk1x,no_bits_sent,tbr)
begin
if rst = '1' then
txd <= '1' ;
tsr <= (others => '0');
elsif clk1x'event and clk1x = '0' then
-- перегрузка данных из приемного буфера в передающий (из tbr в tsr)
if conv_integer(no_bits_sent) = 1 then
tsr <= tbr;
-- стартовый бит
elsif conv_integer(no_bits_sent) = 2 then
txd <= '0' ;
-- txd передача
elsif conv_integer(no_bits_sent) >= 3 and conv_integer(no_bits_sent) <= databytes + 2 then
tsr <= tsr(databytes - 2 downto 0) & '0' ;
txd <= tsr(databytes - 1) ;
-- стоповый бит (1 или 2)
elsif conv_integer(no_bits_sent) = databytes + 3 then
txd <= '1' ;
end if ;
end if ;
end process ;
-- счет no_bits_sent при clk1x_enable = '1'
process (rst,clk1x,clk1x_enable)
begin
if rst = '1' or clk1x_enable = '0' then
no_bits_sent <= "0000" ;
elsif clk1x'event and clk1x = '1' then
if clk1x_enable = '1' then
no_bits_sent <= no_bits_sent + "0001" ;
end if ;
end if ;
end process ;
----------------------------------------------------------------------
end ;
Для правильной работы UART необходимо установить такие параметры как databytes и stopbits. Функция инвертирования данных подключается в случае если передатчик должен выдвигать данные наоборот - младшими битами вперед. По умолчанию передатчик выпускает информацию старшими битами вперед. Входная частота UART передатчика должна быть в 16 раз выше частоты бод. Простейшими манипуляциями с кодом передатчик можно снабдить возможностями работы с 1, 1.5, 2 стоповыми битами, а также с битом паритета. На скриншоте ниже представлена диграмма работы RS232 передатчика по передаче пакета с Modbus запросом давления на датчик "Сапфир-22МП-ВН"
Продолжение следует...
Электроника :
- Техника электроника (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)