This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Uart using mode 3

Hellow

I have a project now, using Atmel's AT89C51RE2 as MCU.
I've already checked each UART(UART0, UART1) worked alone in mode 1, but I need 2 uarts works simultaneously.
I heard for both uarts working, each uart configuration has different baud rate, and different mode, is it correct?
anyway, I tried to make uart work in mode 3, but I failed.
Could you give me any advice ?? (or eg?)

thank you.

Parents Reply Children
  • I appreciate your relpy.

    but I'm not good at english.
    I don't understand 'they must be interrupt driven' means.

    Could you please tell me more in detail?

    thank you.

  • take a look at this tutorial: www.8052.com/.../120308

    In fact, there's a whole section on 8051/2 serial comms at http://www.8052.com/faqs

    Hint: When is SBUF ready to take the next character...?

  • I don't think that's necessarily true at all.

    I don't see why you shouldn't poll both UARTs.

  • I don't think that's necessarily true at all
    with great skill and a very short workloop you can.

    The common misconception that poll is easier the interrupt driven is totally false.

    Anyhow now that the OP has posted readable code it is clear that an (erroneous) TI will hang him.

    Erik

  • Yes, it is very often the case that the "easy" option is the most limited option - and working around those limitations can soon make the "hard" option a lot simpler!

    In this case, I don't think polled transmission should be difficult - reception is another thing...

  • I tried to change the codes to check Tx interrupt flag before using serial buffer register(SFR : SBUF_0, SBUF_1).

    the result is uart1 has totally no respond(uart0 still works), but when I use uart0 after I check uart1 doesn't work, I see uart1 prints test string("==Exciter Uart1 Test==") just once through hyper-terminal(I use two hyper terminal program, for uart0 and uart1). the condition is when I use uart0 just after checking uart1 does not work, then I see this phenomenon.

    void print_Uart0(char *sBuf_0)
    {
        while(*sBuf_0 != NULL)
        {
            while(!TI_0);<== add this
            TI_0 = 0;  <== add this
            SBUF_0 = *sBuf_0++;
        }
        while(!TI_0);<== add this
        TI_0 = 0;><== add this
        SBUF_0 = 0x0D;
    }
    
    void print_Uart1(char *sBuf_1)
    {
        while(*sBuf_1 != NULL)
        {
            while(!TI_1);<== add this
            TI_1 = 0;  <== add this
            SBUF_1 = *sBuf_1++;
        }
        while(!TI_1);<== add this
        TI_1 = 0;><== add this
        SBUF_1 = 0x0D;
    }
    


    and add this codes in initial of main function

     TI_0 = 1;
     TI_1 = 1;
     RI_0 = 0;
     RI_1 = 0;
    

  • I tried codes below, and saw both uarts(uart0/uart1) were working concurrently.
    I just made reset each tx interrupt flag(TI_0/TI_1) in different place.

    #include <stdio.h>
    #include <string.h>
    #include "at89c51re2_2.h"
    #include "INTRINS.H"
    
    #define TRUE              1
    #define FALSE             0
    #define BUF_SIZE          50
    
    typedef unsigned char       Int8;
    typedef signed char         SignedInt8;
    typedef unsigned short      Int16;
    typedef signed short        SignedInt16;
    typedef unsigned long       Int32;
    typedef signed long         SignedInt32;
    typedef bit                 Boolean;
    
    Int8        serialBuf[BUF_SIZE];
    Int8        serialBufPos;
    Int8        serialByte;
    Boolean     parseCommandFlag = FALSE;
    
    Int8        serialBuf1[BUF_SIZE];
    Int8        serialBufPos1;
    Int8        serialByte1;
    Boolean     parseCommandFlag1 = FALSE;
    
    void print_Uart0(char *sBuf_0)
    {
        while(*sBuf_0 != NULL)
        {
            SBUF_0 = *sBuf_0++;
        }
        SBUF_0 = 0x0D;
    }
    
    void print_Uart1(char *sBuf_1)
    {
        while(*sBuf_1 != NULL)
        {
            while(!TI_1);
            TI_1 = 0;
            SBUF_1 = *sBuf_1++;
        }
        while(!TI_1);
        TI_1 = 0;
        SBUF_1 = 0x0D;
    }
    
    void ParseCommand (void)
    {
        print_Uart0("\n==Exciter UART0 Test==\n");
        memset(serialBuf, 0x00, sizeof(Int8)*BUF_SIZE);
        serialBufPos = 0;
        parseCommandFlag = FALSE;
    }
    
    void ParseCommand1(void)
    {
        print_Uart1("\n==Exciter UART1 Test==\n");
        memset(serialBuf1, 0x00, sizeof(Int8)*BUF_SIZE);
        serialBufPos1 = 0;
        parseCommandFlag1 = FALSE;
    }
    
    void main (void)
    {
        memset(serialBuf, 0x00, sizeof(Int8)*BUF_SIZE);
        serialBufPos = 0;
        memset(serialBuf1, 0x00, sizeof(Int8)*BUF_SIZE);
        serialBufPos1 = 0;
    
    /********* Timer Set ********/
        T2CON = 0;
        BDRCON_0 |= 0x0C; //RBCK_0 = 1, TBCK_0 = 1
        BDRCON_1 &= 0xF3; //RBCK_1 = 0, TBCK_1 = 0
    
        TMOD |= 0x20 ;         /* Timer 1 in mode 2 */
    
    /****** UART0 ******/
        //use internal Baud Rate Generator
        SCON_0 = 0x50;    /* uart0 in mode 1 (8 bit), REN_0=1 */
        BDRCON_0 &=0xEC;  /* BRR_0=0; SRC_0=0; SPD_0 = 0*/
        PCON |= 0x80;     /* SMOD1_0 = 1;*/
        BRL_0 = 251;      /* set 19200, @18.432Mhz (BRL_0=251;SPD_0=1;SMOD1_0=0) */
    
    
    /****** UART1 ******/
        SCON_1 = 0x50;    /* uart1 in mode 1 (8 bit), REN_1=1*/
        BDRCON_1 |= 0x80;
        TH1  = 0xFB;                 /* 19200 Bds at 18.432MHz */
    
        TI_0 = 1;
        TI_1 = 1;
        RI_0 = 0;
        RI_1 = 0;
    
        IEN1 |= 0x08;    /* Enable serial port1 interrupt   */
        ES = 1;          /* Enable serial port0 interrupt   */
        EA = 1;              /* Enable global interrupt */
    
        BDRCON_0 |=0x10; /* Baud rate generator run*/
        TR1 = 1;
        while(1)
        {
            if(parseCommandFlag == TRUE)
                ParseCommand();
            if(parseCommandFlag1 == TRUE)
                ParseCommand1();
        }
    }
    
    void serial0_IT(void) interrupt 4
    {
        if (RI_0 == 1)
        {
            RI_0 = 0;
    
            serialByte = SBUF_0; /* Read receive data */
            if (serialByte == ' ')
            {
                /* skip space */
            }
            else if (serialByte == 0x0D)    /* CR */
            {
                serialBuf [serialBufPos] = '\0';
                parseCommandFlag = TRUE;
            }
            else
            {
                if ((serialByte >= 'a') && (serialByte <= 'z'))
                {
                    serialByte -= 0x20;     /* 0x20 = 'a' - 'A' */
                }
                serialBuf [serialBufPos] = serialByte;
                serialBufPos++;
            }
        }
        else if (TI_0 == 1)
            TI_0 = 0;
    }
    
    void serial1_IT(void) interrupt 10
    {
        if (RI_1 == 1)
        {
            RI_1 = 0;
    
            serialByte1 = SBUF_1; /* Read receive data */
            if (serialByte1 == ' ')
            {
                /* skip space */
            }
            else if (serialByte1 == 0x0D)    /* CR */
            {
                serialBuf1[serialBufPos1] = '\0';
                parseCommandFlag1 = TRUE;
            }
            else
            {
                if ((serialByte1 >= 'a') && (serialByte1 <= 'z'))
                {
                    serialByte1 -= 0x20;     /* 0x20 = 'a' - 'A' */
                }
                serialBuf1[serialBufPos1] = serialByte1;
                serialBufPos1++;
            }
        }
    }