Connect with us

8051,not able to receive from serial port.......Plz Help,,,,

Discussion in 'Electronic Design' started by [email protected], Mar 22, 2007.

Scroll to continue with content
  1. Guest

    hi ;

    This is sulabh,i am programming my controller 89s52, for
    recieving and trasmitting from serial port .I m using embedded C in
    keil UV2.

    It is trasmitting properly but while reception it is not
    raising the RI flag...(i suspect) ,
    in main loop of my programme i m checking for :
    if(trigger==1) // Externel input for trigger

    if(RI==1 )


    In main programme i m giving


    In DEbugger window it is working fine,in hardware it is showing (ON
    Osciloscop)that whenever i m giving trigger it is transmitting through
    pin 11, by the same time i m receiving the txmitted stream in another
    89s52 and on that Rx pin it is showing that same data has reached to
    89s52(second), but it is not receiving and not going in rx_char()

    I am stuck here Plz help....


  2. mpm

    mpm Guest

    raising the RI flag...(i suspect)

    Hi Sulabh,
    Not familiar with your chip, but here's a couple ideas to check:
    I assume your serial routines are polled, and not interrupt driven

    In either case:
    The RI interrupt flag might need to be cleared manually after each
    character. I would start there.
    Simply fetching the character from the receive buffer may not clear
    this flag, and then all subsequent received characters get "stuck",
    and eventually get overwritten in the buffer.

    Next (but not as likely to be the problem?), on the Dallas Semi
    DS87C530 chip for example, there is a bit tucked away in one of the
    Special Function Registers (SRF) to enable reception on the serial
    port - though there is no corresponding bit for transmit.

    I think I spent an entire day chasing that one!

    Anyway, like I said, I don't recall the Atmel chips having Serial
    Receive Enables tucked away like that, but it might be worth a look in
    the Datasheet? Good luck.

  3. Did you clear RI before you start the receiver? It's not enough to clear it
    in the main program. You have to make sure it is cleared before you start
    receiving and you have to clear it again after reading SBUF.

    petrus bitbyter
  4. Eeyore

    Eeyore Guest

    Of course reading should be interrupt driven.

    For transmit you have to wait for TI to clear or somesuch. And then there's the
    issue of setting up a timer for the baud rate too.

  5. Well, RI is the receive interrupt flag. But as the OP is apparently just a
    beginner, I guess the first attempt using polling is good enough for a

    petrus bitbyter
  6. Eeyore

    Eeyore Guest

    Sounds like a recipe for creating bad habits actually. I've seen that kind of
    thing done too often by programmers who have no real excuse. They look kind off
    oddly at you when you tell them that interrupts aren't done by of polling.

  7. Paul Burke

    Paul Burke Guest

    Depends entirely on what you are doing. In many applications, you KNOW
    the character poll loop is faster than the data rate, you are looking
    for a fixed format message with a known delimiter, nothing happens until
    you get that message, and no other valid message can arrive before you
    have actioned it. So why bother with interrupts?

    Paul Burke
  8. MooseFET

    MooseFET Guest

    Also, the 8051 has only two levels of interrupt priority. If you have
    other things happening with timing requirements that demand the
    interrupts be used for them, you are sort of stuck as far as the

    BTW: a cute trick is to call a RETI instruction to go back normal
    without leaving the code that processes the input event. You can make
    it appear that you have an extra level of priority this way. Just
    remember to prevent more of the smae interrupt.
  9. Eeyore

    Eeyore Guest

    True of 'original' 8051s. More modern ones such as from Philips oops NXP (and
    Atmel too ?) have 4 levels.

    Can you explain how that works ?

  10. Eeyore

    Eeyore Guest

    It would be a whole load more useful if you stated those values in binary !

    Here's a snippet of code from an ancient project of mine btw. Oops I didn't use
    binary in this case myself !

    TR1 = 0;
    ET1 = 0;
    TMOD = TMOD AND 00001111B;
    TMOD = TMOD OR 20H;
    TF1 = 1;
    IE1 = 0;
    SCON = 0CAH;
    TH1 = 0F3H;
    TL1 = 0FFH;
    TR1 = 1;

    ????? 2400 baud N,8,1 ????? with 12MHz crystal (I should have commented that)

    co:procedure(char); /* single character output */
    dcl char byte;
    do while (not(TI)); /* wait for TI to be set by hardware */
    TI = 0; /* now clear TI */
    SBUF = char;
    end co;

    Trsnamission is initiated by any instruction that uses
    SBUF as a destination register. The “write to SBUF’
    signal at S6P2 also loads a 1 into the 9th position of the
    transmit shift register and tells the TX Control block to
    commence a transmission.The internal timing is such
    that one full machine cycle will elapse between“write
    to SBUF,”and activation of SEND.

    SEND enables the output of the shift register to the
    alternate output function line of P3.0, and also enables
    SHIFT CLOCKto the alternate output function line of
    P3.1. SHIFT CLOCK is low during S3, S4, and S5 of
    every machine cycle, and high during S6, S1and S2.At
    S6P2 of every machinecycle in which SEND is active,
    the contents of the transmit shift register are shifted to
    the right one position.

    As data bits shift out to the right, zeroes come in from
    the left. When the MSBof the data byte is at the output
    position of the shift register, then the 1 that was initially
    loaded into the 9th position, is just to the left of the
    MSB, and all positions to the left of that contain zeroes
    This condition flags the TX Control block to do one
    last shift and then deactivate SEND and set TI.

    (from Intel's 8051 family manual)

  11. mpm

    mpm Guest

    This makes my head hurt.
    Sounds cool, though. :)

  12. MooseFET

    MooseFET Guest

    Do you have any idea how hard it is for me to resist saying "Yes." or
    "Very well" as the answer to this.

    Assume code like this:

    push this ; Save the outer context
    push that
    push theother

    lcall TheReti ; Reset the interrupt hardware

    mov A,BCD ; Do stuff 1
    mov DEF,GHI ; DO stuff 2

    pop theother
    pop that
    pop this

    When IntVector1 is hit, the stack has the address of the interrupted
    context on it just like there was a call instruction.

    When the RETI gets called, the call instruction pushes the address for
    the "Do stuff 1" onto the stack. When the RETI instruction is done,
    this is the place we will return to.

    If a different interrupt happens between "Do stuff 1" and "Do stuff
    2", the interrupt will be serviced and then "Do stuff 2" will happen.

    When we wnat to return to the main context, we need just to pop the
    registers and do a normal return.

    If you want to get a little extra cute, you can make it so that this
    same interrupt can happen again. This involves adding a flag that the
    interrupt code sets and clears and tests or some counters or the
    like. This is good where only one out of many passes through the
    interrupt code takes long enough that you may miss one.
Ask a Question
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Electronics Point Logo
Continue to site
Quote of the day