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.
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
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
View all questions in Keil forum