<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>芷菁博客 &#187; 滤波</title>
	<atom:link href="http://www.stars625.com/tag/filtering/feed" rel="self" type="application/rss+xml" />
	<link>http://www.stars625.com</link>
	<description>记录生活点滴，分享学习体会，专注微嵌开发。</description>
	<lastBuildDate>Sun, 18 Jul 2010 02:55:22 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>灭火机器人的设计与制作之滤波算法</title>
		<link>http://www.stars625.com/firefighterdata.html</link>
		<comments>http://www.stars625.com/firefighterdata.html#comments</comments>
		<pubDate>Thu, 11 Jun 2009 12:50:46 +0000</pubDate>
		<dc:creator>stars_625</dc:creator>
				<category><![CDATA[嵌入开发]]></category>
		<category><![CDATA[firefighter]]></category>
		<category><![CDATA[robot]]></category>
		<category><![CDATA[机器人]]></category>
		<category><![CDATA[滤波]]></category>

		<guid isPermaLink="false">http://www.stars625.com/?p=136</guid>
		<description><![CDATA[传感器在系统中作为输入装置，输入的是模拟量，经过A/D转换器将模拟信号转换成数字信号后，才能被系统所使用。因此，数模转换后数值的准确性直接影响到系统的判断。本文就介绍了实际应用中使用的滤波算法。]]></description>
			<content:encoded><![CDATA[<p>在系统中总会存中部分电路噪声或电磁辐射干扰A/D信号，影响数字信号的准确性和平滑性。一般情况下先在硬件上尽可能地进行优化，降低噪声辐射干扰，当硬件上无法进一步改善信号干扰时，这时候就需要采用软件滤波的方法来减少干扰。</p>
<p>滤波算法有很多种，如：限幅滤波、中位值滤波、一阶滤波、消抖滤波等，但各种滤波算法各有特点，使用场合也各不相同。在本系统中使用了中位值、平均、递推复合滤波算法，简称中位值平均递推滤波。</p>
<p>中位值滤波算法是通过连续采样N次，把N次采样值排序，取中间值为本次有效值。该滤波算法能有效克服因偶然因素引起的波动干扰；对变化缓慢的被测参数有良好的滤波效果，但是对快速变化的参数不宜。使用在本系统中，可以消除因电压波动引起的偶然脉冲干扰。</p>
<p>算术平均滤波算法是连续取N个采样值进行算术平均运算，当N值较大时，信号平滑度较高，但灵敏度较低；N值较小时，信号平滑度较低，但灵敏度较高，该算法可以很好的滤除随机干扰。在本系统中，考虑到系统的执行速度较快，并且保证信号的灵敏度，这里N取4，可以很好的滤除随机干扰。</p>
<p>递推平均滤波算法又称滑动平均滤波法，它是将N个采样值放入一个队列，有新的采样值到来时，将最早的一个值去除，再将新值加入队列，求队列平均值。这种算法对周期性干扰有良好的抑制作用，平滑度高，但具有灵敏度低，数据滞后等特点。</p>
<p>在本系统中使用了以上三个算法的复合算法，结合了三种算法各自的优点，并且能够保证系统的灵敏度。</p>
<p>下面将滤波算法列出，以便更好地进行分析：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
</pre></td><td class="code"><pre class="c" style="font-family:monospace;">uint16 ADC_mget<span style="color: #009900;">&#40;</span>uint8 channel<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>	uint16 adc_temp<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">10</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
	<span style="color: #993333;">static</span> uint16 pre_temp<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">10</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #009900;">&#123;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
	uint16 temp<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
	uint32 sum<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
	uint8 i<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">,</span>j<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>	
	<span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>i<span style="color: #339933;">&lt;</span><span style="color: #0000dd;">10</span><span style="color: #339933;">;</span>i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>	adc_temp<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> ADC_get<span style="color: #009900;">&#40;</span>channel<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #666666; font-style: italic;">//连取十个值</span>
	<span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span>j<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>j<span style="color: #339933;">&lt;</span><span style="color: #0000dd;">9</span><span style="color: #339933;">;</span>j<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #666666; font-style: italic;">//冒泡排序</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>i<span style="color: #339933;">&lt;</span><span style="color: #0000dd;">9</span><span style="color: #339933;">-</span>j<span style="color: #339933;">;</span>i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#123;</span>
			<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span>adc_temp<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">&gt;</span>adc_temp<span style="color: #009900;">&#91;</span>i<span style="color: #339933;">+</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
			<span style="color: #009900;">&#123;</span>
				temp <span style="color: #339933;">=</span> adc_temp<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
				adc_temp<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>adc_temp<span style="color: #009900;">&#91;</span>i<span style="color: #339933;">+</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
				adc_temp<span style="color: #009900;">&#91;</span>i<span style="color: #339933;">+</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>temp<span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>	
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>	
	sum <span style="color: #339933;">+=</span> adc_temp<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><span style="color: #666666; font-style: italic;">//累加</span>
	sum <span style="color: #339933;">+=</span> adc_temp<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
	sum <span style="color: #339933;">+=</span> adc_temp<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">5</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
	sum <span style="color: #339933;">+=</span> adc_temp<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">6</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>	
	sum <span style="color: #339933;">&gt;&gt;=</span> <span style="color: #0000dd;">2</span><span style="color: #339933;">;</span>	<span style="color: #666666; font-style: italic;">//求均值</span>
	pre_temp<span style="color: #009900;">&#91;</span>channel<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>pre_temp<span style="color: #009900;">&#91;</span>channel<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><span style="color: #666666; font-style: italic;">//递推入列</span>
	pre_temp<span style="color: #009900;">&#91;</span>channel<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>pre_temp<span style="color: #009900;">&#91;</span>channel<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
	pre_temp<span style="color: #009900;">&#91;</span>channel<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>pre_temp<span style="color: #009900;">&#91;</span>channel<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
	pre_temp<span style="color: #009900;">&#91;</span>channel<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span>uint16<span style="color: #009900;">&#41;</span>sum<span style="color: #339933;">;</span>	
	sum <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>	
	sum <span style="color: #339933;">+=</span> pre_temp<span style="color: #009900;">&#91;</span>channel<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><span style="color: #666666; font-style: italic;">//累加</span>
	sum <span style="color: #339933;">+=</span> pre_temp<span style="color: #009900;">&#91;</span>channel<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
	sum <span style="color: #339933;">+=</span> pre_temp<span style="color: #009900;">&#91;</span>channel<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
	sum <span style="color: #339933;">+=</span> pre_temp<span style="color: #009900;">&#91;</span>channel<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>	
	sum <span style="color: #339933;">&gt;&gt;=</span> <span style="color: #0000dd;">2</span><span style="color: #339933;">;</span>	<span style="color: #666666; font-style: italic;">//求均值</span>
	<span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span>uint16<span style="color: #009900;">&#41;</span>sum<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>从以上程序中可以看到，在中位值滤波中连取十个值，取中间四个有效，将这四个值累加求均值后加入到递推滤波算法的队列中，再累加求平均值后才作为最终有效值返回。在程序中，累加值个数都取四，是为了求均值时可以使用移位的方法来快速求平均值。</p>
<p>在嵌入式系统中，资源和效率始终是程序员不断追求的，求平均值时使用除法运算需要三到四个指令周期，如果使用移位操作同样可以达到除法的效果，但只要用一个指令周期，节省了CPU时间。同样地，递推入列的时候采用的是四个赋值语句，相比循环语句经编译器编译后，四个赋值语句执行效率更高。软件滤波的效果请参考图7-1。</p>
<div id="attachment_163" class="wp-caption aligncenter" style="width: 566px"><a href="http://www.stars625.com/firefighterdata.html/firefighterdata-2" rel="attachment wp-att-163"><img src="http://www.stars625.com/wp-content/uploads/firefighterdata.jpg" alt="灭火机器人软件滤波算法示意图" title="灭火机器人软件滤波算法示意图" width="556" height="317" class="size-full wp-image-163" /></a><p class="wp-caption-text">灭火机器人软件滤波算法示意图</p></div>
<p>由上图可以看出初始采样值波动比较大，峰峰值达到42，对实际距离的判断可能会有5cm左右的误差，经过软件滤波后峰峰值仅为1，大大提高了转换值的准确性，增强了系统的稳定性。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stars625.com/firefighterdata.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
