新聞中心

EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 51單片機(jī) 運(yùn)算能力 測(cè)試

51單片機(jī) 運(yùn)算能力 測(cè)試

作者: 時(shí)間:2016-11-19 來(lái)源:網(wǎng)絡(luò) 收藏
幾天前在做51循跡小車(chē)程序的時(shí)候,為了能用得上PID算法,在程序中用了很多浮點(diǎn)數(shù)運(yùn)算。大家都知道51單片機(jī)是8位單片機(jī),而浮點(diǎn)數(shù)是32位的,當(dāng)時(shí)我就在想,浮點(diǎn)運(yùn)算用多了會(huì)不會(huì)影響到小車(chē)程序的反應(yīng)速度和性能呢,當(dāng)時(shí)為了完工,沒(méi)有多想,只是想著——反正我在程序里也用不到多少,應(yīng)該不會(huì)有太大的影響。

今天一想,為何不來(lái)做個(gè)測(cè)試呢,說(shuō)做就做,程序很快調(diào)通了,測(cè)試結(jié)果也出來(lái)了。

本文引用地址:http://butianyuan.cn/article/201611/318157.htm

首先說(shuō)一下我所用的51單片機(jī)配置:

STC12C5A60S2增強(qiáng)型51單片機(jī), 11.0592M晶振, 1T模式(1個(gè)時(shí)鐘周期執(zhí)行1條指令,大部分51單片機(jī)是12T的,單片機(jī)這點(diǎn)和PC不同)。

測(cè)試原理:

1.用片上定時(shí)器/計(jì)數(shù)器0實(shí)現(xiàn)了一個(gè)計(jì)時(shí)器;

2.記錄一定量浮點(diǎn)數(shù)計(jì)算(加法)運(yùn)算的總時(shí)間,并記錄浮點(diǎn)運(yùn)算測(cè)試過(guò)程中其他運(yùn)算操作的時(shí)間;

3.利用以上記錄的兩個(gè)時(shí)間之差和運(yùn)行前指定的運(yùn)算次數(shù)即可算出每秒浮點(diǎn)運(yùn)算次數(shù)(暫時(shí)用fps表示);

先來(lái)看看測(cè)試結(jié)果:

測(cè)試總時(shí)間:407s

平均速度:25047.8 fps

最快速度:33559.5 fps

最慢速度:22932.8 fps

再來(lái)看看我們的測(cè)試主體部分吧:

// 先指定浮點(diǎn)運(yùn)算次數(shù):n = 10000; send_str("t0tt1tt2tfpsipsrn");while(1) {t0 = t_cur;	// float t_cur 為當(dāng)前時(shí)間,由中斷服務(wù)程序自動(dòng)更新。for( i=0; i


在我筆記本電腦上的測(cè)試結(jié)果:

平均值:836263534
最大值:990099010
最小值:735294118

我筆記本的配置:

CPU:intel core i5 2.30GHz

RAM:2.00GB DDR3

操作系統(tǒng):Win7旗艦版64bit

用此我們看到了二者的對(duì)比,筆記本的速度大約是單片機(jī)的 33387.7 倍( =836263534 /25047.8 )。然而,這并不是CPU的最快速度(畢竟是在操作系統(tǒng)上運(yùn)行的 ,CPU同時(shí)需要處理其他任務(wù)),51MCU卻是“開(kāi)足馬力了”。

由此我們也有了一個(gè)大致的概念:

增強(qiáng)型 51 單片機(jī)每秒也只能做幾萬(wàn)次浮點(diǎn)運(yùn)算(普通的只有它的 1/12 ,大概只有 兩千多次/秒);

現(xiàn)在主流PC每秒能作將近一億次浮點(diǎn)運(yùn)算。

當(dāng)然,在電腦上測(cè)試的程序要做些改動(dòng),運(yùn)算次數(shù)的設(shè)定不能太小,否則在后面做除法的時(shí)候可能會(huì)溢出,而且次數(shù)設(shè)定得太少的時(shí)候誤差也不叫大,下面貼出源碼,僅供參考:

#include #include using namespace std;int main(){int i;float ft=0.001, ft0=0.0;clock_t t0, t1, t2;long n = 100000000;double time_cnt = 500.0;while(1) {t0 = clock();for( i=0; i time_cnt ) break;}return 0;}


我電腦上使用的是:g++ (GCC) 4.6.1(MinGW版)默認(rèn)編譯設(shè)置.

編譯前面一段代碼的是Keil uVersion 3.0,下面貼出程序全部源碼,歡迎各位大蝦拍磚。

main.c:

#include "def.h"#define LEDU 0x01#define LEDL 0x02#define LEDD 0x04#define LEDR 0x08sbit start=P0^5;int i, n;xdata float ft  = 0.001,ft0 = 0.0;xdata float t0 = 0.0,t1 = 0.0,t2 = 0.0,t3 = 0.0,t4 = 0.0;char ch=1, ch0=0;void init(){tm0_init(); UART_init(6);P0 &= 0x00;start=1;while( start );}void main(){init();restart(); // timer restart.// 先指定浮點(diǎn)運(yùn)算次數(shù):n = 100000; send_str("t0tt1tt2tfpsipsrn");while(1) {t0 = t_cur;	// t_cur 為當(dāng)前時(shí)間,由中斷服務(wù)程序自動(dòng)更新。for( i=0; i

