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