Since I have 10 I/O lines connected between two microcontrollers (AT89C4051 + AT89S52), I am trying to get away with elegant data transfer. Instead of spending months redoing an entire circuit board, I'm trying to divide the 8-bit port into two nibbles so I can achieve bi-directional data transfer as well as being able to skip the step of tristating and waiting.

Except somewhere in my code, something is wrong. I managed to transmit the data from the master to the slave and the data is recognized, but when the slave returns its data back to the master, the value returned is incorrect. In this example, the master is supposed to send the value 5 to the slave, and then the slave is supposed to respond back with the value 9, but instead the slave returns the value of 15 (0Fh). I know this because I used the hexadecimal routine (included in the code snippet) that converts the returned value to hex.

I feel there is something obviously wrong in my code but my brain is fried. What can I do to make this code work?

;Port is organized as: rrrrssss where:
;r= 4-bit data received from master
;s= 4-bit data sent to master

;Master begins with this function
  mov A,#05h ;set output to 5
  lcall uCdat ;process
  lcall printhex ;print result to screen in hex
  ;Expecting A=09h, but always getting A=0Fh. why?

;mini micro issues a 4-bit command to big micro
;then waits for a reply
;Low nibble of accumulator = data to send
  orl A,#0F0h ;Make high nibble tristate
  mov D,A     ;Send XXXXdata to port
  clr ACT     ;Tell remote were ready
  jb ACK,$    ;Wait till remote is done
  mov A,D     ;Get data
  anl A,#0F0h ;High nibble is output
  swap A      ;Make it low nibble
  setb ACT    ;Tell remote were ready
  jnb ACK,$   ;Wait till remote is done

;Function takes input as accumulator and prints out "xnn " where n=hex character
;Example. if A=#0ABh, then xAB is printed.
  setb NIBNO
  mov R7,A
  mov A,#'x'
  lcall cout ;each call to cout prints a digit on serial line
  mov A,R7/swap A
    anl a,#15
    add a,#246
    jnc phexb
    add a,#7
    add a,#58
    lcall cout
    mov A,R7
  jbc NIBNO,nextnib
  mov A,#' '
  lcall cout

;Slave starts with this function
  ;Stall until we receive a 5.
    lcall miniuCdatin
    jc test1 ;if C=0, then remote lowered ACT line and we have data.
  cjne A,#05h,test1 ;Input must be 5 to proceed
  ;Send out 9
  mov A,#09h
    lcall miniuCdatout
  jnc test2 ;Stall until data is sent out
  ;All this is processed, but apparently 0Fh is returned to master instead of 09h

;Slave calls to get data from master
  mov C,ACT ;Check action
  jc noUdat
    mov A,D    ;receive XXXXdata from port
    anl A,#0Fh ;get request into low nibble
  mov ACK,C ;Acknowledgement = Request state

;Big slave then processes data then calls this to give result.
  mov C,ACT
  jnc noUdat2
    swap A     ;make output high nibble
    orl A,#0Fh ;Tristate lower nibble
    mov D,A    ;send dataXXXX to port
  mov ACK,C

1 Answer 1


In miniuCdatout you are setting D only after ACT is set high. So your master reads the default value that is 0FH.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.