目前,我有一个AT89C2051微控制器,通过多路复用器-多路分路器设置连接到ISD声卡芯片上。我也有其他的事情,但我的重点是让声音尽可能快地执行。目前芯片的速度是3.6 the,因为这个微控制器是由另一个微控制器驱动的。
根据文档和实验,声音芯片需要向它发送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)通过多路复用器/多路分路器在系统中的每条数据线之间共享。这意味着当我想要接收数据时,我需要通过启用接收和不发送任何东西来使线路只是单向的(而不是双向的)。
我将接收启用称为“刷新”,因为它还会刷新超出此问题范围的其他输出行。
现在我想要做的是让这段代码执行得更快。
所以我看了下面这几行:
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空间。
发布于 2018-04-11 15:14:56
可以对FLUSH和ENXMIT使用两个不同的端口引脚。通过这样做,您可以直接在端口上使用ANL或ORL。
https://stackoverflow.com/questions/49724176
复制相似问题