目前我有一个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空间的需求,并且我不会留下太多的自由空间。
答案 0 :(得分:0)
可以为FLUSH
和ENXMIT
使用两个不同的端口引脚。通过这样做,您可以直接在端口上使用ANL或ORL。