1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

Sending data on 8051 serial port (asynchronously)

Discussion in '8051/8951' started by mik3ca, Oct 11, 2017.

  1. mik3ca

    mik3ca Member

    Joined:
    Jun 24, 2017
    Messages:
    180
    Likes:
    1
    I am currently using an AT89C4051 microcontroller with a 22.1184Mhz crystal attached to it.

    The following code that someone else posted here is suitable for me if I don't mind synchronous transmitting operation:

    Code (text):

    mov scon,#50h
    mov tmod,#21h
    mov th1,#f4h
    mov tl1,#f4h
    setb tr1

    mov a,#'A'
    mov sbuf,a
    jnb ti,$

    clr ti
     
    Transmission works perfectly, but there is however one problem with it. Every time I send a character, I have to wait as long as it takes for the transmit flag to be set (96 clock cycles I think). The problem is these clock cycles are precious because at any point I could receive data. So at first I wanted to do code like this:

    **note: in the code, cc stands for clock cycles, and trigger is clock input.

    Code (text):

    ;setup serial
    mainloop:
        jnb RI,recv
            ;act on received character and ditch invalid characters (uses 19 cc)
        recv:
    jb trigger,processdata
    ajmp mainloop

    processdata:
        ;shift out result and shift in new data while trigger is toggled (uses 54 cc)
        ;format incoming data to prepare byte to serial and set accumlator to serial data (uses 13 cc)
        CLR TI
        mov SBUF,A
        jnb TI,$
    ajmp mainloop
     
    Now the above may work wonderfully if I didn't care if data reception speed is ultra slow, but I'd like to have 9600bps for both receive and send. So I tried this method:

    Code (text):

    ;setup serial
    setb TI ;serial port ready to transmit
    mainloop:
        jnb RI,recv
            ;act on received character and ditch invalid characters (uses 19 cc)
        recv:
    jb trigger,processdata
    ajmp mainloop

    processdata:
        ;shift out result and shift in new data while trigger is toggled (uses 54 cc)
        ;format incoming data to prepare byte to serial and set accumlator to serial data (uses 13 cc)
        jnb TI,$ ;only stall if data isn't received
        CLR TI ;reset because last byte was received
        mov SBUF,A ;send new data
    ajmp mainloop
     
    The problem is the second method does not work. I tried to make all my functionality work within 96 clock cycles so that the serial operations work but with this last idea, all I was able to do was transmit one and only the first character until I resetted the microcontroller, and then after only the first character could be transmitted again.

    Is there a good way to make this asynchronous? Now I did try the interrupt route in the past with bad luck.
     

Share This Page