利用飞思卡尔单片机官网进行转速采集计算

基于飞思卡尔S12单片机的智能车系统设计与实现_刘允峰_图文_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
基于飞思卡尔S12单片机的智能车系统设计与实现_刘允峰
上传于||暂无简介
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩2页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢君,已阅读到文档的结尾了呢~~
基于飞思卡尔单片机的木棒长度测量系统基于飞思
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
基于飞思卡尔单片机的木棒长度测量系统
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口单片机中怎样利用移位法代替乘除法计算AD转换结果?
之前用飞思卡尔的MC9RS08KA4_8单片机做了个电压采集板,12位精度,基准为4.5V。
上头点评了一下我的程序,说result = ADCR * ;这一句的效率不高,可以用移位法。
下面我把我的程序精简出来如下,哪位高手可以用移位法来高效地实现这个程序呢?
word StartConvert(byte channel)
& & ADCSC1 =& && && &&&//选择通道
& & while(!ADCSC1_COCO);& && &&&//转换是否完成?
& & result = ADCR * ;&&//计算转换结果
result = ((ADCR * 4500)&& 12);&&//计算转换结果
同时要保证ADCR不会因为×4500而溢出
乘除2的指数编译器会自动给你优化成移位的,IAR就可以,编译器很聪明的
为啥不写成,Freescale应该有硬件乘法器的吧?
word StartConvert(byte channel)&&
& & ADCSC1 =& && && &&&//选择通道
& & while(!ADCSC1_COCO);& && &&&//转换是否完成?
& & result = ADCR * (4500ul/4096ul);&&//计算转换结果
看来我刚才糊涂了……仔细一看 4500 / 4096……不就是1么……哎……
大家能给个实际的例子么?
回复【4楼】Gorgon Meducer 傻孩子
-----------------------------------------------------------------------
嘿嘿不好意思,这里只是简化的,实际当中我是定义了变量的。粘上去的时候没在意思,请见谅....
这个优化作用不大啊同学。除非是求余
那个WORD是什么类型的数据啊?可以把的值先算出来,然后按照精度要求再扩大。可以提高效率的哦
那个WORD是什么类型的数据啊?可以把的值先算出来,然后按照精度要求再扩大。可以提高效率的哦
&& &result = ADCR * (4500ul/4096ul);&&//计算转换结果&&&
because (4500ul/4096ul)=0.
you can use floating point math here, however.
& &result = (unsigned short ) (ADCR * );&&//计算转换结果&&
but that's going to increase the code size significantly if you aren't already using floating poin math.
.这样看,没必要让单片机算.可以让单片机x1或x11,x110,x.......上面的乘法可以用移位。
unsigned int x,y,z;
y=((x&&3)+1)&&1; z+=y;
y=(y+1)&&1;& && &z+=y;
y=((y&&2)+1)&&1; z+=y;
y=((y&&1)+1)&&1; z+=y;
入口x,出口z 超快,已经4舍5入了,不过还有点误差。
unsigned int x,y,z;
&&z+=y+(y&&2);
&&z=x+(z&&4);
【14楼】 cowboy
好强,倒过来移结果跟用除法一样了哈哈
我顺着移每移一次,精确度就少了一点,学习了。
&倒过来移结果跟用除法一样了哈哈 &
not exactly the same. for 10-bit adc, you need to device by 1023 (and 4095 for 12-bit adc).
shifting is just an approximation.
英文看不懂...
not exactly the same. = 不完全一样.&&?
10位ADC我需要什么什么...1023?(12位ADC到4095?)
shifting is just an approximation. = 转换只是一个近似值.&&?
回复【3楼】again
乘除2的指数编译器会自动给你优化成移位的,iar就可以,编译器很聪明的
-----------------------------------------------------------------------
是的,会自动优化成移位的。并且建议保留/4096的写法,这样方便阅读源代码。
【16楼】 millwood0
写了个程序测试了,确实只是近似。
从0-4095里有184个结果跟用除法的结果差1,而且都是小1,其它都是相等的。
i是输入值,z是用【14楼】 cowboy的方法,z2是直接用除法,j是不同的个数。
i=001F&&z=0021&&z2=0022
i=0029&&z=002C&&z2=002D
i=0033&&z=0037&&z2=0038
i=003D&&z=0042&&z2=0043
i=0047&&z=004D&&z2=004E
i=007A&&z=0085&&z2=0086
i=008E&&z=009B&&z2=009C
i=00AD&&z=00BD&&z2=00BE
i=00B7&&z=00C8&&z2=00C9
i=00CB&&z=00DE&&z2=00DF
i=00D5&&z=00E9&&z2=00EA
i=00FE&&z=0116&&z2=0117
i=011C&&z=0137&&z2=0138
i=013B&&z=0159&&z2=015A
i=0F9B&&z=1124&&z2=1125
i=0FA5&&z=112F&&z2=1130
i=0FAF&&z=113A&&z2=113B
i=0FEC&&z=117D&&z2=117E
i=0FF6&&z=1188&&z2=1189
unsigned int calc(unsigned int x)&&//x:0~41527, 结果与x*相同。
&&z = x + (x&&2);
&&z = x + (z&&3);
&&z = x + (z&&1);
&&z = x + (z&&4);
哈哈,完全倒序版。
result = (uint16_t)(( ADCR * 4500UL ) / 4096U );
result = (uint16_t)(( ADCR * 1125UL ) / 1024U );
现在的编译器一般不需要特意用移位,除以4096或者1024都会被自动优化。
12位的AD结果范围在0-00是会溢出的,这个需要特别注意!!!
完全没必要用浮点数,如果可能的话,硬件电路上可以考虑用4.1V的基准,
出来的数据直接用就好,稍有点误差也不怕,最后的结果总是需要校准的
【21楼】 cowboy 的方法是比较高效的。
只是别人看不出来用来干麻的,要打注解。
23L说的没错,有心思这么复杂的计算,还不如把参考电压降为2.048V或者4.096V。
能用2.048V或者4.096V当然最好了,算都不用算,但有时必须用特殊的采考啊。
比如楼主的4.5V 很有可能用在测试锂电池的电压的,用4.096V的参考电压是不是不适合。
回复【26楼】hsztc&&
能用2.048v或者4.096v当然最好了,算都不用算,但有时必须用特殊的采考啊。
比如楼主的4.5v 很有可能用在测试锂电池的电压的,用4.096v的参考电压是不是不适合。
-----------------------------------------------------------------------
现在很多12位或16位ADC能测量±10V或0~20V电压,参考电压才2.5V,其实都是在ADC内使用了电阻分压。所以外部电路使用分压再输入ADC进行转换,有何不可呢?
分压是可以的,但硬件复杂了,精度降低了.
回复【21楼】cowboy
-----------------------------------------------------------------------
这方法好,嘿嘿,我喜欢! cowboy , oh , coolboy!! thank you so so so much!
比21楼更快的方法:
z=((x&&1)*36000ul)&&16;
&只是别人看不出来用来干麻的,要打注解。&
it is a typical trick used to speed up division by a constant. essentially, you are trying to break the division by a number that is not a power of two by approximating it with a fraction whose denominator is a power of two.
say x = y / 10.
one way to do it is the following.
1) x = y / 10.
2) approximation: x = y * 102 / 1024.
3) you can calculate y * 102 through a series of combination left shifts, and division by 1024 through a right shift.
that's the principle.
for more details, check out Hacker's Delight.
alternatively, a well known implementation of fast division is the division routine in Keil C51. Check its library for details.
回复【33楼】hsztc
-----------------------------------------------------------------------
hsztc 厉害啊,很多次都见你算法高明。
【34楼】 millwood0
英文看不懂。。。
【35楼】 cowboy
我很菜的,只是时间比较多就慢慢摸索下。(上面是在IAR FOR AVR开最高优化时测的)
你21楼的算法那才叫做牛,我发现每次移位都是移出了余数的其中几位,
把几次移出的数合并起来就是除完后的余数了。所以在不溢出的情况下跟除法的结果是一样的。
有高手能解释下21楼算法的原理么,自己看了会没搞明白
我用C监测电池电压的时候,把单片机使用的2.43V参考电压送入DAC0,使之输出2.048V给12位ADC0使用,电池电压使用精密电阻分压的1/3进入ADC0转换,得到的效果很不错,哈哈。
4500& &&&4500/45& &&&100& && && & 9& && && &9*4096& && && && &&&36864& && && && && &0b01
------ = --------- = ----- = 1 + ---- = 1 + --------/4096 = 1 + -------/4096 ≈ 1 + ------------------
&&4095& &&&4095/45& && &91& && && &91& && && &&&91& && && && && && &91& && && && && && && & 4096
z = x + (x&&1);
z = x + (z&&4);
z = x + (z&&5);
z = z + (z&&4);
可惜性能不如21楼的方法稳定。
【41楼】 eduhf_123 经历
你牛,这个都能算,不过我是用比较懒的方法
打开电脑里的计算器功能,切换到科学型输入4500,然后点二进制,就可以得到4500的二进制数了
那么 00&&12=1.B
使用举个例子
使用方法:
(使用PC中的计算器得到 001000B 除4096=移12位 = 1.B)
小数后面移 3 4 5 9& &(小数后面第3位,第4位,第5位,第9位是&1&)
分别移了& &3 1 1 4 位
倒序移位& &4 1 1 3
&&z = x + (x&&4);&&//等效z=(x*5000ul)/4096;
&&z = x + (z&&1);
&&z = x + (z&&1);
&&z = x + (z&&3);
设当前x=4999 (随意设的)
x=1&&//4999
&&1& && && && &&&// x
+0&&0111 余数& &// x&&4
=1& && && && &&&// z = x + (x&&4);
&&1& && && && &&&// x
+1&&1& & 余数& &// z&&1
=0& && && && &&&// z = x + (z&&1);
&&1& && && && &&&// x
+1&&0& & 余数& &// z&&1
=10& && && && &&&// z = x + (z&&1);
&&1& && && && && && && &&&// x
+1&&010&&余数& && && && &// z&&3
=0&&010 0 1 0111&&余数& &// z = x + (z&&3);
&&0&&&&余数
使用计算器验算次 96=()&&12=
(原文件名:的二进制数.PNG)
结果跟使用除法的结果完全一样,连余数都是对的
因此同时也能得到余数,但效率不一定高:
&&z2= x & 15;& && && &&&//等效z2=(x*5000ul)%4096;
&&z = x + (x&&4);& && & //等效z=(x*5000ul)/4096;
&&z2 |= (z & 1) && 4;
&&z = x + (z&&1);
&&z2 |= (z & 1) && 5;
&&z = x + (z&&1);
&&z2 |= (z & 7) && 6;
&&z = x + (z&&3);
&&z2 &&= 3;
回复【42楼】hsztc
【41楼】 eduhf_123 经历
你牛,这个都能算,不过我是用比较懒的方法
打开电脑里的计算器功能,切换到科学型输入4500,然后点二进制,就可以得到4500的二进制数了
那么 00&&12=1.b
-----------------------------------------------------------------------
可惜的是,12位AD的满量程输出是4095而不是4096。
所以你们的办法其实在算法上就引入了(负)误差(分母变大了导致商变小),再考虑右移过程中溢出的位其实都被截断了,所以整体的误差都偏大了。
我41楼的算法其实也是近似的,为了运算次数跟21楼保持一致、为4次移位和4次加法。
数学公式得到的结果是0b1.01
但那四条语句的结果是0b1.0011
绝对误差已经由-2.4E-5变到了-8.5E-5,再加上移位过程中引入的截断误差,所以总体都偏小了。
【44楼】 eduhf_123 经历
是你理解错了,
12位AD的满量程输出是4095,所以AD输入的电压范围是0-()*4.5V
最大值并不是4.5V,超过()*4.5V均输出4095.
但这个输入值只影响输出结果,跟计算公式无关。
公式是z=(x*4500ul)/4096;
而不是z=(x*4500ul)/4095;
以前公式是取整的算法,如果要四舍五入那又是另一码事了,不过不管怎么算都是有误差的。
加入四舍五入的方法:
&&z = x + (x&&2);& &//z=(x*4500ul)/4095;
&&z = x + (z&&3);
&&z = x + (z&&1);
&&z = 1 + (z&&3);& &//插入四舍五入
&&z = x + (z&&1);
你看看哪个更准。
看看这样行不行(没有经过验证哦):
&&result = ADCR * ;
==&&&result = ADCR * ;
==&&&result = ADCR * ;
==&&&result = ADCR *(101 + ;
==&&&result = ADCR *(101/1024 + 1);
==&&&result = ADCR *101/1024 + ADCR;
==&&&result = ((ADCR *101) && 10) + ADCR;
result = ADCR * ; 与 result = ((ADCR *101) && 10) + ADCR;
估计后者效率高一些。
记号,学习了!
回复【46楼】hsztc
【44楼】 eduhf_123 经历
是你理解错了,
12位ad的满量程输出是4095,所以ad输入的电压范围是0-()*4.5v&&
最大值并不是4.5v,超过()*4.5v均输出4095.
但这个输入值只影响输出结果,跟计算公式无关。
公式是z=(x*4500ul)/4096;
而不是z=(x*4500ul)/4095;
以前公式是取整的算法,如果要四舍五入那又是另一码事了,不过不管怎么算都是有误差的。
--------------------------------------------------------------------
是的,是我理解错了,汗……
X*4500=X*4096+X*404=X*4096+X*256+X*148=X*4096+X*256+X*128+X*20
=X*4096+X*256+X*128+X*16+X*4
以上分别对X左移12位、8位、7位、2位,再累加
把以上结果 /4096,即右移12位即可
或者分子分母同除以4,再按以上方法运算,移位数减少了
以上运算速度应该可以吧,不知道整数运算,误差是否是LZ的允许范围
几天不来,哇,都这么多帖子啦,大家好样的....
厉害 长见识了
如果是我算这个,直接就*72000然后取最高两个字节。只需要对乘法优化一下就行了。兼顾效率和精度。
【55楼】 QQ&&
你看下我33楼的,看哪个快,如果没有硬件乘法还是21楼的快。
51L的办法已经很好了。
=(+4+1)*4
所以在计算A×的时候,近似为:
A*(1+0.25),后面的16/6可以忽略不计。
A*1很好计算,A*0.0625就变成另外一篇帖子中讨论的内容了(关于DS18B20温度计算的),A*0.03125也一样。
【58楼】 XA144F
A*(1+0.25),后面的16/6可以忽略不计。
这个后面不算的话误差很大的。
回复【56楼】hsztc
-----------------------------------------------------------------------
你的“比21楼更快的方法: z=((x&&1)*36000ul)&&16; ”确实很快,但是把36000改为我在55楼描述的“如果是我算这个,直接就*72000然后取最高两个字节。只需要对乘法优化一下就行了。兼顾效率和精度。”可以省去你的移位除法“&&16”。效率岂不是更高!只是多乘一个2而已,乘法效率上是差不多的。
另外,楼主的计算方法不是很好,会有()*100%=9.%的丢失码。这个比例已经相当的高了。
回复【56楼】hsztc&&
-----------------------------------------------------------------------
你的“比21楼更快的方法: z=((x&&1)*36000ul)&&16; ”
刚才还没有仔细看,你的算法是错的。应当是“z=((x&&1)*36000ul)&&15”,少算了一位。如果确实是笔误的话,我的算法基本上跟你是一样的。只是用直接舍弃最低两个字节的方法代替了移位除法。
回复【59楼】hsztc&&
【58楼】 xa144f
a*(1+0.25),后面的16/6可以忽略不计。
这个后面不算的话误差很大的。
-----------------------------------------------------------------------
如果保证小于1%的误差,足够了,哈哈。
回复【61楼】QQ&&
-----------------------------------------------------------------------
hsztc的算法是
z=((x&&1)*36000ul)&&16
x&&1就是*2
x*2*36000ul就是x*72000ul
&&16就是只取最高2字节,编译器并不会真的去移位16次的(超级SB编译器除外),所以算法原理和你的一样,
但速度的区别在于36000ul上,36000ul&65536,是16位整型乘法,
你*72000ul,需要用到32位乘法,效率已经差了一截了...
我还是没有仔细看帖,老_毛病又犯了。
楼上确实是对的。
不过还好,我做*72000也不会真的傻乎乎去做32位乘法。
对于没有乘法指令的芯片,看来只有考虑移位了
47楼是移位算法并加入了四舍五入。
这是33楼加入四舍五入的方法:
z=((x&&1)*36000ul+32768u)&&16;
这样就能将误差降到最低。
【62楼】 XA144F
误差还是大了点,如果将4095代入你会发现误差大于20。
马克下 好好学习
mark, ADC算法优化。
算法!——好神奇
留个脚印先,还没有到达这样高深的阶段,但是吸收下知识
MARK先,单片机直接做除法太慢了。。。
学习ing......
有时间再慢慢看
cowboy 发表于
unsigned int calc(unsigned int x)&&//x:0~41527, 结果与x*相同。
请教一下 如果是x乘又是如何移位的
我觉得如楼主那样的计算是不需要的,应该直接采用,因为:采集的数据在使用时或显示为相应的物理量时还要计算,可以统一考虑和处理
本帖最后由 hzn1948 于
08:38 编辑
我觉得如楼主那样的计算是不需要的,应该直接采用,因为:采集的数据在使用时或显示为相应的物理量时还要计算,可以统一考虑和处理
不好意思,重复了!
一直以来,我都直接除。除非是刚刚2的整数次幂的除法,我就用移位。原来有这么多可以转变的啊。看来思路还真不够宽
头像被屏蔽
提示: 作者被禁止或删除 内容自动屏蔽
哈哈。。。单片内部不是带有*/吗,移位可以实现,但要是浮点麻烦多
& &result = ADCR * (4500ul/4096ul);&&//计算转换结果
What do you think the result is going to be?
Where you bracket matters.
好看帖,不求甚解;每有会意,便欣然回帖。好帖
看看汇编语言就知道了
请教一下 如果是x乘又是如何移位的
同问!,如何解决
阿莫电子论坛, 原"中国电子开发网"黑龙江八一农垦大学&&2012-09 - 2016-07
最高学历:本科
专业名称:农业电气化与自动化
专业描述:
技能专长:&
1.熟练应用C语言,了解C++。2.能够熟练应用PROTEL进行PCB设计。3.理解函数与程序结构、指针、数组、数据结构等基础内容。4.能够在部分ARM架构单片机下自主移植uC/OS并进行多任务实时项目开发。 &5.了解嵌入式操作系统的原理(任务链表、任务调度、linux内核链表等)。
语言水平:
第九届飞思卡尔杯全国大学生智能车竞赛
软件环境:
硬件环境:
开发工具:
项目描述:智能车系统以mc9s12xs128微处理器为核心控制单元,通过ov7620摄像头检测赛道信息,使用软件对图像进行硬件二值化,提取赛道黑线,计算出智能车与黑线的位置偏差,结合特定算法计算出前方赛道信息实现对智能车电机转速转向的反馈控制;通过欧姆龙编码器检测模型车的实时速度,使用PID控制算法调节驱动电机的转速,实现了对模型车运动速度的闭环控制。
责任描述:电机驱动电路、主控制电路的pcb设计以及程序编写。
2014年黑龙江省大学生电子设计大赛
软件环境:
硬件环境:
开发工具:
项目描述:利用RC震荡原理通过原线圈与副线圈产生的共振效应把直流电中的功率传递给副线圈电路
责任描述:硬件电路的pcb设计
U盘数据采集系统
软件环境:
硬件环境:
开发工具:
项目描述:本项目是油田数据采集系统的一个子项目,利用CH375把油田现场的各个传感器的数据(包括井压、井温、井湿、转数、扭矩)采集到U盘里并生成EXCLE文件。
责任描述:负责数据采集处理与存储。
黑龙江八一农垦大学&&2014-09 - 2015-12
职务名称:电子协会会长
职务描述:
本人在大学期间多次参加电子竞技大赛、飞思卡尔大赛的赛事,虽然作为应届毕业生来说工作经验欠缺是我的劣势,但是大学三年的多次比赛和日常积累培养出的处理问题的思路和毅力会是我迅速的融入到工作中来,请您给我一次机会,谢谢!温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
白云推荐阅读:
阅读(19165)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
loftPermalink:'',
id:'fks_085064',
blogTitle:'基于“飞思卡尔”单片机的智能车控制器硬件设计',
blogAbstract:'&
本次设计以全国智能车大赛为背景,主要以freescale 16位微控制器MC9S12DG128作为小车模型的核心控制单元,由于智能车要在黑色引线的识别过程中跑完全程,采用的寻迹传感器主要是光电传感器。MC33886模块稳定、有力地驱动直流电动机。所选用的电源管理芯片TPS7350具有可靠的工作性能、较高的工作效率和较强输出电流驱动能力,可在7.2伏电池供电的条件下为系统的各功能模块提供稳定、可靠的工作电源,为智能车的稳定工作提供了有力的保证。测速部分采用CS3020型的霍尔元件完成对速度的及时测量和反馈。
blogTag:'',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:7,
publishTime:6,
permalink:'blog/static/',
commentCount:13,
mainCommentCount:9,
recommendCount:2,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'',
hmcon:'1',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}

我要回帖

更多关于 飞思卡尔32位单片机 的文章

 

随机推荐