Mình đang tìm hiểu board ProASIC3 của Actel, mục tiêu của mình là có thể nhận dữ liệu từ PC đưa xuống board qua cổng nối tiếp RS232. Về chương trình để gửi dữ liệu từ PC xuống board mình đã có rùi(Terminal, LookRS 232) nhưng ko biết cơ chế nhận data trên các board FPGA sẽ như thế nào. Rất mong được các bạn chỉ dùm...(có thể là cơ chế nhận data trên board FPGA nói chung cũng được, nếu trên board ProASIC3 của Actel thì quá tốt). Thanks các bạn nhiu nhiu
Thông báo
Collapse
No announcement yet.
Nhận dự liệu từ cổng nối tiếp RS232 trên board FPGA
Collapse
X
-
Ca^`n biet:
-Mode hoat dong cua RS232: mấy cai thông số: baudrate, handshaking ... -2 lines cua RS232 TX voi RX
-Nếu đã lấy Code tren mang rồi thi cũng ko cần biết chi tiêt trong đó lam gì, Set up core cho đúng thôi ... baudrate, stop bit, parity nay no ..
Comment
-
mình đã lam` được truyền dữ liệu từ RS232 xuống kit FPGA,nhưng mình sử dụng Kit DE2 của altera.Cơ chế nhận cũng khá đơn giản.Ví dụ:trong khung truyền của bạn là 8bit dữ liệu,1 start,1stop và tốc độ baud là 9600 chẳng hạn.Thì khi nhận,bạn chỉ việc chia tần số clock trên board sao cho trùng với tốc độ baud(9600bit/s).sau đó bạn lập trình theo kiểu máy trạng thái,lấy dữ liệu từ chân RX của FPGA.Bạn có thể tham khảo trên FPGA4FUN.Mình cũng tham khảo từ đấy.
Comment
-
Tần số sampling của receiver nên cao hơn baud rate nhiều lần (thường là 16x).
Nếu sampling rate = baud rate, có thể có vấn đề, vì transmitter và receiver dùng hai oscillator khác nhau, clock edge của transmitter và receiver không trùng khớp nhau. Hơn nữa, mỗi oscillator có thể sai lệch chút ít, thí dụ như transmitter = 9600.1Hz và receiver = 9599.9Hz. Sau một thời gian, bên transmitter có thể đã chuyển bit thứ 96001, trong khi bên receiver vẫn còn đang chờ cho bit thứ 95599, receiver lầm data bit là start bit, vv.
Comment
-
Nguyên văn bởi typhn Xem bài viếtmình đã lam` được truyền dữ liệu từ RS232 xuống kit FPGA,nhưng mình sử dụng Kit DE2 của altera.Cơ chế nhận cũng khá đơn giản.Ví dụ:trong khung truyền của bạn là 8bit dữ liệu,1 start,1stop và tốc độ baud là 9600 chẳng hạn.Thì khi nhận,bạn chỉ việc chia tần số clock trên board sao cho trùng với tốc độ baud(9600bit/s).sau đó bạn lập trình theo kiểu máy trạng thái,lấy dữ liệu từ chân RX của FPGA.Bạn có thể tham khảo trên FPGA4FUN.Mình cũng tham khảo từ đấy.
Nguyên văn bởi nemesis21 Xem bài viếtTần số sampling của receiver nên cao hơn baud rate nhiều lần (thường là 16x).
Nếu sampling rate = baud rate, có thể có vấn đề, vì transmitter và receiver dùng hai oscillator khác nhau, clock edge của transmitter và receiver không trùng khớp nhau. Hơn nữa, mỗi oscillator có thể sai lệch chút ít, thí dụ như transmitter = 9600.1Hz và receiver = 9599.9Hz. Sau một thời gian, bên transmitter có thể đã chuyển bit thứ 96001, trong khi bên receiver vẫn còn đang chờ cho bit thứ 95599, receiver lầm data bit là start bit, vv.
Comment
-
Nguyên văn bởi nemesis21 Xem bài viếtTần số sampling của receiver nên cao hơn baud rate nhiều lần (thường là 16x).
Nếu sampling rate = baud rate, có thể có vấn đề, vì transmitter và receiver dùng hai oscillator khác nhau, clock edge của transmitter và receiver không trùng khớp nhau. Hơn nữa, mỗi oscillator có thể sai lệch chút ít, thí dụ như transmitter = 9600.1Hz và receiver = 9599.9Hz. Sau một thời gian, bên transmitter có thể đã chuyển bit thứ 96001, trong khi bên receiver vẫn còn đang chờ cho bit thứ 95599, receiver lầm data bit là start bit, vv.
thực tế thì sai số của hai bộ oscillator của bên trans và recei có thể cho phép là 10 %, bởi sau khi kết thúc nhận một frame data thì quá trình gởi nhận data sẽ được reset lại từ đầu, nên sai số chỉ là sai số trong thời gian 1 khung truyền, nếu hiểu như bác thì dù sai số của hai oscillator có rất nhỏ thì sau 1 thời gian gởi nhận data thì cũng bị lỗi data.
Comment
-
Nếu mình sử dụng chương trình Terminal để truyền dữ liệu từ PC xuống board thì liệu có xảy ra tình trạng mất hoặc sai dữ liệu nhiều ko?(mình muốn truyền dữ liệu mà ko sử dụng tín hiệu bắt tay - handshacking).
Về cách kết nối của cable RS232 thì chúng ta sử dụng 3 chân (2 - RxD, 3 - TxD,5 - GND) hay...Mình đọc một số tài liệu thì thấy ngoài 3 chân này thì khi truyền nhận mà ko sử dụng tín hiệu handshacking phải nối thêm 2 chân RTS & CTS và DTR & DSR vào nhau? Điều này có đúng ko các bạn?
Comment
-
Nguyên văn bởi thavali Xem bài viếtcó thể bác nếmis đã nhầm ở chỗ: "thí dụ như transmitter = 9600.1Hz và receiver = 9599.9Hz. Sau một thời gian, bên transmitter có thể đã chuyển bit thứ 96001, trong khi bên receiver vẫn còn đang chờ cho bit thứ 95599, receiver lầm data bit là start bit"
thực tế thì sai số của hai bộ oscillator của bên trans và recei có thể cho phép là 10 %, bởi sau khi kết thúc nhận một frame data thì quá trình gởi nhận data sẽ được reset lại từ đầu, nên sai số chỉ là sai số trong thời gian 1 khung truyền, nếu hiểu như bác thì dù sai số của hai oscillator có rất nhỏ thì sau 1 thời gian gởi nhận data thì cũng bị lỗi data.
Thường thì bạn sample data ngay giữa bit, sai số 10% hình như quá lớn, chưa kể trường hợp bạn có thêm parity bit. Còn các vấn đề khác với đường chuyền, thí dụ như tín hiệu rise/fall chậm, sẽ khiến cho sai số đó càng phải nhỏ hơn.
Comment
-
Nguyên văn bởi tienbkit Xem bài viếtNếu mình sử dụng chương trình Terminal để truyền dữ liệu từ PC xuống board thì liệu có xảy ra tình trạng mất hoặc sai dữ liệu nhiều ko?(mình muốn truyền dữ liệu mà ko sử dụng tín hiệu bắt tay - handshacking).
Về cách kết nối của cable RS232 thì chúng ta sử dụng 3 chân (2 - RxD, 3 - TxD,5 - GND) hay...Mình đọc một số tài liệu thì thấy ngoài 3 chân này thì khi truyền nhận mà ko sử dụng tín hiệu handshacking phải nối thêm 2 chân RTS & CTS và DTR & DSR vào nhau? Điều này có đúng ko các bạn?
Nếu cả hai bên đều không sử dụng handshaking, thì nối RTS & CTS và DTR & DSR cũng không cần thiết.
Comment
-
Neu ban muon co duoc ca truyen va nhan thi lien he voi minh theo email duchut@gmail.com.
Hoac em co the len trang web fpga4fun.com de download ve . Ho viet bang code Verilog hoac VHDL
Comment
-
Mình đã tham khảo code trên fpga4fun và sửa lại nhưng chẳng hiểu sao chạy ko dc...Không thể xác định được kết quả ra output là gì cả. Các bạn xem qua code và chỉ giúp mình chỗ sai với nhé!Thanks alot!
Code:// RS232_main.v module RS232_main(clk, RxD, TxD, GPout, GPin); input clk; input RxD; output TxD; output [7:0]GPout; input [7:0]GPin; wire RxD_data_ready; wire [7:0]RxD_data; async_receiver RS232(.clk(clk), .RxD(RxD), .RxD_data_ready(RxD_data_ready), .RxD_data(RxD_data)); reg [7:0]GPout; always @(posedge clk) if(RxD_data_ready)GPout<=RxD_data; endmodule //async_receiver.v module async_receiver(clk, RxD, RxD_data_ready, RxD_data, RxD_endofpacket, RxD_idle); input clk, RxD; output RxD_data_ready; // onc clock pulse when RxD_data is valid output [7:0] RxD_data; //parameter ClkFrequency = 25000000; // 25MHz parameter ClkFrequency = 40000000; // 40MHz parameter Baud = 115200; output RxD_endofpacket; // one clock pulse, when no more data is received (RxD_idle is going high) output RxD_idle; // no data is being received // Baud generator (we use 16 times oversampling) //parameter Baud8 = Baud*8; parameter Baud8 = Baud*16; parameter Baud8GeneratorAccWidth = 16; wire [Baud8GeneratorAccWidth:0] Baud8GeneratorInc = ((Baud8<<(Baud8GeneratorAccWidth-7))+(ClkFrequency>>8))/(ClkFrequency>>7); reg [Baud8GeneratorAccWidth:0] Baud8GeneratorAcc; always @(posedge clk) Baud8GeneratorAcc <= Baud8GeneratorAcc[Baud8GeneratorAccWidth-1:0] + Baud8GeneratorInc; wire Baud8Tick = Baud8GeneratorAcc[Baud8GeneratorAccWidth]; //////////////////////////// reg [1:0] RxD_sync_inv; always @(posedge clk) if(Baud8Tick) RxD_sync_inv <= {RxD_sync_inv[0], ~RxD}; // we invert RxD, so that the idle becomes "0", to prevent a phantom character to be received at startup reg [1:0] RxD_cnt_inv; reg RxD_bit_inv; always @(posedge clk) if(Baud8Tick) begin if( RxD_sync_inv[1] && RxD_cnt_inv!=2'b11) RxD_cnt_inv <= RxD_cnt_inv + 2'h1; else if(~RxD_sync_inv[1] && RxD_cnt_inv!=2'b00) RxD_cnt_inv <= RxD_cnt_inv - 2'h1; if(RxD_cnt_inv==2'b00) RxD_bit_inv <= 1'b0; else if(RxD_cnt_inv==2'b11) RxD_bit_inv <= 1'b1; end reg [3:0] state; reg [3:0] bit_spacing; wire next_bit = (bit_spacing==4'd10); always @(posedge clk) if(state==0) bit_spacing <= 4'b0000; else if(Baud8Tick) bit_spacing <= {bit_spacing[2:0] + 4'b0001} | {bit_spacing[3], 3'b000}; //Baud8Tick always @(posedge clk) if(Baud8Tick) case(state) 4'b0000: if(RxD_bit_inv) state <= 4'b1000; // start bit found? 4'b1000: if(next_bit) state <= 4'b1001; // bit 0 4'b1001: if(next_bit) state <= 4'b1010; // bit 1 4'b1010: if(next_bit) state <= 4'b1011; // bit 2 4'b1011: if(next_bit) state <= 4'b1100; // bit 3 4'b1100: if(next_bit) state <= 4'b1101; // bit 4 4'b1101: if(next_bit) state <= 4'b1110; // bit 5 4'b1110: if(next_bit) state <= 4'b1111; // bit 6 4'b1111: if(next_bit) state <= 4'b0001; // bit 7 4'b0001: if(next_bit) state <= 4'b0000; // stop bit default: state <= 4'b0000; endcase //RxD_data reg [7:0] RxD_data; always @(posedge clk) if(Baud8Tick && next_bit && state[3]) RxD_data <= {~RxD_bit_inv, RxD_data[7:1]}; //RxD_data_ready, RxD_data_error reg RxD_data_ready, RxD_data_error; always @(posedge clk) begin RxD_data_ready <= (Baud8Tick && next_bit && state==4'b0001 && ~RxD_bit_inv); // ready only if the stop bit is received RxD_data_error <= (Baud8Tick && next_bit && state==4'b0001 && RxD_bit_inv); // error if the stop bit is not received end //RxD_idle reg [4:0] gap_count; always @(posedge clk) if (state!=0) gap_count<=5'h00; else if(Baud8Tick & ~gap_count[4]) gap_count <= gap_count + 5'h01; assign RxD_idle = gap_count[4]; reg RxD_endofpacket; always @(posedge clk) RxD_endofpacket <= Baud8Tick & (gap_count==5'h0F); endmodule
Comment
-
chu de RS232 soi noi that.Minh da lam thu tren KIT DE2 cua Artera thi thay no chay dung.Thuc ra thi moi Kit cua moi hang khac nhau thi cung co cung mot nguyen tac.Minh post code RS_receive viet bang VHDL len anh em gop y nhe.Code nay minh lay tren trang http://www.fpga4fun.com/ExternalContributions/.Phan receiver minh co chinh sua mot ty thi no chay duoc tren KIT DE2 cua Artera.
--
-- UART: receiver
--
-- Copyrighted by Wincent Balin
-- Idea by Jean P. Nicolle
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
entity UARTReceiver is
generic
(
frequency : integer:=50000000;
baud : integer:=9600;
oversampling : integer:=8
);
port
(
clk : in std_logic;
rxd : in std_logic;
rxd_data : out std_logic_vector(7 downto 0);
rxd_data_ready : out std_logic
);
end entity UARTReceiver;
architecture UARTReceiverArch of UARTReceiver is
-- defining constants
constant BIT_SPACE : integer := 10; -- 8 to 11 are common
constant DIVISOR : integer := 1600;
constant FREQ_INC : integer := (oversampling + 0) * baud / DIVISOR;
constant FREQ_DIV : integer := frequency / DIVISOR;
constant FREQ_MAX : integer := FREQ_DIV + FREQ_INC - 1;
-- defining types
type state_type is (idle, bit0, bit1, bit2, bit3, bit4, bit5, bit6, bit7, stop);
-- defining signals
signal state : state_type := idle; -- receiver's state
signal rxd_sync_inv : std_logic_vector(1 downto 0);
signal rxd_cnt_inv : std_logic_vector(1 downto 0);
signal rxd_bit_inv : std_logic;
signal baud_divider : integer range 0 to FREQ_MAX := 0;
signal data : std_logic_vector(7 downto 0);
signal baudover_tick : std_logic := '0';
signal bit_spacing : integer range 0 to 15;
signal next_bit : std_logic := '0';
begin
-- assignments
next_bit <= '1' when bit_spacing = BIT_SPACE else '0';
-- processes
baud_gen : process(clk)--dung de bam xung, tao ra xung co tan so lon hon toc do baud
begin
if clk'event and clk = '1' then
baud_divider <= baud_divider + FREQ_INC;
if baud_divider >= FREQ_DIV then
baud_divider <= 0;
baudover_tick <= '1';
else
baudover_tick <= '0';
end if;
end if;
end process baud_gen;
--
rxd_sync_inverted : process(clk) -- inverted to suppress phantom character
begin
if clk'event and clk = '1' then
if baudover_tick = '1' then
rxd_sync_inv <= rxd_sync_inv(0) & not rxd;
end if;
end if;
end process rxd_sync_inverted;
--
rxd_counter_inverted : process(clk)
begin
if clk'event and clk = '1' then
if baudover_tick = '1' then
if rxd_sync_inv(1) = '1' and rxd_cnt_inv /= "11" then
rxd_cnt_inv <= unsigned(rxd_cnt_inv) + 1;
elsif rxd_sync_inv(1) = '0' and rxd_cnt_inv /= "00" then
rxd_cnt_inv <= unsigned(rxd_cnt_inv) - 1;
end if;
if rxd_cnt_inv = "00" then
rxd_bit_inv <= '0';
elsif rxd_cnt_inv = "11" then
rxd_bit_inv <= '1';
end if;
end if;
end if;
end process rxd_counter_inverted;
--
state_proc : process(clk)
begin
if clk'event and clk = '1' then
if baudover_tick = '1' then
case state is
when idle =>
if rxd_bit_inv = '1' then
state <= bit0;
end if;
when bit0 =>
if next_bit = '1' then
state <= bit1;
end if;
when bit1 =>
if next_bit = '1' then
state <= bit2;
end if;
when bit2 =>
if next_bit = '1' then
state <= bit3;
end if;
when bit3 =>
if next_bit = '1' then
state <= bit4;
end if;
when bit4 =>
if next_bit = '1' then
state <= bit5;
end if;
when bit5 =>
if next_bit = '1' then
state <= bit6;
end if;
when bit6 =>
if next_bit = '1' then
state <= bit7;
end if;
when bit7 =>
if next_bit = '1' then
state <= stop;
end if;
when stop =>
if next_bit = '1' then
state <= idle;
end if;
end case;
end if;
end if;
end process state_proc;
--
bit_spacing_proc : process(clk)
begin
if clk'event and clk = '1' then
if state = idle then
bit_spacing <= 0;
elsif baudover_tick = '1' then
if bit_spacing < 15 then
bit_spacing <= bit_spacing + 1;
else
bit_spacing <= 8;
end if;
end if;
end if;
end process bit_spacing_proc;
--
shift_data_proc : process(clk)
begin
if clk'event and clk = '1' then
if baudover_tick = '1' and next_bit = '1' and
state /= idle and state /= stop then
data <= not rxd_bit_inv & data(7 downto 1);
end if;
end if;
end process shift_data_proc;
--
output_data_proc : process(clk)
begin
if clk'event and clk = '1' then
if baudover_tick = '1' and next_bit = '1' and
state = stop and rxd_bit_inv = '0' then
rxd_data <= data;
rxd_data_ready <= '1';
else
rxd_data_ready <= '0';
end if;
end if;
end process output_data_proc;
end UARTReceiverArch;
Comment
Bài viết mới nhất
Collapse
-
bởi yname11 E có 1 laptop bị hỏng màn hình, e tháo ra thì thấy nó có 4 lớp , lớp ngoài cùng là 1 lớp nhựa rất mỏng màu hơi đen ( chắc là 1 loại film dán), tiếp theo là 1 lớp thủy tinh bị vỡ (màu đen) , đến 1 lớp thủy tinh trắng ( lớp này có...
-
Channel: Thiết bị điện tử cá nhân
hôm nay, 19:12 -
-
Trả lời cho Mua anten ở đâu?bởi tmcodonAnten bạn thu nguồn sóng nào vậy? Nếu xem truyền hình thì giờ k làm đc anten nữa rồi
-
Channel: Ăng ten và truyền sóng
16-11-2024, 15:34 -
-
Trả lời cho Mạch nguồn đôi dùng 7812 và 7912bởi tmcodonThank bác nhá. Tìm mãi mới thấy. Giờ vọc đã xem sao...
-
Channel: Hỗ trợ học tập
16-11-2024, 10:39 -
-
bởi tungdqEm cần tìm sơ đồ mạch một số Main máy tính đời cao như Asrock B560M-HDV, các cao nhân chỉ giúp với. Thank!
-
Channel: Các mạch điện ứng dụng
15-11-2024, 08:27 -
-
Trả lời cho Kiểm tra biến ápbởi lamvu0677nhân tiện cho mình hỏi thêm về cái phần test hipot (cao áp),là để kiểm tra độ bền cách điện giưa các cuộn dây,mà thấy thông số test thường ở mức 4kvac,vậy nếu mấy con fail đó xài bình thường vẫn dduocj phải không ạ,vì điện mình làm gì lên tới mức đó
-
Channel: Điện tử dành cho người mới bắt đầu
10-11-2024, 08:52 -
-
Trả lời cho Kiểm tra biến ápbởi lamvu0677máy đo số vòng thì cty có ,mà nó to quá,tưởng có máy nào gọn gọn bỏ túi được thì tiện hơn,vì đi lại nhiều...
-
Channel: Điện tử dành cho người mới bắt đầu
10-11-2024, 08:47 -
-
bởi tmcodonMình thấy diễn đàn có chuyên mục quảng cáo rồi mà. Bạn đóng góp để mở luồng riêng
-
Channel: Hướng dẫn sử dụng diễn đàn
09-11-2024, 13:36 -
-
bởi Nicole08Xin chào mọi người, tôi đã sử dụng Flashforge Inventor 2 được gần 5 năm và rất hài lòng với nó, nhưng tuần trước đã xảy ra sự cố. Có vẻ như động cơ bước đưa sợi in vào đầu nóng đã bị hỏng. Mọi thứ khác có vẻ ổn trên máy...
-
Channel: Điện tử dành cho người mới bắt đầu
09-11-2024, 12:55 -
Comment