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

no uart output

Hi, I'm using the C51 compiler and running the SIO sample projects with an AT89s52 atmel microcontroller. The code compiles fine and I've run various simple I/O and timer programs successfully. When I tried to generate my own program that integarate pieces from various projects I found that I don't get any serial data out of the TX pin when using the code from the SIO and SIO2 examples.

I then tried only using the example projects and I don't get any output from those samples either. I'm viewing the output with a scope and I don't see any changes on the I/O line. The pin is floating so there isn't any possibility of some external circuit affecting the output. The datasheet states that Port3 has internal pullups so I don't expect I need any type of interface components to simply see the serial data.

Any idea what might be inhibiting the output? I'm new with the 8051 controllers so I expect its a simply problem.

I'm using a 12Mhz crystal with my hardware. Any suggestions would be appreciated.

-- Dan

  • The stock SIO.zip example results in the same results as my code, that's why I didn't post it. The only change I made was to change the include to:

    #include <REGX52.h>

    I did make some progress though, I found that if I commented out the enabling of the serial interrupts, ES=1, and also commented out the overloaded putchar function the code would execute TX's ok.

    I'm guessing that the problem might be a result of floating both the RX and TX lines.

    I can post my code if anyone is interested in reviewing it.

    -- dan

  • I'm guessing that the problem might be a result of floating both the RX and TX lines.
    if you do not plant you get weeds. If you float you get noise.

    Erik

  • So I've made some progress. I am now able to get correctly formatted serial data out of the 8051 at the desired 2400 baud. The problem is that I'd like to be able to get the interrupt based comms working like the intsio project claims it should. I am pasting the modified project below with comments added to describe what was needed to be done to get output from the uart.

    First and foremost, I had to disable serial interrupts. With the interrupts enabled the code hung without any serial data out.

    I then had to comment out the overloaded putchar function.

    I also had to move the instructions for configuring the uart into the baud rate calculator function.

    finally, I had to set the TI (transmit interrupt) to a 1.

    After all of those conditions were met, the uart would output serial data correctly. ANY deviation of the above changes resulted in no data output.

    Any advice or things to try to get the sample code working? I have the RXD and TXD lines connected to a rs-232 tranceiver so they are no longer floating and that made no difference.

    The only changes I made to main was to comment out the putchar function and change the baudrate to 2400. The forum is quite limited and won't let me post the entire sio.c file so I cut it down to simply the functions I edited.

    void com_initialize (void)
    {
    /*------------------------------------------------
    Setup TIMER1 to generate the proper baud rate.
    ------------------------------------------------*/
    com_baudrate (1200);
    
    /*------------------------------------------------
    Clear com buffer indexes.
    ------------------------------------------------*/
    EA = 0;                         /* Disable Interrupts */
    
    t_in = 0;
    t_out = 0;
    t_disabled = 1;
    
    r_in = 0;
    r_out = 0;
    
    /*------------------------------------------------
    Setup serial port registers.
    ------------------------------------------------*/
    SM0 = 0; SM1 = 1;               /* serial port MODE 1 */
    SM2 = 0;
    REN = 1;                        /* enable serial receiver */
    
    TI = 1;                         /* clear transmit interrupt, must set or hang */
    RI = 0;                         /* clear receiver interrupt */
    
    //ES = 1;                               /* enable serial interrupts, dan commented out or hang */
    PS = 0;                         /* set serial interrupts to low priority */
    
    EA = 1;                         /* Enable Interrupts */
    }
    
    /*------------------------------------------------------------------------------
    ------------------------------------------------------------------------------*/
    void com_baudrate (
      unsigned baudrate)
    {
    EA = 0;                             /* Disable Interrupts */
    
    /*------------------------------------------------
    Clear transmit interrupt and buffer.
    ------------------------------------------------*/
    TI = 0;                             /* clear transmit interrupt */
    t_in = 0;                           /* empty transmit buffer */
    t_out = 0;
    t_disabled = 1;                     /* disable transmitter */
    
    /*------------------------------------------------
    Set timer 1 up as a baud rate generator.
    ------------------------------------------------*/
    TR1 = 0;                            /* stop timer 1 */
    ET1 = 0;                            /* disable timer 1 interrupt */
    
    PCON |= 0x80;                       /* 0x80=SMOD: set serial baudrate doubler */
    
    TMOD &= ~0xF0;                          /* clear timer 1 mode bits */
    TMOD |= 0x20;                       /* put timer 1 into MODE 2 */
    
    TH1 = (unsigned char) (256 - (XTAL / (16L * 12L * baudrate)));
    
    TR1 = 1;                            /* start timer 1 */
    
    ////////////////////////////////////////////////////////////////////////////////
    //had to move init here or hang - dan
    SM0 = 0; SM1 = 1;               /* serial port MODE 1 */
    SM2 = 0;
    REN = 1;                        /* enable serial receiver */
    
    TI = 1;                         /* clear transmit interrupt, must set or hang */
    RI = 0;                         /* clear receiver interrupt */
    
    //ES = 1;                               /* enable serial interrupts, dan commented or hang */
    ///////////////////////////////////////////////////////////////////////////////////
    
    
    
    EA = 1;                             /* Enable Interrupts */
    }
    
    

    -- dan

  • i manually set the bits of SCON with:

    SM0 = 0; SM1 = 1; /* serial port MODE 1 */
    SM2 = 0;
    REN = 1; /* enable serial receiver */

    TI = 1; /* clear transmit interrupt, must set or hang */
    RI = 0; /* clear receiver interrupt */

    The really odd behavior is when I enable the serial interrupt, all of my i/o pins flicker. I have some I/O tied to LEDs for status and when the interrupt is enabled they are dimly lit and no serial output is generated. If I make the changes listed the serial output works but obviously not interrupt driven. I don't understand what's happening, it lools like the code example should work

    thanks,

    --dan

  • If all pins flasehs, I get the feeling that your processor is constantly restarting. Maybe watchdog. Maybe too high power consumption because of shorted output pins. Maybe some issue with the stack.

  • This only occurs when the serial interrupt is enabled. Otherwise everything else, including I/O and current consumption are normal.

    I agree it sounds like it's resetting but don't know why? I'm using the example from Keil, I figured these examples work.

    All I changed was the crystal frequency and the baud rate. The other changes noted in previous threads were to get the serial output to actually occur.

    -- dan

  • in sio.c, pasted below:

    static void com_isr (void) interrupt 4 using 2
    {
    /*------------------------------------------------
    Received data interrupt.
    ------------------------------------------------*/
    if (RI != 0)
      {
      RI = 0;
    
      if ((r_in + 1) != r_out)
        rbuf [r_in++] = SBUF;
      }
    
    /*------------------------------------------------
    Transmitted data interrupt.
    ------------------------------------------------*/
    if (TI != 0)
      {
      TI = 0;
    
      if (t_in != t_out)
        SBUF = tbuf [t_out++];
      else
        t_disabled = 1;
      }
    
    }
    

  • the only action to these variables in your shown code (you hid the ISR are you hiding more) is twice

    t_in = 0;
    t_out = 0;
    

    in sio.c (whereever you got it, whatever it is) you find

      if (t_in != t_out)
        SBUF = tbuf [t_out++];
    

    since t_in != t_out never is true, you will, of course, not get any output

    Erik

  • There are more issues.

    The code does a t_out++.

    No turn-around when it reaches the end of the buffer, or modulo operation in case the index is allowed to run the full length of the data type (I'm assuming an unsigned data type).

    There is nothing wrong with good, honest, debugging. Anyone who does spend time with code, setting breakpoints, single-stepping and looking at the code, will quickly notice when things starts to deviate from what was planned.

    And the really good thing here is the availability of a simulator. So it is way easier to debug than when running on real, live, hardware where all stimuli are arriving at full speed even when the processor is stopped at a breakpoint.

  • As I said before, the forum doesn't let me post the entire code so no I'm not HIDING anything. Also as I mentioned, this is not my code but a Keil example that apparently doesn't work. I am new to Keil and the 8051 so I was hoping to have a working example to evaluate. I am quite capable of debugging my own code, I simply thought someone here had run through the example code and could point out why an example provided by KEIL might not be working.

    I'll evaluate some other compiler since Keil can't provide working examples so I can only imagine how good the compiler itself is.

    I'm done here

    -- dan

  • The five your old tantrum.

    This forum isn't handled by Keil support staff but other Keil users.

    So why are we here? Most probably because we have not found the Keil compilers to be lousy...

  • in your first post The code compiles fine and I've run various simple I/O and timer programs successfully

    now suddenly but a Keil example that apparently doesn't work

    could it possibly - I know the chance is infitessimally small - be your fault in When I tried to generate my own program that integarate pieces from various projects I found that I don't get any serial data out of the TX pin when using the code from the SIO and SIO2 examples.

    Erik