We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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.
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?
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.
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++; } } }