代码在两个微控制器之间进行通信

时间:2016-11-09 20:33:50

标签: assembly io spi 8051

我试图实现类似于SPI(串行编程接口)的功能,以便在两个迷你微控制器(芯片#AT89c2051)之间进行通信。由于每个微控制器已经将板载串行端口用于其他目的,因此我作为通信线路可用的总数为10位。 8个是地址位,另外两个是控制位。由于晶体价格和与计算机的兼容性,每个微控制器以不同的速度(18.432Mhz和20Mhz)运行。

我的代码可以部分工作但不正确。

以下是整个程序中使用的常量:

NUMBYTESIO EQU 10h ;set transfer bytes to 16
TEMP EQU 30h ;temporary pointer for register saves
DATAPTR EQU 31h ;data pointer for commands
RINT EQU P3.2 ;INTerrupt to tell slave that master is ready
RACK EQU P3.3 ;Remote busy INTerrupt to tell master that slave is busy 

这是在向主服务器发出请求时以18.432Mhz速度在主服务器上执行的代码:

request: ;start request from slow microcontroller
  mov R0,#DATAPTR ;set R0 to data pointer (address 30h)
  mov R7,#0h ;clear counter register
  dorequest:
mov P1,@R0   ;read local register data from memory location and store in the outgoing 8 bits
clr RINT     ;clear request interrupt to let remote know data is ready
jb RACK,$    ;wait till remote acknowledges data
mov P1,#0FFh ;set data line high to enable remote to send data
setb RINT    ;set request interrupt to let remote know we're ready for data
jnb RACK,$   ;wait till remote understands were ready
mov @R0,P1   ;overwrite memory location with new data
inc R0       ;advance memory location pointer
inc R7       ;add 1 to # of bytes processed
  cjne R7,#NUMBYTESIO,dorequest ;if # bytes processed < 16, repeat process
ret         ;end the request

这是奴隶处理来自主服务器的请求的方式,但最后一行是reti而不是ret,因为remotereq是从主服务器触发的中断处理程序中调用的:

remotereq: ;fast micro received request from slow micro and RINT is low
  mov P1,#0FFh ;sanity check: make data line high to let remote send data
  ;next 5 lines save R1...R7 registers onto stack
  mov TEMP,#7h 
  saveb: 
  push TEMP
  dec TEMP
  jnz saveb
  mov R7,#0h
  rrr:          ;start reception of request
mov P1,#0FFh    ;make data line high
jb RINT,$           ;wait until remote has data (it will set this line low)
mov A,P1            ;get the data
clr RACK            ;and send an acknowledgement to remote
jnb RINT,$      ;wait until remote is ready for data
lcall doradcmds     ;process byte
mov P1,A            ;take result of the byte as data to send back
setb RACK           ;send acknowledgement to remote to let it know data is ready
mov R6,#0FFh ;start data timeout of 255 clock cycles (about 100-ish microseconds)
djnz R6,$
inc R7 ;increment counter
  cjne R7,#NUMBYTESIO,rrr ;repeat process for all remaining bytes
  mov P1,#0FFh ;set data line high to avoid contention
  mov TEMP,#7h
  saveb2:
  pop TEMP
  dec TEMP
  jnz saveb2
reti

这是奴隶执行所有命令处理的地方:

;PROC COMMANDS
; R7=LIVE byte#, A=live data, R6=bad

doradcmds:
  cjne R7,#0h,majorcmd ;see if byte # is the first
mov R2,A ;byte is first. store command in R2
mov A,#40h ;returned result starts with @
ret
  majorcmd:
  mov TEMP,R7 ;copy current byte #...
  mov R3,TEMP ;... into R3
  cjne R2,#A5h,notest ;run test command if 1st byte is A5h
djnz R3,notestp1
  mov R5,A    ;store first command parameter into R5
  mov A,#40h  ;return an @ in result
  ret
notestp1:
djnz R3,notestp2
  mov R4,A    ;store second parameter into R4
  mov A,#40h  ;return an @ in result (not working)
  ret
notestp2:
djnz R3,notesto1
  mov A,R4 ;return value of R4 for 3rd byte 
  ret
notesto1:
djnz R3,notesto2
  mov A,R5 ;return value of R5 for 4th byte 
  ret
notesto2:
  notest:
ret

这就是主人如何调用请求(前端代码):

mov DATAPTR,#A5h
mov DATAPTR+1,#43h ;C
mov DATAPTR+2,#41h ;A
mov DATAPTR+3,#44h ;D
mov DATAPTR+4,#42h ;B
mov DATAPTR+5,#46h ;F
mov DATAPTR+6,#45h ;E
lcall request

这就是主人检索结果的方式:

mov A,DATAPTR
lcall outserbyte
mov A,DATAPTR+1
lcall outserbyte
mov A,DATAPTR+2
lcall outserbyte
mov A,DATAPTR+3
lcall outserbyte
mov A,DATAPTR+4
lcall outserbyte
mov A,DATAPTR+5
lcall outserbyte
mov A,DATAPTR+6
lcall outserbyte

串口字节功能很简单:

outserbyte:
  clr TI
  mov SBUF,A
  jnb TI,$
ret

基本上,我发送给奴隶的数据是:

A5h, 'C', 'A', 'D', 'B', 'F', and 'E'. where A5h is a hexadecimal value.

我收到的数据是:

'@', '@', 'A', 'D', 'B', 'F' and 'E'.

操作速度可以接受,但返回的数据不正确。我期望作为我的命令返回的数据是交换字节函数是这样的:

'@', '@', '@', 'A', 'C', 'F' and 'E'.

但我只关心前5个字节,特别是第4个和第5个字节。 有没有办法可以修复我的代码以返回正确的数据?

0 个答案:

没有答案