Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
17 years ago

RS232 communication with a MAX 2 CPLD

Hi everyone,

I'm trying to send data (8 bits) from my CPLD MAX2 to my computer using the RS232 protocol but I don't find anything good.

First, I have tried the SOPC RS2323 module witch give me an error :"...avalon-MM master needed..." but the nios 2 CPU don't support MAX2 chip so where can I find an other master or create it?

I also thing about using a latch module with the good frequency (to send at a RS232 standard rate) witch send my 8 bits but I don't find how can I generate the good frequency (I'm limited to 3.3 or 5.5 MHz with the alt_oscillator module).

As you can see with my vocabulary, I'm french, and furthermore, I'm beginner, so please well feel free to detail.

Thanks a lot :rolleyes:

9 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    A basic Rx- or Tx-UART with MAX II is pretty easy. I append a component I previously used. Please note the unusual oversampling ratio of 13 with the receiver, that helps to setup the needed baud rate with a rather low crystal frequency.

    But I don't think that it will work satisfyingly with MAX II internal oscillator, cause the frequency is too unprecise. A least a tuning for each individual device would be necessary.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi FvM,

    I really thanks you for your help. I know it was a very simple program for you but for me It's a lot.

    My system send data to the computer well now but I have some difficulties to create a internal clock.

    I read some post with your advices but I'm not very good at vhdl so I don't understand everything (Furthermore, I'm french so I don't understand every words...).

    Is it possible to create a box with my 66MHz clock as input and a customized clock as output ? I tried to find it in altera function but visibly, it doesn't exist for CPLD MAX 2.

    Have you got an other example or an idea ?

    Don't hesitate to explain to me very simply
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    You need an external clock source with sufficient stability, typically a crystal oscillator. In my example, I'm using a 6 MHz crystal oscillator. MAX II has an internal oscillator, that can be accessed my a MegaFunction, but has only a roughly defined frequency and isn't suitable for UART communication. You would need an individual calibration at least, and there's no specified stability over temperature or supply voltage variation.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I have wrote this clock generator using your RS232 code (thx :-) and it works.

    But to use it simply, I want to put the value 133 (INTEGER) as a variable.

    In fact I use this code in a block with my 66.6Mhz clock in input and my created clock in a output, and I want to add an other input with a 16 bit constant value to change easily the clock divider. All solutions that I try doesnt work and altera show me an error screen so is it really possible to do that?

    I don't know if you have understand my question but, in advance, thanks

    --- Quote Start ---

    library ieee;

    use ieee.std_logic_1164.all;

    use ieee.std_logic_arith.all;

    entity CustclockV3 is

    port (

    Clk : in Std_Logic; -- Sample CLK

    clkout : buffer Std_Logic);

    end entity;

    architecture RTL of CustclockV3 is

    signal clkcount : unsigned(7 downto 0);

    CONSTANT BAUD : INTEGER := 133; -- 500kHz @ 66.66 MHz

    begin

    -- Tx Process

    TxProc : process(Clk)

    begin

    if Rising_Edge(Clk) then

    if clkcount < BAUD-1 then

    clkcount <= clkcount + 1;

    clkout <= '0';

    else

    clkout <= '1';

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

    end if;

    end if;

    -- RisindEdge(clk)

    end process;

    end RTL;

    --- Quote End ---

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    You most likely didn't use a correct data type for the clock divider input port. If you check the error message thoroughly, you should be able to understand the problem. The variable clock divider should have an unsigned type, generally. Please consider, that the bit lengths of clkcount and clock divider input should match for a meaningful operation.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I correct with

    --- Quote Start ---

    library ieee;

    use ieee.std_logic_1164.all;

    use ieee.std_logic_arith.all;

    entity CustclockV3 is

    port (

    Clk : in Std_Logic; -- Sample CLK

    clkout : buffer Std_Logic;

    div : in unsigned (7 downto 0));

    end entity;

    architecture RTL of CustclockV3 is

    signal clkcount : unsigned(7 downto 0);

    CONSTANT BAUD : unsigned(7 downto 0) := div;

    begin

    -- ClockProcess

    ClockProcess : process(Clk)

    begin

    if Rising_Edge(Clk) then

    if clkcount < baud-1 then

    clkcount <= clkcount + 1;

    clkout <= '0';

    else

    clkout <= '1';

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

    end if;

    end if;

    -- RisindEdge(clk)

    end process;

    end RTL;

    --- Quote End ---

    but it doesn't work because the program dosn't recognise the sign < (in clockprocess)

    I suppose that it keep the binary numbers and not the value of it.

    Should I make a translation line to convert unsigned (00000010) into number (2) ? If yes, how can I do that because I must do that in an other part of my program and I havn't already find the solution?

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I don't understand the problem, simply write

    --- Quote Start ---

    if clkcount < div-1 then

    --- Quote End ---

    It's basic VHDL syntax, nothing special.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Of course, I lost my mind.:o It works efficiently.:rolleyes:

    I can now try to finish my program with the binary to decimal conversion.

    Thanks for your help
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi, It's me (again:rolleyes: )

    I have some problem to realise a part of my program.

    In this part, I want to test 10 wire.

    To do that, I send by 10 output a sinple bit and I check by 10 other input pin if the bit is transmitted.

    Each wire is simply connected pin output to pin input (with resistance and other elecronique security).

    I need to check each wire lonely and in the order 0 to 9 with one at each clock cycle

    To start this part, I tried to send a bit on each wire lonely and wrote this very simple vhdl code :

    --- Quote Start ---

    library ieee;

    use ieee.std_logic_1164.all;

    use ieee.std_logic_arith.all;

    entity VHDL_V1 is

    port (

    CLK : in std_logic; -- Sample CLK

    --BUSIN : in std_logic_Vector(7 downto 0); -- BUS commun aux sections

    REF : buffer std_logic_vector(9 downto 0) -- Alimentation des differentes sections

    );

    end entity;

    architecture numero1 of VHDL_V1 is

    begin

    VHDLProc : process(CLK ,REF )

    begin

    for i in 9 to 0 loop

    wait until clk = '1';

    REF(i) <= '1';

    wait until clk = '0';

    end loop;

    end process;

    end numero1;

    --- Quote End ---

    The compilation windows say "ok" and the simulation too but in the simulation report, my output REF doesn't change. Do you understand why ?

    It's my first code written in vhdl so it can be bad but I don't know where...:confused:

    Do you have an idea ?