def.h:

#ifndef _DEF_H_#define _DEF_H_#include "stc51.h"http:///////////////////////////////////////////////////////////////////////////////#define UART#define TIMER	/*  計(jì)時(shí)器,定時(shí)/計(jì)數(shù)器0實(shí)現(xiàn)  *////////////////////////////////////////////////////////////////////////////////typedef unsigned char uchar;typedef unsigned int  uint;typedef uchar uint8;#ifdef UART // 串口通信 				// UART.cvoid UART_init(uint8 mode);void send_data(char ch); // 向串口發(fā)送一個(gè)8位整數(shù)(非中斷方式)void send_str(char* str); // 串口發(fā)送字符串	#define SENDOUT() send_str(buffer)#define sendout() SENDOUT()#include extern xdata char buffer[]; // 外部數(shù)組,串口字符串緩存.#endif#ifdef TIMER  // 計(jì)時(shí)器,定時(shí)器0實(shí)現(xiàn).void tm0_init(void);void restart(void);// 計(jì)時(shí)變量:		   extern uint t_msec; // millisecond counter.extern uchar t_sec; // second counter.extern float t_cur; // second & millisecond.#endif//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void init(void);//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////#endif // _DEF_H_

timer.c:

#include "def.h"#ifdef TIMER// 計(jì)時(shí)變量:		   uint t_msec=0; // millisecond counter.uchar t_sec=0; // second counter.float t_cur=0.0; // second & millisecond.#define MODE1T         //Timer clock mode, comment this line is 12T mode, uncomment is 1T mode#define FOSC 11059253L	   // 11.0592 MHz#ifdef MODE1T#define T1MS (65536-FOSC/1000)      //1ms timer calculation method in 1T mode#else#define T1MS (65536-FOSC/12/1000)   //1ms timer calculation method in 12T mode#endifvoid tm0_init(void)		//50毫秒@11.0592MHz{#ifdef MODE1TAUXR |= 0x80;#elseAUXR &= 0x7F; // 最高位置0		//定時(shí)器時(shí)鐘12T模式#endifTMOD |= 0x01; // 最低位置1  // 16位定時(shí)器EA = 1;ET0 = 1;TL0 = T1MS;		//設(shè)置定時(shí)初值TH0 = T1MS >> 8;		//設(shè)置定時(shí)初值TR0 = 1;		//定時(shí)器0開(kāi)始計(jì)時(shí)}//定時(shí)器0中斷服務(wù)程序/* Timer0 interrupt routine */void tm0_isr() interrupt 1 // using 1{TL0 = T1MS;                     //reload timer0 low byteTH0 = T1MS >> 8;                //reload timer0 high byte++t_msec;t_cur += 0.001;if (t_msec == 1000) {              //1ms * 1000 -> 1st_msec = 0;               //reset millisecond counter++t_sec; // second counter.P0 ^= 0x0f;	// lighting... ...}}void  restart(void){t_msec=0;t_sec=0;t_cur=0.0;tm0_init();}#endif // TIMER

UART.c:

#include "def.h"#ifdef UARTxdata char buffer[32];  // 全局變量.//串口初始化 晶振為 11.0592M  方式 1 波特率 300-57600 void UART_init(unsigned char BaudRate) { unsigned char THTL; switch (BaudRate) { case 1: THTL = 64; break; //波特率 300 case 2: THTL = 160; break; //600 case 3: THTL = 208; break; //1200 case 4: THTL = 232; break; //2400 case 5: THTL = 244; break; //4800 case 6: THTL = 250; break; //9600 case 7: THTL = 253; break; //19200 case 8: THTL = 255; break; //57600 default: THTL = 250; } SCON = 0x50; //串口方式 1 ,8位 波特率可變 允許接收 TMOD = 0x20; //定時(shí)器1定時(shí)方式2 TCON = 0x40; //設(shè)定時(shí)器 1 開(kāi)始計(jì)數(shù) PCON = 0x80; //波特率加倍控制,SMOD 位 TH1 = THTL; TL1 = THTL; RI = 0; //清收發(fā)標(biāo)志 TI = 0; // 發(fā)送TR1 = 1; //啟動(dòng)定時(shí)器 }void send_data(char OutData) //向串口輸出一個(gè)字符(非中斷方式) { SBUF = OutData; //輸出字符 while(!TI); //空語(yǔ)句判斷字符是否發(fā)完 TI = 0; //清 TI }void send_str(char* str) // 串口發(fā)送字符串{while(*str) send_data(*str++);}// #define UARTOUT(inum) ComOutChar((uchar)inum);// ComOutChar((uchar)inum>>8);ComOutChar((uchar)inum&0xff);	   #endif // UART


關(guān)鍵詞: 51單片機(jī)運(yùn)算能

評(píng)論


技術(shù)專(zhuān)區(qū)

關(guān)閉