引言
VRS51L3074是美国Ramtron(瑞创)公司推出的8位单片机VRS51L3xxx系列的成员。该单片机拥有许多优良的性能特点:峰值速度高达40MIPS的增强型8051内核,大容量的片上存储器(64 KB Flash与4 KB扩展RAM),写入速度及重复擦写次数远超过EEPROM的铁电存储器(FRAM),多达8通道的PWM输出等。
增强型算术单元(Enhanced Arithmetic Unit, EAU)是VRS51L3074单片机的众多外围模块之一。该模块可以执行类似于通用DSP芯片中的乘加(MAC)操作,即2个16位二进制数相乘后,再将32位乘积与另一个32位数相加。并且,乘加运算所得结果还可进行桶形移位,整个“乘—加—移位”操作只需1个时钟周期即可完成。不难看出,如果能充分利用VRS51L3074的EAU,可以使该单片机更高效地执行复杂的算术运算。
1EAU的原理与使用
EAU的运算模式可分为3种:乘加运算、32位加法运算和16位整数除法运算。前两种模式还可以附加一次移位操作。
从硬件结构的角度来看,EAU可以再细分为4个单元:16×16位乘法器、32位加法器、32位桶型移位器和16位除法器。这4个单元并不是可以任意搭配使用的,而上述的3种EAU工作模式正好对应了实际可用的3种搭配方式,即:乘法器—加法器—移位器连用,加法器—移位器连用,以及单独使用除法器。
EAU中的乘法器和除法器都只能执行有符号数的运算,加法器则只能执行无符号加法,而桶型移位器可以设置为将其输入值看作有符号数或者无符号数。关于如何选择要执行的运算及其操作数,VRS51L3074的手册中已有详细介绍,不再赘述。
2EAU应用举例
以下要介绍的是利用EAU进行计算的实例。所有代码均在Keil uVision3集成开发环境下编译通过(需用到Ramtron公司提供的VRS51L3074_keil.h头文件)。
2.132位有符号数开平方算法
设被开方数为x,其平方根为y,并且有y=a14?214+a13?213+…+a0?20。y的最高位为符号位,此处仅计算算术平方根,故符号位为0。
首先来看如何确定a14。如果该位实际为0,即y=a13?213+…+a0?20<214,则必有x<(214)2;反之,若该位实际为1,则必有y≥214,即x≥(214)2。因此,要确定a14,只需将其置1,并比较此时的y2(不妨称此时的y为“试根”)与x。若y2≤x,则a14=1,反之a14=0。特别地,如果此时恰有y2=x,则y=214就是所求平方根的准确值。
又如a14~aN(0<N≤14)各位已确定,当aN-1=1时,有y=a14?214+…+aN?2N+2N-1+…。因此,必有x≥(a14?214+…+aN?2N+2N-1)2。故可先置aN-1=1,并比较此时的y2与x:若y2≤x,则aN-1=1成立;反之,aN-1=0。特别地,如果恰有y2=x,则此时的y就是所求平方根的准确值。
上述算法的关键在于,求试根的平方并将其与被开方数比较大小。通过使用EAU的乘法器和加法器可以方便地实现该算法。代码如下:
signed int l_sqrt(signed long x) {//输入32位有符号数,输出16位算术平方根
signed int i;
unsigned long tmp;
PERIPHEN2|=0x20;//EAU启用
DEVMEMCFG|=0x01;//切换到SFR Page1
AUCONFIG2=0xa0;//清除EAU各寄存器及标志位
tmp=0x80000000-x;
AUC0=((char*)&tmp)[3];
AUC1=((char*)&tmp)[2];
AUC2=((char*)&tmp)[1];
AUC3=((char*)&tmp)[0];
AUCONFIG1=0x05;//EAU执行AUA×AUA+AUC
for(i=0x4000;i!=0;i>>=1) {
AUA|=i;//需事先将AUA声明为16位SFR
if(AUCONFIG2&0x01) {//加法有溢出,说明试根的平方大于或等于被开方数
if(((AURES3&0x7f)|AURES2|AURES1|AURES0)==0)break;
else AUA^=i;
}
}
i=AUA;
PERIPHEN2&=0xdf;//EAU停用
DEVMEMCFG&=0xfe;//切换到SFR Page0
return i;
}
2.216位二进制数转BCD码算法
将二进制数转换为BCD码,通常是利用除法和取余运算来实现。借助EAU的除法器,可以提高该算法的效率。代码如下:
void hex2bcd(unsigned int hexnum,char data* bcd) {
//输入16位二进制数,输出5字节非压缩BCD码,
//可进一步转换为ASCII码
unsigned char tmp0,tmp1;
PERIPHEN2=0x20;//EAU启用
DEVMEMCFG=1;//切换到SFR Page1
AUCONFIG2=0xa0;//清除EAU各寄存器及标志位
AUA1=((char*)&hexnum)[0];
AUA0=((char*)&hexnum)[1];
AUB1=0x27;
AUB0DIV=0x10;//除以10 000得万位
bcd[0]=AURES2;
tmp0=AURES0;
tmp1=AURES1;
AUA0=tmp0;
AUA1=tmp1;
AUB1=0x03;
AUB0DIV=0xe8;//除以1 000得千位
bcd[1]=AURES2;
tmp0=AURES0;
tmp1=AURES1;
AUA0=tmp0;
AUA1=tmp1;
AUB1=0;
AUB0DIV=0x64;//除以100得百位
bcd[2]=AURES2;
bcd[3]=AURES0/0x0a;//除以10得十位
bcd[4]=B;//最终余数为个位
AUB0=0;//除法器停用
DEVMEMCFG=0;//切换到SFR Page0
PERIPHEN2&=0xdf;//EAU停用
}
3算法验证
在VRS51L3074单片机程序中,分别调用2.1小节中给出的函数l_sqrt以及Keil C51提供的浮点库函数sqrt,利用定时器/计数器T0记录函数从调用到返回所花费的时间(以系统时钟周期为单位),结果如表1所列。
表1l_sqrt函数与浮点库函数对比
在调用浮点库函数时,编译器会同时调用整数与浮点数相互转换的函数,其执行时间也包含在表1所列的调用时间内。从表1可以看出2.1小节所述算法的一个特点:当被开方数是完全平方数,且平方根末尾有连续的若干位为0时,计算过程会在算出其中第一个0后立即结束,计算时间也就相应地减少了。
对于2.2小节所介绍的算法,由于其中没有分支和跳转,执行时间是固定的。同样用T0对其调用过程计时,计数值总是为0x008c,即从函数调用到返回所需时间为140个时钟周期。
4EAU使用注意事项
从实践经验来看,在使用EAU时,应当特别注意以下几点:
①EAU所对应的SFR均只能在Page1中寻址,而UART0、UART1、SPI、I2C以及FRAM等模块所对应的SFR只能在Page0中寻址。因此,当EAU与上述模块同时使用时,必须注意切换当前的SFR寻址页面,即对DEVMEMCFG的最低位(SFRPAGE)进行设置。考虑到EAU是唯一只能在SFR Page1寻址的模块,可以仅在使用到EAU的函数或子程序中切换到Page1,并在返回前重新切换到Page0。2.1和2.2小节中的示例即采用此种方式。但更重要的是,如果在程序中启用了UART、SPI、I2C等模块的中断,并且这些中断可能会在使用EAU的过程中发生,那么就要在中断服务程序的首尾分别进行SFR寻址页面的切换,或者在使用EAU的过程中屏蔽中断。
②尽管EAU中的加法器执行的是无符号数的加法,但是AUCONFIG2中的AUOV32这一标志位并非是32位加法器的“进位”标志位,而是32位有符号数加法的“溢出”标志位。也就是说,AUOV32标志位置1的条件是:参与32位加法的2个操作数最高位均为0,而所得结果的最高位为1;或者2个操作数最高位均为1,而结果的最高位为0。正是利用这一点,2.1小节的开平方算法中用0x80000000减去被开方数,所得之差与试根的平方相加,从而利用AUOV32判断被开方数与试根平方的相对大小。
③当AUB0DIV被写入时,EAU的除法器即被启用。按照VRS51L3xxx数据手册上的介绍,每执行一次对AUB0DIV的写入,就启动一次除法运算,并且每次除法运算需用5个时钟周期。然而,实践表明,在除法器已被启用的情况下,对AUA1、AUA0、AUB1或AUB0DIV中任一者执行写操作,都会立即影响除法器的输出。正是由于这个原因,2.2小节的程序中,在写入被除数和除数后不经等待而直接读取商,并且将余数暂存到tmp0和tmp1后再写入AUA0和AUA1。
④除法器启用后,只有对AUB0执行写操作才能将其停用;否则,即使将EAU禁用后再启用,或通过设置AUCONFIG2对其清零,EAU也会一直执行除法,而不能作加法、乘法或移位。基于这一点,2.2小节中程序的结尾处对AUB0执行了一次写入。这是考虑到用EAU计算除法必然要写AUB0DIV,而用EAU执行加法、乘法或移位却未必会用到AUB(2.1小节的程序中便没有用到AUB),因此有必要在完成除法后进行这样的善后操作。
⑤除法器执行的是有符号整数的除法,其结果(包括商和余数)均为16位有符号数。如果商为负数,除法器会将其向0取整,并得出相应的余数。
结语
VRS51L3074的EAU具有16位数据宽度(对加法为32位)和仅1个时钟周期的运算时间,并且是一个独立的外围模块。利用这一单元来执行算术运算,不仅可以大大缩短运算时间,还能使51单片机固有的累加器瓶颈得到稍许缓解。
通过本文介绍的实例可以看到,EAU确实使得VRS51L3074具有比传统51单片机更加强大的算术运算能力。对单片机工程师来说,带有EAU的VRS51L3074及其同系列产品,可以使他们凭借经典的8051内核及其开发环境来逼近DSP的运算能力。