0
\$\begingroup\$

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
test59:
  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?
ret

;mini micro issues a 4-bit command to big micro
;then waits for a reply
;Low nibble of accumulator = data to send
uCdat:
  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
ret

;Function takes input as accumulator and prints out "xnn " where n=hex character
;Example. if A=#0ABh, then xAB is printed.
printhex:
  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
  nextnib:
    anl a,#15
    add a,#246
    jnc phexb
    add a,#7
    phexb:
    add a,#58
    lcall cout
    mov A,R7
  jbc NIBNO,nextnib
  mov A,#' '
  lcall cout
ret


;Slave starts with this function
get5send9:
  ;Stall until we receive a 5.
  test1:
    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
  test2:
    lcall miniuCdatout
  jnc test2 ;Stall until data is sent out
  ;All this is processed, but apparently 0Fh is returned to master instead of 09h
ret

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

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.