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.

  • "I heard"

    Where did you hear it?

    Don't rely on hearsay - check it in the Datasheet!

    "for both uarts working, each uart configuration has different baud rate, and different mode, is it correct?"

    It's up to you to configure them how you want to!

    "I tried to make uart work in mode 3, but I failed."

    In what way, precisely, did you "fail"?

    "Could you give me any advice ?? "

    You need to describe the problem properly:

    What, exacly, did you try?
    What were you expecting to happen?
    What actually happened?
    What debugging have you done to account for the difference?

  • thanks for replying.

    first of all, I've already checked the datasheet(AT89C51RE2), and sample uart test codes from atmel web site(http://www.atmel.com).

    what I want is both uarts(uart0, uart1) work at the same time.

    each uart operates very well by itself using different baud rate source(timer1, timer2, internal baud rate generator), and using different baud rate(9,600bps, 19,200bps, 11,5200bps).
    but, if both two uarts(uart0/uart1) operate, it happens that uart1 is dead.
    say again, after power on the board before using uart0, uart1 seems to be working good, but once I using uart0 with hyper-terminal program, uart1 doesn't work any more.

    thank you.

    Here's my codes I used.
    =========== code start =============
    #include <stdio.h>
    #include <string.h>
    #include "at89c51re2_2.h"
    #include "INTRINS.H"

    #define TRUE 1
    #define FALSE 0
    #define BUF_SIZE 100

    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) { SBUF_1 = *sBuf_1++; } 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; T2CON |= 0x30; //RCLK=1(use timer2 as receive clock in serial port mode 1,3), TCLK = 1 (use timer2 as receive clock in mode 1,3) BDRCON_0 |= 0x0C; //RBCK_0 = 1, TBCK_0 = 1, Tx/Rx select internal baud rate generator BDRCON_1 &= 0xF3; //RBCK_1 = 0, TBCK_1 = 0, Tx/Rx select timer1 or timer2 for baud rate generator

    TH2=0xFF; /* init value */ TL2=0xFB; /* init value */ RCAP2H=0xFF; /* reload value, 115200 Bds at 18.432MHz */ RCAP2L=0xFB; /* reload value, 115200 Bds at 18.432MHz */

    /****** UART0 ******/ //use internal Baud Rate Generator SCON_0 = 0x50; /* uart 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;*/ BDRCON_0 |=0x0C; /* TBCK_0=1;RBCK_0=1; SPD_0=0 use Slow internal Baud Rate Generator*/ BRL_0 = 251; /* set 19200, @18.432Mhz (BRL_0=251;SPD_0=1;SMOD1_0=0) */

    /****** UART1 ******/ //CKCON0 = 0x7F; SCON_1 = 0x50; /* uart1 in serial port mode 1 (8 bit), REN_1=1, enable multiprocessor comm */

    IEN1 |= 0x08; /* Enable serial port1 interrupt */ ES = 1; /* Enable serial port0 interrupt */ EA = 1; /* Enable global interrupt */

    BDRCON_0 |=0x10; /* Baud rate generator run*/ TR2 = 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++; } }
    }

    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++; } }
    }

    =========== code end ===============

  • but, if both two uarts(uart0/uart1) operate, it happens that uart1 is dead.
    say again, after power on the board before using uart0, uart1 seems to be working good, but once I using uart0 with hyper-terminal program, uart1 doesn't work any more.

    nothing to do with UART mode
    if you follow the direction above "Place source code source code between ....." that is properly formatted and commented it is likely that someone will point you in the right direction.

    Erik

  • " I've already checked the datasheet(AT89C51RE2), and sample uart test codes from atmel web site"

    Well, if you checked them as carefully as you studied the instructions on how to post source code on this forum, and as carefully as you checked your post in the Preview, it wouldn't be surprising that you missed a load of important details!

    See: www.danlhenry.com/.../keil_code.png

    Correctly-posted source code should look something like this:

    void print_Uart0(char *sBuf_0)
    {
       while( *sBuf_0 != NULL)
       {
          SBUF_0 = *sBuf_0++;
       }
       SBUF_0 = 0x0D;
    }
    


    and the problem should be obvious...

    If it's not obvious to 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...?

  • thank you for replying.

    This is first time for me to use this forum, and I might be impatient to solve my problem.
    I missed the tips for posting messages, sorry :-)

    I leave my codes again.
    ===================================================

    #include <stdio.h>
    #include <string.h>
    #include "at89c51re2_2.h"
    #include "INTRINS.H"
    
    #define TRUE                            1
    #define FALSE                           0
    #define BUF_SIZE                                                100
    
    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)
        {
            SBUF_1 = *sBuf_1++;
        }
        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;
        T2CON |= 0x30; //RCLK=1, TCLK = 1
    
        BDRCON_0 |= 0x0C; //RBCK_0 = 1, TBCK_0 = 1,
        BDRCON_1 &= 0xF3; //RBCK_1 = 0, TBCK_1 = 0,
    
        TH2=0xFF; /* init value */
        TL2=0xFB; /* init value */
        RCAP2H=0xFF; /* reload value, 115200 Bds at 18.432MHz */
        RCAP2L=0xFB; /* reload value, 115200 Bds at 18.432MHz */
    
        /****** UART0 ******/
        //use internal Baud Rate Generator
        SCON_0 = 0x50;    /* uart 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;*/
        BDRCON_0 |=0x0C;  /* TBCK_0=1;RBCK_0=1; SPD_0=0 */
        BRL_0 = 251;      /* set 19200, @18.432Mhz */
    
        /****** UART1 ******/
        SCON_1 = 0x50;         /* uart1 in serial port mode 1 (8 bit), REN_1=1, */
    
        IEN1 |= 0x08;    /* Enable serial port1 interrupt   */
        ES = 1;          /* Enable serial port0 interrupt   */
        EA = 1;          /* Enable global interrupt */
    
        BDRCON_0 |=0x10; /* Baud rate generator run*/
        TR2 = 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++;
            }
        }
    }
    
    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++;
            }
        }
    }
    
    


    ===================================================

  • if you want the two UARTs to work concurrently they must be interrupt driven

    Erik

  • 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++;
            }
        }
    }