首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在低于1ms - 8051的范围内执行函数中的SPI命令

在低于1ms - 8051的范围内执行函数中的SPI命令
EN

Stack Overflow用户
提问于 2018-04-09 08:39:04
回答 1查看 58关注 0票数 0

目前,我有一个AT89C2051微控制器,通过多路复用器-多路分路器设置连接到ISD声卡芯片上。我也有其他的事情,但我的重点是让声音尽可能快地执行。目前芯片的速度是3.6 the,因为这个微控制器是由另一个微控制器驱动的。

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

这是到目前为止我所拥有的可以工作的代码:

代码语言:javascript
复制
  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)通过多路复用器/多路分路器在系统中的每条数据线之间共享。这意味着当我想要接收数据时,我需要通过启用接收和不发送任何东西来使线路只是单向的(而不是双向的)。

我将接收启用称为“刷新”,因为它还会刷新超出此问题范围的其他输出行。

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

所以我看了下面这几行:

代码语言:javascript
复制
              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 **

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

有没有其他方法可以修改重复的代码,让它运行得更快?

我已经节省了至少380微秒(每次删除DJNZ需要6.5微秒乘以8次字节+1来加载DJNZ的计数器变量+循环中的其他命令,然后乘以字节来处理命令(7字节))

但我想存更多的钱。

有什么想法吗?

除了我不打算删除外部循环,因为这样做会增加对rom空间的需求,并且我没有太多的空闲rom空间。

EN

回答 1

Stack Overflow用户

发布于 2018-04-11 15:14:56

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49724176

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档