在1ms内执行SPI命令 - 8051

时间:2018-04-09 00:39:04

标签: microcontroller boolean-logic bits spi 8051

目前我有一个AT89C2051微控制器通过多路复用器 - 多路分解器设置连接到ISD声卡。我还有其他的东西,但我的重点是尽可能快地执行声音。目前,由于另一个微控制器正在驱动这个微控制器,因此芯片的速度为3.6Mhz。

基于文档和实验,声音芯片需要发送7个字节才能让它在任何两个内存范围之间播放声音。花费时间的部分是传输七个字节。

这是我到目前为止的代码:

  FLUSH bit P3.7            ;Low=enable data reception
  ENXMIT bit P3.5           ;High=Enable data transmission
  GLOBALCLK bit P3.1        ;TXD: clock (connects to soundcard clock)
  GLOBALDAT bit P3.0        ;RXD: I/O data line (connects to MISO and MOSI)

  C_SND2 = address of soundcard 2
  C_SND = address of soundcard 1

  O_SND:
      setb FLUSH            ;disable reception
      clr ENXMIT            ;disable transmission
      mov R7,A              ;Parameter in: Accumulator = # bytes to transfer out. 
      mov A,#C_SND2         ;A=address of soundcard 2
      mov R6,#C_SND         ;R6=address of soundcard 1
      jnb SS,nc1            ;Parameter in: SS = soundcard to use.
          xch A,R6          ;Switch A + R6 if other soundcard is wanted.
      nc1:
                          ;NOTE: soundcard Slave select lines are connected together through an inverter.
      mov P1,R6            ;Enable wrong soundcard (to disable the correct one)
      mov R0,#BUFOUT       ;Set data space pointer
      mov P1,A             ;Now enable only the correct soundcard
      setb ENXMIT          ;Enable data transmission
      tx2:
              mov A,@R0         ;Load a byte from our data space

              ;This fragment executes 8x but I only showed it one time here.
              ;I avoided loops. DJNZ requires two clock cycles (7uS) to process command.

              clr FLUSH                ;Enable data input **
              setb GLOBALDAT           ;Set data to high impedance so input can be captured **
              clr GLOBALCLK            ;Lower clock line to accept bit input **
              mov C,GLOBALDAT          ;Get incoming bit
              setb FLUSH               ;Disable data input
              rrc A                    ;store incoming bit and load next output bit
              mov GLOBALDAT,C          ;set data line to bit
              setb GLOBALCLK           ;raise clock so soundcard accepts bit

              ;end of repeating fragment

              mov @R0,A                ;save what soundcard sent us to our data space
              inc R0                   ;increment pointer

        djnz R7,tx2                    ;Keep going until all bytes are processed

        clr ENXMIT                     ;Disable further transmissions    
        setb GLOBALDAT                 ;Set data line to high
        mov P1,R6                      ;reset the SS line to tell soundcard we're done.

        ;Save audio statuses to RAM
        mov AUDSTATL,BUFOUT
        mov AUDSTAT,BUFOUT+2
  ret

如您所见,微控制器的数据线(RXD)通过多路复用器/多路分解器在系统中的每条数据线上共享。这意味着我需要通过启用接收来使线路单向(不是双向),并且当我想要接收数据时不发送任何信息。

我打电话给接收启用" FLUSH"因为它还会刷新超出此问题范围的其他输出行。

现在我想要做的是让这段代码片段执行得更快。

所以我正在看这些内容:

              clr FLUSH                ;Enable data input **
              setb GLOBALDAT           ;Set data to high impedance so input can be captured **
              clr GLOBALCLK            ;Lower clock line to accept bit input **

并考虑在同一端口上的各个引脚上连续的clear和setb语句,我可以使用ANL或ORL,但如果我直接在端口上执行,结果可能由于8051的行为而无法正确更新

还有其他方法可以修改重复代码以使事情运行得更快吗?

我已经保存了至少380微秒(每次删除DJNZ 6.5微秒乘以一次使用它8次一个字节+ 1加载计数器变量用于DJNZ +循环中的其他命令然后再乘以字节来处理命令( 7个字节))

但我想保存更多。

有什么想法吗?

除非我不打算移除外环,因为这样做会大大增加对rom空间的需求,并且我不会留下太多的自由空间。

1 个答案:

答案 0 :(得分:0)

可以为FLUSHENXMIT使用两个不同的端口引脚。通过这样做,您可以直接在端口上使用ANL或ORL。