logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

RS232 – wysyłanie bajtu, na terminalu odbierane zera lub śmieci, VHDL, 600bps

sieciech 30 Sty 2008 13:08 1191 3
REKLAMA
  • #1 4751786
    sieciech
    Poziom 12  
    Posty: 107
    Ocena: 1
    Hej

    Napisałem program który wysłyła 1 bajt (wartości 0-255) po RSie do terminala. Problem w tym, że na ledach inkrementacja działa - widac jak wysłyłany bajt się zmienia, natomniast na terminalu otrzymuję same zera albo nie poukładna śmieci. Kod wyglada tak:
    shared variable temp1 : std_logic_vector(3 downto 0); -- :="11001100";
    shared variable temp2 : std_logic_vector(9 downto 0);
    signal shiftcounter: std_logic_vector(3 downto 0) := "0000";
    signal reg_clock2 : std_logic_vector(23 downto 0);
    signal rscounter: std_logic_vector(7 downto 0) := "00000000";
    begin
    process(clk)
    begin
    if (CLK'event and CLK = '1') then --rising_edge(CLK_50MHZ) then

    if reg_clock2 < 833330 then --600bps
    reg_clock2 <= reg_clock2 + 1;
    else
    reg_clock2 <= (others=>'0');
    temp2 := "1"& rscounter&"0"
    rscounter <= rscounter +1;
    if rscounter = "11111111" then
    rscounter <= "00000000";
    end if;
    result <=rscounter;

    txd<=temp2(conv_integer(shiftCounter));
    shiftCounter <= shiftCounter +1;
    if shiftCounter = "1001" then
    shiftCounter <= "0000";
    end if;
    end if;
    end if;
    end process;

    z góry dzięki za wszelkie sugestie
  • REKLAMA
  • #2 4752702
    pndemon
    Poziom 19  
    Posty: 444
    Pomógł: 35
    Ocena: 18
    
    shared variable temp1 : std_logic_vector(3 downto 0); -- :="11001100";
    shared variable temp2 : std_logic_vector(9 downto 0); 

    unikaj stosowania zmiennych

    
     if reg_clock2 < 833330 then
    

    nie stosuj warunków typu </>

    
     if rscounter = "11111111" then
    rscounter <= "00000000";
    end if; 
    

    to jest zbędne, sygnały jeśli przekroczą swój maksymalny zakres same się zerują, czyli 'przekręcają', tak jak zwykłe liczniki

    
    signal temp2 : std_logic_vector(9 downto 0);
    signal shiftcounter: std_logic_vector(3 downto 0) := "1001";
    signal reg_clock2 : std_logic_vector(23 downto 0);
    signal rscounter: std_logic_vector(7 downto 0) := "00000000"; 
    process(clk)
    begin
    if (CLK'event and CLK = '1') then --rising_edge(CLK_50MHZ) then
    	if reg_clock2 = 833330 then --600bps
    		reg_clock2 <= (others=>'0');
    		
    		rscounter <= rscounter + 1;
    		if shiftCounter = "1001" then
    			shiftCounter <= "0000";
    			temp2 <= "1"& rscounter&"0"
    		else
    			temp2 <= temp2(8 downto 0) & '0';
    			shiftCounter <= shiftCounter +1;
    		end if;
    	else
    		reg_clock2 <= reg_clock2 + 1;
    	end if;
    end if;
    end process; 
    txd<=temp2(9);

    to jest moja propozycja, nie testowałem jej, jedynie 'myślowo', więc może zawierać błędy, musisz odpalić jakiś symulator i zobaczyć co się będzie dziać, oczywiście zakładam że wszystkie wartości masz poprawnie wyliczone, oraz że na terminalu ustawiasz również tą samą prędkość transmisji

    byłbym zapomniał
     rscounter <= rscounter +1;
    if rscounter = "11111111" then
      rscounter <= "00000000";
    end if; 

    nie rób tak więcej, albo zerujesz licznik, albo inkrementujesz, czyli jakoś tak:
    
    if rscounter = "11111111" then
      rscounter <= "00000000";
    else
      rscounter <= rscounter +1;
    end if; 


    jeszcze coś mi się przypomniało, otóż transmisja zaczyna się od najmłodszego bitu a kończy na najstarszym, wobec czego trzeba dokonać odpowiednich modyfikacji w kodzie
  • REKLAMA
  • #3 4754969
    sieciech
    Poziom 12  
    Posty: 107
    Ocena: 1
    a mozesz mi wyjasnic co robia te linie w kodzie (i tez w jakim celu sie znalazly) :
    temp2 <= temp2(8 downto 0) & '0';
    ...
    txd<=temp2(9) - (czy jest to wyslyalnie bitow od 0 do 9 ? )

    czego do konca nie rozumiem (jestem wychowany na C ;) )

    z gory dzieki
  • #4 4755062
    pndemon
    Poziom 19  
    Posty: 444
    Pomógł: 35
    Ocena: 18
    To jest rejestr przesuwny, przy każdym wejściu w tą część procesu, czyli kiedy warunek 'if reg_clock2 = 833330 then' jest spełniony, w rejestrze temp2 następuje przesunięcie jego bitów w lewo, czyli np. "1110010101" przesunie się na "110010101" (czyli byty od 8-0), a na najmłodszą pozycję wejdzie '0', natomiast 'txd<=temp2(9) ' oznacza że na wyjściu układu jest zawsze widoczny najstarszy bit.
    Jak już pisałem powinieneś to obrócić czyli zamiast
    temp2 <= temp2(8 downto 0) & '0';
    dać
    temp2 <= '0' & temp2(9 downto 1);
    , a zamiast dać , wtedy będziesz przesuwał w prawo, czyli wysyłał od najmłodszego bitu.
    W VHDL'u jest jeszcze coś takiego jak 'sll' i 'slr', są to przesunięcia logiczne, dają w wyniku to samo co napisałem.
REKLAMA