Connect with us

Using Interrupt driven serial Port on 8051

Discussion in 'Misc Electronics' started by Makhan, Aug 8, 2004.

Scroll to continue with content
  1. Makhan

    Makhan Guest

    Hello all,

    I have a very typical problem with a twist. Here goes:

    I have a main loop running a piece of code. However, upon receiving
    character '0' from serial port (or any 8bit code for that matter), I
    want to read 8 or 16 or lets say n number of bytes from serial port.

    So here is what I did, I created an updateFlag bit which gets set
    whenver the true code is reached and the ISR quits. Whenever in the
    main loop I reach the place for checking updateFlag, I deactivate the
    ISR for Serial Port and assuming that now the serial port will act
    just as normal, I run a debug code of reading a byte and outing it.
    Only the serial port interrupt flag remains inactive while I am in
    that function.

    So the ISR goes like:

    ISR_SP:
    JBC TI, QUITY ; if TI caused it, just quit
    MOV A, SBUF ; if '0' = 30 then update the IDATA
    ADD A, #-30H ; else skip the update
    JNZ QUITY
    SETB UpdateFlag
    QUITY:
    RETI ; if TX irq just returns

    and the main loop:

    while (1)
    {
    if (UpdateFlag == 1)
    {
    /*---------------------------- Debug ------------------------*/
    EA = 0;
    choice = GetByte();

    choice++;

    OutByte(choice);

    UpdateFlag = 0;

    EA = 1;
    }

    // Some functions here

    My problem is this that the ISR works fine if I dont involve serial
    port reading writing, that ISR would turn on or off any port correctly
    upon receiving character '0'.

    Similarly the GetByte and OutByte routines work fine as well when
    Serial port is not on interrupt.

    Its only after combining both I end up in problems, can anyone see any
    potential problem in the approach?

    Thanks in advance

    Makhan
     
  2. Ryan Wheeler

    Ryan Wheeler Guest

    thou shallt never disable the interrupt on a recv serial port.
     
  3. Where is the gain? Sit and wait until all those other 15 bytes arrive
    in the serial port? It seems that such approach is only a waste of time.

    Keep a 256 byte ringbuffer, and let your serial interrupt fill it.
    Your main loop compares a pointer/index with the one you use to fill
    the buffer, to check if new characters have arrived. Process those
    characters, and update the main pointer/index.
     
  4. Dan Henry

    Dan Henry Guest

    One problem that has not been mentioned by others (at least in
    c.a.e.), is that your ISR does not save and restore ACC and PSW.

    Oops!
     
  5. CBFalconer

    CBFalconer Guest

    Please don't toppost. Your answer goes after, or possibly
    interleaved with, appropriately snipped quoted material. i.e.
    remove anything not germane to your answer.

    You also need to resolve how to handle buffer overflow on input.
    For interactive use I recommend discarding the oldest char, rather
    than the new char. This allows a manual interrupt such as CTL-C
    to be noticed.
     
  6. Phil Hobbs

    Phil Hobbs Guest

    You also need to serialize access to the buffer pointers, unless there's an
    atomic read-modify-write on an 8051 (which I don't know, being a PIC guy).
    Otherwise once in awhile your mainline code will be interrupted after reading
    the buffer pointer and before updating it--and when the ISR returns, the
    pointer will be overwritten. This sort of thing is a real headache to debug,
    so just follow the rule about not sharing resources between ISRs and mainline
    routines, and serialize the circular buffers used for the interface. That
    will make your programs much less flaky.

    Cheers,

    Phil Hobbs
     
  7. Neil Kurzman

    Neil Kurzman Guest

    256 may be too much for a 8051, But he definitely needs a buffer ring or
    otherwise.
     
  8. I assumed plenty of XDATA ;)
     
  9. Makhan

    Makhan Guest

    Thank you all for the discussion, I am afraid there is more to it than
    I first wrote.

    Actually, there is an array of microcontrollers each doing identical
    job, that is lighting up a multiplexed LED array (of variable
    characters) and the characters to display are configurable ofcourse,
    i.e. user can choose to display any information onto the array(s).
    Each micro corresponds to one row.

    So there we go. I thought of giving an identity (any character 0xA0
    and so on) each, to the microcontrollers for the rows and initially
    the idea was on identity match, update the allocated IDATA space with
    the charcters, else just ignore.

    But can you please comment on the fact that if I go for filing the
    buffers on each serial port interrupt I will end up writing and
    rewriting all the micros with same data?

    Thanks

    Makhan
     
  10. Each and every uC in your setup will receive and generate an interrupt
    for each character. Of course you only want one uC to actually display
    the message, if the first character matches.

    But who cares if each uC stores the entire message in a ringbuffer?
    Your main loop will just ignore messages that don't have that first
    character match. When it sees a character 0x0A or higher, it has
    received a full previous message, and it can check if that is is
    a matching one that needs to be copied to your led display.

    So yes, you end up writing each uC with the same data, but who
    cares?
     
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

-