About P89LPC934 ISP/RxD issue !

Started by Jeffrey Chang, September 06, 2004, 12:24:28 AM

Previous topic - Next topic

Jeffrey Chang

I developed P89LPC934 ADC program in Break detection approach
successfully. But it does NOT work anymore while I removed the
ISP kit. After investigating the issue, I found it needs a HIGH at RxD pin.
Why ? How to fix it ?

/* -------------------------------------------------------------------
    Name: UART_Init -
    Purpose: To initialize UART module.
    Passed: None.
    Returns: None.
    Notes:
   ------------------------------------------------------------------- */
void UART_Init (void)
{
    /* ::::::::::::::::::::::::::::::::::::
        Configure UART
       :::::::::::::::::::::::::::::::::::: */

    // [2]34 Framing Error location
    // clear SMOD0
    PCON &= ~0x40;                  // bit 7 of SCON is accessed as SM0 for the UART

    // Serial Port Control register
    // Mode 1: 10 bits are transmitted: A start bit (0),
    // 8 data bits (LSB first), and a stop bit (1).
    // [2]60 Mode 1: 8-bit UART
    SCON = 0x50;

    // [2]34 Framing Error location
    // set or clear SMOD1
    PCON &= 0x7F;
    PCON |= (0 << 8);

    // [2]61
    SSTAT = 0x00;

    // [2]103
    // enable break detect
    AUXR1 |= 0x40;                  // UART Break Detect Reset Enable

    /* ::::::::::::::::::::::::::::::::::::
        [2]59 Configure baud rate generator
        Baudrate = CCLK / ((BRGR1, BRGR0) + 16)
        = CCLK / (0x2F0 + 0x10) = CCLK / 0x300 = 7.3728 MHz / 768 = 9600

        Baudrate = CCLK / ((BRGR1, BRGR0) + 16)

        ((BRGR1, BRGR0) + 16) = CCLK / Baudrate
        (BRGR1, BRGR0) = CCLK / Baudrate - 16

        1) Baudrate = 9600
           (BRGR1, BRGR0) = CCLK / Baudrate - 16
                          = 7.3728 MHz / 9600 - 16 = 0x02F0

        2) Baudrate = 19200
           (BRGR1, BRGR0) = CCLK / Baudrate - 16
                          = 7.3728 MHz / 19200 - 16 = 0x0170

        3) Baudrate = 38400
           (BRGR1, BRGR0) = CCLK / Baudrate - 16
                          = 7.3728 MHz / 38400 - 16 = 0x00B0

        4) Baudrate = 57600
           (BRGR1, BRGR0) = CCLK / Baudrate - 16
                          = 7.3728 MHz / 57600 - 16 = 0x0070

        5) Baudrate = 115200
           (BRGR1, BRGR0) = CCLK / Baudrate - 16
                          = 7.3728 MHz / 115200 - 16 = 0x0030

       :::::::::::::::::::::::::::::::::::: */
    BRGCON  = 0x00;

    #if (UART_BAUD == BAUD9600)
    // 9600 Baud
    BRGR0   = 0xF0;
    BRGR1   = 0x02;
    #elif (UART_BAUD == BAUD19200)
    // 19200 Baud
    BRGR0   = 0x70;
    BRGR1   = 0x01;
    #endif

    BRGCON  = 0x03;         // SBRGS = 1

    // [2]28
    // PxM1.y   PxM2.y
    //  0       0       Quasi-bidirectional
    //  0       1       Push-Pull
    //  1       0       Input Only (High Impedance)
    //  1       1       Open Drain
    // TxD = P1.0   Push-Pull
    // RxD = P1.1   Input
    // P1M1     x x x x x x 1 0
    // P1M2     x x x x x x 0 1
    P1M1 &= 0xFE;               // For TxD = P1.0   Push-Pull   (M1=0, M2=1)
    P1M2 |= 0x01;
    P1M1 |= 0x02;               // For RxD = P1.1   Input       (M1=1, M2=0)
    P1M2 &= 0xFD;

    // set isr priority to 0
    IP0     &= 0xEF;
    IP0H    &= 0xEF;

    // enable uart interrupt
    ES = 1;
} /* UART_Init */


/* -------------------------------------------------------------------
    Name: UART_ISR -
    Purpose: Serial Port Interrupt Service Routine (ISR).
    Passed: None
    Returns: None.
    Notes:
    Reference: [2]19
   ------------------------------------------------------------------- */
void UART_ISR (void) interrupt UART_INT     /* Serial Port */
{
    /* /// Rx /// */
    if (RI)
    {
        // clear interrupt flag
        RI = 0;
    } // if

    if (TI)
    {
        // clear interrupt flag
        TI = 0;
    } // if
} /* UART_ISR */

Andy Ayre

A low for more than two character periods is a break condition. Pulling RxD high will ensure the device is not receiving a break condition. Normally RS232 transievers handle this for you, so I would double-check your connections.

Embedded Systems Academy, Inc.
support at esacademy dot com

Jeffrey Chang

I can NOT keep LPC934 RxD pin floating. Why ?

erikm

>>I can NOT keep LPC934 RxD pin floating. Why ?<<

Because you have jumped into this without doing your homework.

first get familiar with "the bible"
then the chip datasheet and user manual

Erik

here are the links to "the bible"
Chapter 1
http://www.semiconductors.philips.com/acrobat/various/80C51_FAM_ARCH_1.pdf

chapter 2
http://www.semiconductors.philips.com/acrobat/various/80C51_FAM_PROG_GUIDE_1.pdf  
 

chapter 3
http://www.semiconductors.philips.com/acrobat/various/80C51_FAM_HARDWARE_1.pdf

Jeffrey Chang

Do you mean the floating RxD pin results in a break condition ?

Andy Ayre

Embedded Systems Academy, Inc.
support at esacademy dot com

Jeffrey Chang

Hi Andy,
Can I find the *break condition* answer from the 8051 bible ?
As I know, the break condition is NOT a standard 8051 feature. Right ?
Why does the floating RxD pin result in *break condition* of LPC934 ?

Andy Ayre

No, break conditions are not standard. As far as I know, a break condition is holding the pin low for more than two character transmission times at whatever the current baud rate is.

Embedded Systems Academy, Inc.
support at esacademy dot com

erikm

>>Can I find the *break condition* answer from the 8051 bible ?<<

No, but you can find how to hold Rx low to generate a break condition

Erik

Graham

Hello Jeffrey, et al,

The high impedance input mode that  the LPC9xx family has is not standard 8051 and designers have to take this into account. The original 8051 was always quasi and therefore would naturally assume a valid input level if left alone.

As you would expect any input that is allowed to float will take whatever voltage level it can dependent upon induced voltages from stray electric fields (capacitively coupled from mains or static sources).

From the previous discusions you are aware that a UART will interpret a Rxd = low as a break detect. As you cannot know what the voltage level on the Rxd pin will be, it is quite probable that it could be low long enough to trip the break detection.

The simple solution is to define the Rxd mode as quasi so that the internal pullup will take it high. Alternatively you could use a resistor.

Graham
support at acqura dot com