在做一个产品,最初第一版是用msp430fr5969做的,后来产品升级ROM不够用了,就将mcu更换为了msp430fr5992,这两个单片机管脚完全兼容,ROM比之前的5969大一倍。但是更换后发现了一个问题,相同的时钟配置下,5992的运行速度比之前5969的慢了好多,比如之前的一个计算函数在5969单片机上运行需要11ms,在5992单片机上运行则需要26ms,不知道是什么原因?请高手指点一下。
MCLK用的是内部的DOC,我配置的是21MHz(NWAITSX bit也全设置为了1),SMCLK用的是外部HF(12MHz),ACLK用的是外部LF(32.768KHz)。
灰小子:
做产品不建议超频使用啊,这两个mcu的最高频,数据手册里写的都是16MHz。
如果运算比较多,注意用好硬件乘法器。
user4461879:
回复 灰小子:
硬件乘法器已经使能了,产品中浮点数据的运算量比较大,三角函数调用比较多,所以只能超频了,极限是24M,我只用到了21M,我的疑问是相同的时钟配置,相同的函数,为什么在5992上运行比在5969上慢,两个程序我没有看出有什么明显区别啊?
灰小子:
回复 user4461879:
我怀疑5992的实际运行频率可能并没到21MHz,你把时钟通过io输出,用示波器观察一下实际的运行频率。
Susan Yang:
另外您可以先看一下 www.ti.com/…/slaa801.pdf的 2.1.1 Optimization Settings,可以帮助您提高代码运行速度
相对来说频率较高的时候,功耗也会相应增加
user4461879:
回复 灰小子:
我试着把SMCLK设置为DOC,然后在IO口上看过,是21M左右,正式产品上SMCLK是外部HF,但是MCLK是用的DOC(21M),因此MCLK就是21M,问题是相同的时钟设置和运行函数,在5992上运行时间比5969慢好多啊。这个不理解啊,产品升级更换MCU后计算速度慢了进一倍。现在是要解决这个问题。
user4461879:
回复 Susan Yang:
我用的是IAR,代码优化我选的是LOW,这个办法在产品第一版时就实验过,过分提高级别会导致优化后代码表达的意思不完全对,另外新添加的功能需要的ROM很大,所以只能更换MCU了,问题是在时钟配置几乎相同的情况下,原来的函数运行时间都慢了很多,这个是什么原因,我甚至单独建了两个测试工程(和产品功能完全脱离),一个是5969的,一个是5992的,两个使用相同的时钟配置,都调用同一个函数(函数内容是一大堆浮点的乘法和加法),结果5969用了107ms,5992用了238ms,太奇怪了,难道是5992性能不如5969?
user4461879:
回复 user4461879:
时钟初始化代码如下:
void clk_init(void)
{
// LED1_CLOSE;FRCTL0=0XA500+NACCESS0+NACCESS1+NACCESS2;//晶振大于8M时需要设置NWAITS为1//FRCTL0=NACCESS0;PJDIR=0x00;PJOUT=0;PJREN=0xFF;PJSEL0=PJSEL0_6+PJSEL0_7; PJDIR|=(BIT5+BIT7);CSCTL0=0xA500;//passwordCSCTL1=DCOFSEL0+DCOFSEL2+DCORSEL;//DCORSEL=高速模式101=21MCSCTL2=0;CSCTL2=SELS0+SELS2+SELM0+SELM1;//MCLK=DOCSMCLK=HFCSCTL3=0;CSCTL4=VLOOFF+LFXTDRIVE0+LFXTDRIVE1+HFXTDRIVE0+HFXTDRIVE1+HFFREQ1+LFXTOFF;//关闭VLO
CSCTL5=0; CSCTL6=ACLKREQEN+MCLKREQEN+SMCLKREQEN+MODCLKREQEN;//
// LED1_OPEN;do{PM5CTL0 &= ~LOCKLPM5;CSCTL0=0xA500;//passwordCSCTL0_H=0xa5;CSCTL5 &= ~(LFXTOFFG+HFXTOFFG);SFRIFG1&=~OFIFG;delay(0x8f);}while(CSCTL5&HFXTOFFG);//SFRIFG1&OFIFG}
Susan Yang:
回复 user4461879:
请问能否给出您具体的测试代码?
user4461879:
回复 Susan Yang:
#include "io430.h"
typedefunsignedcharuchar;
typedefsignedcharschar;
typedefunsignedintuint;
typedefsignedintsint;
typedefunsignedlong intulint;
typedefsignedlong intslint;
#definePI3.14515926void delay(uint i)
{while(i–);
}void clk_init(void)
{
// LED1_CLOSE;FRCTL0=0XA500+NACCESS0+NACCESS1+NACCESS2;//晶振大于8M时需要设置NWAITS为1//FRCTL0=NACCESS0;PJDIR=0x00;PJOUT=0;PJREN=0xFF;PJSEL0=PJSEL0_6+PJSEL0_7; PJDIR|=(BIT5+BIT7);CSCTL0=0xA500;//passwordCSCTL1=DCOFSEL0+DCOFSEL2+DCORSEL;//DCORSEL=高速模式101=21mCSCTL2=0;CSCTL2=SELS0+SELS2+SELM0+SELM1;CSCTL3=0;CSCTL4=VLOOFF+LFXTDRIVE0+LFXTDRIVE1+HFXTDRIVE0+HFXTDRIVE1+HFFREQ1+LFXTOFF;//关闭VLO
CSCTL5=0; CSCTL6=ACLKREQEN+MCLKREQEN+SMCLKREQEN+MODCLKREQEN;//
// LED1_OPEN;do{PM5CTL0 &= ~LOCKLPM5;CSCTL0=0xA500;//passwordCSCTL0_H=0xa5;CSCTL5 &= ~(LFXTOFFG+HFXTOFFG);SFRIFG1&=~OFIFG;delay(0x8f);}while(CSCTL5&HFXTOFFG);//SFRIFG1&OFIFG}
void timerA0_init(void)//1ms定时器用于测量计算时间
{TA0CTL=TASSEL1+MC0+ID1+ID0;//+TAIE; 12M12/8=1.5TA0CCR0=1500;//32__bis_SR_register(GIE); TA0R=1499;TA0CCTL0=CCIE;
}uintcount=0;
#pragma vector = TIMER0_A0_VECTOR
__interrupt void TimeA0(void)
{count++;
}//测试用变量
uint ii,jj;
float f1[100],f2[100],f3[100];int main( void )
{// Stop watchdog timer to prevent time out resetWDTCTL = WDTPW + WDTHOLD;clk_init();//初始化时钟delay(65530);timerA0_init();//初始化定时器1ms定时for(ii=0;ii<100;ii++)//初始化测试变量{f1[ii]=PI;f2[ii]=2*PI;f3[ii]=f1[ii]*f2[ii];}do{count=0;//清除计数for(jj=0;jj<100;jj++){for(ii=0;ii<100;ii++){f3[ii]=f1[ii]*f2[ii];}}//运行到此后count的值就是运行时间两个for循环就是测试代码}while(1);
return 0;
}
user4461879:
回复 user4461879:
不知能不能从我的测试代码中看到操作不对的地方,另外我将DOC从21M降到了7M,测试的结果还是5992运行速度比5969慢,5992耗时716模ms,5969耗时322ms。