当前位置: 首页 > news >正文

长沙培训网站建设/武汉seo网站优化

长沙培训网站建设,武汉seo网站优化,wordpress toc,教我做网站几天前在做51循迹小车程序的时候,为了能用得上PID算法,在程序中用了很多浮点数运算。大家都知道51单片机是8位单片机,而浮点数是32位的,当时我就在想,浮点运算用多了会不会影响到小车程序的反应速度和性能呢&#xff0…

几天前在做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<n; ++i); 
t1 = t_cur;
for( i=0; i<n; ++i)	{
ft0 += ft;
}
t2 = t_cur;
sprintf(buffer, "%.3f\t%.3f\t%.3f\t", t0, t1, t2);
send_str(buffer); // send_str 将buffer发送到串口,插上串口线就可以在“串口助手”里看见结果了.
// (t2-t1)为第二个循环时间(浮点加法,整数++运算,整数比较运算)
// (t1-t0)为第一个循环时间(整数++,整数比较)
// 两者相减就是 n 次浮点数运算的时间
sprintf(buffer, "%g\r\t", (float)n/((t2-t1) - (t1-t0)) );
send_str(buffer);
}


在我笔记本电脑上的测试结果:

平均值: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 <ctime>
#include <cstdio>
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<n; ++i );
t1 = clock();
for( i=0; i<n; ++i) {
ft0 += ft;
}
t2 = clock();
printf("%d\t%d\t%d\t", t0, t1, t2);
printf("%f\t\n", (double)n/(((t2-t1) - (t1-t0))/(double)CLOCKS_PER_SEC) );
if( clock()/CLOCKS_PER_SEC > 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 0x08
sbit 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<n; ++i); 
t1 = t_cur;
for( i=0; i<n; ++i)	{
ft0 += ft;
}
t2 = t_cur;
sprintf(buffer, "%.3f\t%.3f\t", t0, t1);
send_str(buffer);
sprintf(buffer, "%.3f\t", t2 );
send_str(buffer);
// (t2-t1)为第二个循环时间(浮点加法,整数++运算,整数比较运算)
// (t1-t0)为第一个循环时间(整数++,整数比较)
// 两者相减就是 n 次浮点数运算的时间
sprintf(buffer, "%g\r\t", (float)n/((t2-t1) - (t1-t0)) );
send_str(buffer);
}
}

 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.c
void UART_init(uint8 mode);
void send_data(char ch); // 向串口发送一个8位整数(非中断方式)
void send_str(char* str); // 串口发送字符串	
#define SENDOUT() send_str(buffer)
#define sendout() SENDOUT()
#include <stdio.h>
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
#endif
void tm0_init(void)		//50毫秒@11.0592MHz
{
#ifdef MODE1T
AUXR |= 0x80;
#else
AUXR &= 0x7F; // 最高位置0		//定时器时钟12T模式
#endif
TMOD |= 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 byte
TH0 = T1MS >> 8;                //reload timer0 high byte
++t_msec;
t_cur += 0.001;
if (t_msec == 1000) {              //1ms * 1000 -> 1s
t_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 UART
xdata 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


 

http://www.lbrq.cn/news/1284931.html

相关文章:

  • 漂亮产品网站/营销软文写作
  • 河北邯郸封闭最新消息/常熟seo网站优化软件
  • 微官网和公众号的区别/汕头seo网络推广服务
  • 做网站需要买什么东西/网站互联网推广
  • 海北wap网站建设/创建网址快捷方式
  • 网站图片是用什么软件做的/黑龙江头条今日新闻
  • 网站怎么做才可以做评价/磁力猫最佳搜索引擎入口
  • 怎样做理财投资网站/百度销售平台怎样联系
  • 网站备案幕布照规范/网络营销以什么为中心
  • 返回邢台最新规定/seo教学网seo
  • 17一起做网站zwd.com/成都网站seo收费标准
  • 织梦网站做中英文双语言版本/长春seo招聘
  • 基层人武部正规化建设/北京seo培训机构
  • 西安专业网站开发哪家好/软文推广去哪个平台好
  • 阿里免费做网站/公司培训课程有哪些
  • 城乡建设与管理委员会网站/短视频seo厂家
  • 网站必须做公安部备案/什么是关键词
  • 网站建设费用 百度文库/一个平台怎么推广
  • 手机微信官方网站/seo营销网站的设计标准
  • 网站开发需要哪些人/线上推广是做什么的
  • 营销型网站是啥/杭州百度优化
  • 朝阳网站建设公司/最近一周的新闻
  • 移动门网站建设/seo查询官方网站
  • 做网站必须托管服务器吗/百度快速排名系统查询
  • 小米路由3g wordpress/淮北seo
  • 网站建设开发软件/地推扫码平台
  • b站24小时直播间十大软件/怎么把产品推广到各大平台
  • 市网站制作/百度网站推广费用
  • 威海专业做网站设计的公司/seo是什么的简称
  • 怎么增加网站关键词库/传统营销与网络营销的区别
  • 第10篇:实战验收篇
  • 如何实现打印功能
  • java面试题(一)
  • Windows-WSL-Docker端口开放
  • 2025年电赛--电源题赛前押题
  • Ubuntu22.04.5 LTS安装与使用Docker