您的位置 首页 知识

51单片机 运算才能 测验

几天前在做51循迹小车程序的时候,为了能用得上PID算法,在程序中用了很多浮点数运算。大家都知道51单片机是8位单片机,而浮点数是32位的,…

几天前在做51循迹小车程序的时分,为了能用得上PID算法,在程序中用了许多浮点数运算。咱们都知道51单片机是8位单片机,而浮点数是32位的,其时我就在想,浮点运算用多了会不会影响到小车程序的反应速度和功能呢,其时为了竣工,没有多想,仅仅想着——横竖我在程序里也用不到多少,应该不会有太大的影响。

今日一想,为何不来做个测验呢,说做就做,程序很快调通了,测验成果也出来了。

首先说一下我所用的51单片机装备:

STC12C5A60S2增强型51单片机, 11.0592M晶振, 1T形式(1个时钟周期碑文1条指令,大部分51单片机是12T的,单片机这点和PC不同)。

测验原理:

1.用片上守时器/计数器0完成了一个计时器;

2.记载一定量浮点数核算(加法)运算的总时刻,并记载浮点运算测验过程中其他运算操作的时刻;

3.运用以上记载的两个时刻之差和运转前指定的运算次数即可算出每秒浮点运算次数(暂时用fps一共);

先来看看测验成果:

测验总时刻:407s

平均速度:25047.8 fps

最快速度:33559.5 fps

最慢速度:22932.8 fps

再来看看咱们的测验主体部分吧:

// 先指定浮点运算次数:n = 10000; send_str("t0\tt1\tt2\tfps\ips\r\n");while(1) {t0 = t_cur;	// float t_cur 为当时时刻,由中止服务程序自动更新。for( i=0; i

在我笔记本电脑上的测验成果:

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

我笔记本的装备:

CPU:intel core i5 2.30GHz

RAM:2.00GB DDR3

操作系统:Win7旗舰版64bit

用此咱们看到了二者的比照,笔记本的速度大约是单片机的 33387.7 倍( =836263534 /25047.8 )。但是,这并不是CPU的最快速度(毕竟是在操作系统上运转的 ,CPU一起需求处理其他使命),51MCU却是“开足马力了”。

由此咱们也有了一个大致的概念:

增强型 51 单片机每秒也只能做几万次浮点运算(一般的只要它的 1/12 ,大约只要 两千屡次/秒);

现在干流PC每秒能作将近一亿次浮点运算。

当然,在电脑上测验的程序要做些改动,运算次数的设定不能太小,不然在后面做除法的时分可能会溢出,并且次数设定得太少的时分夺冠也不叫大,下面贴出源码,仅供参考:

#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版)默许编译设置.

编译前面一段代码的是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.// 先指定浮点运算次数:n = 100000; send_str("t0\tt1\tt2\tfps\ips\r\n");while(1) {t0 = t_cur;	// t_cur 为当时时刻,由中止服务程序自动更新。for( i=0; i

def.h:

#ifndef _DEF_H_#define _DEF_H_#include "stc51.h"///////////////////////////////////////////////////////////////////////////////#define UART#define TIMER	/*  计时器,守时/计数器0完成  *////////////////////////////////////////////////////////////////////////////////typedef unsigned char uchar;typedef unsigned int  uint;typedef uchar uint8;#ifdef UART // 串口通讯 				// UART.cvoid UART_init(uint8 mode);void send_data(char ch); // 向串口发送一个8位整数(非中止方法)void send_str(char* str); // 串口发送字符串	#define SENDOUT() send_str(buffer)#define sendout() SENDOUT()#include extern xdata char buffer[]; // 外部数组,串口字符串缓存.#endif#ifdef TIMER  // 计时器,守时器0完成.void tm0_init(void);void restart(void);// 计时变量:		   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// 计时变量:		   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		//守时器时钟12T形式#endifTMOD |= 0x01; // 最低方位1  // 16位守时器EA = 1;ET0 = 1;TL0 = T1MS;		//设置守时初值TH0 = T1MS >> 8;		//设置守时初值TR0 = 1;		//守时器0开端计时}//守时器0中止服务程序/* 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; //守时器1守时方法2 TCON = 0x40; //设守时器 1 开端计数 PCON = 0x80; //波特率加倍操控,SMOD 位 TH1 = THTL; TL1 = THTL; RI = 0; //清收发标志 TI = 0; // 发送TR1 = 1; //发动守时器 }void send_data(char OutData) //向串口输出一个字符(非中止方法) { SBUF = OutData; //输出字符 while(!TI); //空语句判别字符是否发完 TI = 0; //清 TI }void send_str(char* str) // 串口发送字符串{while(*str) send_data(*str++);}// #define UARTOUT(inum) ComOutChar((uchar)inum);// ComOutChar((uchar)inum>>8);ComOutChar((uchar)inum&0xff);	   #endif // UART

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/zhishi/265000.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部