最新日志

发表于:2008-5-22 15:52:54
标签:匠人手记  地震  灾区  赈灾  义拍  捐款  

0

《匠人手记》义拍赈灾活动圆满结束,共筹得善款6911.19元

《匠人手记》义拍赈灾活动圆满结束,共筹得善款6911.19元

上周,匠人在21icbbs举行了一个为期一周的小型的《匠人手记》义拍赈灾活动,在大家的捧场下,该活动已经圆满结束,共筹得善款6911.19元。这些善款已经通过各位活动参与者直接捐献给红十字总会或其它慈善结构了(所有捐款凭证,匠人已经查验)。

让匠人感动的是,这些参加活动的网友中,有的还是学生,也有的居然是来自四川成都的朋友,还有我们21ic网站的站长王欣,虽然已经在此之前捐过了,但是还是热心参加了本次义拍再次献出爱心。大家不论收入高低,地域差别,都一样表达了对灾区的支持。

--------------------------------------------------
附件一:活动规则
--------------------------------------------------

为了支援地震灾区,请大家一起献爱心。匠人个人出资购买十本《匠人手记》,并承担邮费,用于本次义拍活动。

1、义拍时间:截止到2008年5月21日20时(以21ic的系统时间为准)。

2、义拍物品:十本匠人亲笔签名盖章的《匠人手记》,邮费由匠人承担。

3、竞价规则:每本书的起拍价格为39元。竞拍者在本贴下面跟贴,直接报价。在截止时间之内,出价最高的十位网友,竞拍成功。如果出现同样的竞价,则先出价者优先。

4、捐款方式:义拍得到的钱直接捐献,匠人不过手。竞拍成功者,在5月21时20点之后,以个人名义直接给“中国红十字会总会”(或其他公共慈善结构)汇款。并向匠人出示汇款凭条。匠人查验后负责寄书。

5、捐款要求:竞拍人、捐款人与收件人必须为同一个人。并且必须在竞拍成功后的3天内完成捐款。否则视为弃权。


--------------------------------------------------
附件二:竞拍名单
--------------------------------------------------

(全部竞拍者(一共12个人)的捐款凭证已经收到。匠人原本打算义拍10本,看到大家这么热心无私,故决定,对所有参加本次活动者都寄送《匠人手记》签名版本,书已经于5月22日发出,统一走中通快递,单号如下)
21IC       5000元   (快递单号:680027582234)
wujiarui   300元    (快递单号:680027582243)
栏杆       203元    (快递单号:680027582236)    
救火车     201.19元 (快递单号:680027582240)
aihe       200元    (快递单号:680027582237)
lfzabc     200元    (快递单号:680027582239)
ljdcom     200元    (快递单号:680027582242)
老狼       200元    (快递单号:680027582241)
silentband 120元    (快递单号:680027582244)
lpf336     119元    (快递单号:680027582229)
古道热肠   118元    (快递单号:680027582235)
flash607   50元     (快递单号:680027582238)

--------------------------------------------------
附件三:义拍的《匠人手记》照片
--------------------------------------------------

图一:《匠人手记》签名版

图片二:包装好的快递信封

点击此处查看原文 >>

系统分类: 自由话题   |    用户分类:    |    来源: 原创

评论(1) | 阅读(25)
发表于:2008-5-14 22:57:11
标签:地震  

4

心灵的震撼——写在512地震之后(匠人原创)

心灵的震撼——写在512地震之后(匠人原创)

一、

匠人终于决定写点什么了。在已经过去2天零8个小时的此刻。

人总是健忘的,在未来的某个时刻,我们是否还会记得这几天的感受呢?

也许当一切都过去后,我们会淡忘,全心全意地投入新的生活中去。

但是历史总会留下痕迹。就让这篇帖子来记载吧。

 

二、

震动,来得那么突然。那是在2008年5月12下午的某一瞬间。突如其来的晕眩袭击了匠人。当时,匠人的第一反应,居然是以为莫非是前一天晚上睡得太晚了,导致精神恍惚。

但紧接着,发现不对劲了。匠人感觉到整个大楼在摇晃。这是在21楼。

当“地震”这两个词跳入匠人的脑海时,大楼的警报铃声响起了;整个公司人员全部反应过来。

一阵短暂的惊慌失措之后,不知谁喊了一句:“快下楼,走楼梯。”于是同事们纷纷奔楼梯而去。

匠人最终选择了留下,和少数几个同事。留下,倒不是因为勇敢,只是凭直觉判断,21楼这么高,要跑肯定来不及,还不如坐观其变。实在不行找个桌子钻下去得了。

当晃动结束后,透过窗户看出去,也没有看到任何房屋倒塌的迹象。估计也就没事了。

 

三、

然后,给家人打电话问平安。

然后,上网了解真相。

Q群里已经是炸开了锅。

出乎匠人意料的是,Q里面的天南地北的网友居然都说感受到了地震。

太恐怖了!

窗外,响起了救护车和救火车的警笛声。

很快,真实信息传来,原来是四川汶川发生7.6级地震(后来又修正到7.8级),波及全国大部。

从四川到匠人所在的上海,一千多公里,地震波传导速度为8公里/秒。按这个速度衡量,当上海感受到震动时,其实灾难已经发生好几分钟了。但没想到的是,地震波还是跑赢了电磁波。

几十秒的摇晃,让匠人和同事们不适了好几个小时。头晕目眩、有呕吐感。大概类似于晕船的感觉。

再上网看信息。

在灾害没有展现它狰狞的面目前,网友们似乎还挺轻松,大家甚至互相还在打趣。

似乎还没有意识到在那个偏僻的山谷里,已经经历了一轮生死!

没事啦,该干嘛干嘛去吧。

 

四、

再次被震撼,是在初步的伤亡和受灾人数传来时。

突然发现中国人确实挺多的。在那个从来没有听说过的地方,居然也住着那么多人!

9000多条鲜活的生命,他们就这样变成了冰冷的统计数据。而且,谁都知道,这只是开始……

神经就这样被麻木了。

生命有时就是那么渺小,每一个人的逝去,仅仅是让那张死亡名单做一次增量运算。

那就等待,等待命运最终的判决吧。

 

五、

当温总理紧赶慢赶地赶到现场,拿着话筒对废墟里的学生喊话时,匠人没有感动;

当各路明星开始纷纷解囊捐款时,匠人没有感动;

当一个护士工作10多个小时救护伤员,却没精力去过问她自己孩子的安危时,匠人没有感动;

当一个校长忙着在废墟扒拉他的学生,他听到自家老丈人遇难的噩耗只能无奈地按下悲伤时,匠人没有感动;

也许,匠人的神经已经被地震的次声波震伤了吧……

直到那一刻……

在那堵摇摇欲坠的危墙下,当那位消防战士跪下,对拖着他的人说:“你们让我再去救一个,求求你们让我再去救一个!我还能再救一个!”

那一刻,匠人感觉到,神经恢复了。

一股莫大的悲哀,漫上了心头!

欲哭无泪!

如果说两天前的震撼感受是来自身体,那么,这次就是心灵的震撼!

而这篇帖子,是否能够承载这生命之重!?

把希望留给明天吧,就此搁笔。

 

点击此处查看原文 >>

系统分类: 自由话题   |    用户分类:    |    来源: 原创

评论(3) | 阅读(452)
发表于:2008-5-10 22:20:42
标签:匠人手记  上海书城  

1

上海书城暗访记

上海书城暗访记


匠人第一次暗访上海书城,是在4月26日。那天正好是北航编辑晓柏来沪。匠人上午去与晓柏进行地下接头(接头暗号是:“兄弟,你有《匠人手记》吗?”),中午顺带着小小地腐败了一下。下午分道扬镳后,匠人就跳上一辆开往人民广场的BUS,直奔福州路的上海书城而去。

结果令匠人失望的是,在书城里根本没有看到《匠人手记》的影子。匠人不甘心,又屁颠屁颠地跑到服务台电脑去查询,居然被告知没有进货(其实,是已经进货了,只是还没有上架,所以电脑上也查不出来)。就这样,第一次暗访以失败告终。

转眼半个月过去了,其间匠人接到线人举报,说是书城里已经上架了。于是匠人又跃跃欲试准备再入虎穴一探究竟。

估摸着这回不会扑空了,为了避免被人当场识破引起现场混乱,匠人一度还想着,是不是该戴个墨镜什么的呢,呵呵。

于是沐浴斋戒三天,选了个黄道吉日(也就是周六——今天)。匠人整装出发了。

一路无话,来到书城。有了上次的经验,匠人已是轻车熟路,直接乘电梯奔5楼的单片机专区而去。嘿嘿,这次果然没有让匠人失望。很快在专区里看到了《匠人手记》,像是待嫁新娘,静静地躺在那里……

看到书后,匠人心中一块石头“吧嗒”落地。看看这个区域读者也不多,估计时间还早,于是匠人就又在第5层其它区域顺便浏览了一下,结果,居然在靠近收银台的斜对面展架上,发现《匠人手记》被当作推荐书籍,堂而皇之地摆放在一堆IT类书中。匠人晕……

至此,第一个目标基本达成。唯一的遗憾,是没有看到所谓的X展架。据说北航为了宣传这套丛书,特意制作了大幅“易拉宝”(宣传海报),供放在书店里宣传。

可惜匠人找遍了整个书城,也没有看到这传说中的易拉宝,莫非被书店的店长拿回家去糊墙了?

匠人暗访的第二个目的,是要统计一下现场的销售情况。于是匠人故意在该书附近逗留了许久,暗暗观察往来购书的读者。(呵呵,有点像是神探008哦)。当然了,为了避免让保安起疑,以为匠人是个不良分子。匠人只好每隔一段时间,就跑到隔壁的科普专区,断断续续抽空把霍金的《时间简史》给通读一遍。(免费趁了顿书看,呵呵)。

经过小半天的曲折间隔性的暗探。匠人一共发现了3位读者购买了这本《匠人手记》(不排除有漏网之鱼),比例还是很高的哦。两男、一女。看年龄都不是很年轻,应该不是经常上网的那种。另外,他们都还分别选购了一两本其他单片机的书。由此推论,他们并不是“酱粉团”的成员,不是专程来购买这本书的。能够从众多的书籍中选中《匠人手记》,说明群众的眼光还是雪亮的,哈哈。这给了匠人很大的鼓舞。

到了中午,匠人的肚子开始提意见了。看来只好放弃阵地、撤退。悄悄的我走了,正如我悄悄的来;我挥一挥衣袖,不带走一本手记……

对了,最后再补充一句:上海书城里正在搞“红五月”促销活动,北航所有书籍全部挥泪斩仓、割肉放血、跳楼大甩卖,以85折出售。这应该算是个好消息吧,呵呵。

点击此处查看原文 >>

系统分类: 单片机   |    用户分类:    |    来源: 原创

评论(3) | 阅读(168)
发表于:2008-5-10 0:56:06
标签:匠人手记  书友会  

2

网络——互动的力量

在写完《出书的那些日子——写在《匠人手记》上市之后》一文之后,匠人有一种意犹未尽的感觉,写作的冲动仍旧激荡的心胸中。而一旦打开博客进入后台,准备写点什么时,又不知道该写些什么?

 

是啊,再写些什么呢?这种“老王卖瓜——自卖自夸”的东西已经写了不少了。而那没有表达的东西,究竟隐藏在思想的哪个犄角旮旯里,等待匠人去挖掘呢?

 

也许、大概、或者、可能、一定是有一种神秘的力量,它被匠人忽视了……

 

与北航的晓柏仍旧保持着良好的沟通。昨天哪家书店又追加订单啦,今天又在哪个研讨会上被热力推荐啦,明天又要在哪里安放易拉宝宣传展示啦。每一点“绝密情报”,匠人都会在第一时间得到“内线通报”;

 

同时,在21IC社区里、在《匠人的百宝箱》里、在EDN《匠人手记》书友会里、在书友会Q群里。所有的网友、书友,形成一个巨大的“谍报网”。每天源源不断地反馈着信息:哪里的书店被卖空了,哪个网站上书又上架了。(见《哈哈,匠人的书在china-pub上看到了 》、《匠人手记 当当终于有货了!》、《今天在书店看到匠人的书了》、《网友拍的艳照——上海书城里的《匠人手记》》)。这些信息又被匠人及时收集到《《匠人手记》购书全攻略》,为更多人提供了便捷的渠道;

 

那些已经“先下手为强”买到这本书的书友,更是齐心协力发扬了“大家来找茬”的精神,帮助找出并分析书中的大大小小的BUG,很快便汇总成了《《匠人手记》勘误表》。更多关于书中内容的讨论、答疑也在书友会小组及Q群火热进行中(见《散转 是什么意思啊!》、《关于51单片机的指令周期的一些讨论  》、《关于手记12例程中宏的定义补充说明 》);

 

对这本书以及对匠人本人的评论,正在通过各种渠道陆续涌现。真可谓“鲜花与砖头齐飞”。(见《网络互动增添活力,博客改变出版格局 》、《匠人与周立功 》)。

 

沟通如此畅通,反馈如此及时,信息如此透明。似乎从来还没有哪本单片机书,能够让编辑、作者、读者以及销售商,相互之间,这么紧密无间地结合在一起。

 

网络,让这一切变成了可能。

 

网络——这就是那种“神秘的力量”罢。

 

——互动的力量。

 

也许、大概、或者、可能、一定是!

点击此处查看原文 >>

系统分类: 单片机   |    用户分类:    |    来源: 原创

评论(2) | 阅读(143)
发表于:2008-5-1 0:06:26
标签:匠人手记  

1

出书的那些日子——写在《匠人手记》上市之后

出书的那些日子——写在《匠人手记》上市之后

在忙碌了两个月之后的2008年4月份的最后一个晚上,夜已深。

匠人独自静坐电脑前,细细回顾这本《匠人手记》的出书经历,生出许多感慨、感叹、感动、感谢……

匠人无法自己去评价这本书的价值,这需要读者和网友们自行去评判。但毫无疑问,《匠人手记》的宣传工作是非常成功的。这不得不归功于《匠人手记》上市过程中各路朋友们的巨大支持。

首先,是EDN网站为本书提供了网络宣传平台,他们协助匠人成立《匠人手记》EDN书友会,举办了一系列的网上优惠签名售书、E币换书活动。并免费在《EDN杂志》上刊登整副广告宣传。

同时,21IC网站也慷慨出资购买了50本《匠人手记》,赠送给参加2008年4月47日上海网友聚会的网友,以实际行动支持匠人。

另外,还有素不相识的网友慷慨捐献Q群,成立了4个 《匠人手记》书友会Q群 。而目前,已经有2个群爆满。还有更多的网友,通过各种方式,互相奔走相告,为本书做义务“书托”。

正是因为有了上述这么多朋友的合力宣传造势,《匠人手记》上市伊始,就不负众望,迅速从众多同类书籍中脱颖而出,取得不错的效果:

EDN网站的200本签名预售,早早地预订一空,不得不另外追加100本用作E币换礼活动。

而在国内最大的计算机书籍销售网站CHINA-PUB(互动出版网)上,《匠人手记》的势头也是非常良好。上架仅一周,就在927种单片机类别书籍中,销量排名已经飙升到第二位,而受关注程度更是排名第一。

当当网则更离谱,上架两天就卖空了,缺货至今……

淘宝网上,已经有15家商品在同时热卖;还有更多的网上、网下书店,也在热卖中。

但即使这样,似乎仍然无法满足网友们的急切渴望。在《匠人手记》上市的头一周内,他们打爆了书店和快递公司的电话。有些网友,甚至为了这本书,花费大量时间奔波在往返于书店的路上(见《淘书手记》 ) ……

这一切,都出乎匠人的意料……

匠人只能,再次地,感慨、感叹、感动、感谢……

点击此处查看原文 >>

系统分类: 单片机   |    用户分类:    |    来源: 原创

评论(2) | 阅读(200)
发表于:2008-4-22 20:30:00
标签:匠人手记  

3

提醒各位书友,最近逛书店时最好带个相机去

这样,一旦发现书店里有《匠人手记》,可以立马拍张照片回来上传到小组。呵呵

点击此处查看原文 >>

系统分类: 单片机   |    用户分类:    |    来源: 无分类

评论(1) | 阅读(325)
发表于:2008-4-22 16:27:00
标签:无标签

2

IIR滤波器零相位数字滤波及其应用

IIR滤波器零相位数字滤波及其应用
作者姓名: 樊新海 安钢 张传清
所属杂志:《国外电子测量技术》杂志
所属期号: 2005第8期
摘要: 本文介绍了一种利用Delphi7实现数字滤波器零相位滤波的方法,与一般差分滤波方法相比,该方法不仅可以避免相移,而且还能改善起始部分的波形畸变,这一点在信号处理中具有重要的应用价值。
关键词: 虚拟仪器信号处理零相位数字滤波

Zerophase Digital Filter and Application
Fan Xinhai  An Gang  Zhang Chuanqing

Abstract: This paper introduces a method to realize zerophase filtering for digital filters using Delphi7. Comparing with general difference filter, the zerophase digital filter can not only avoid phaseshifting, but also improve the wave aberration of section start. This method has important practical value in signal processing.
Keywords: virtual instrument, signal processing, zerophase digital filtering.

0引言
在动态测试信号处理过程中,滤波器是常用的测试仪器之一。它常被用于抗混滤波,以避免傅立叶变换时在频域产生混叠,或从具有多种频率成分的复杂信号中,将感兴趣的频率成分提取出来,而将不感兴趣的频率成分衰减掉。在传统测试仪器中,滤波器的功能通常需要依靠硬件系统来实现。
随着数字信号处理技术的不断完善,计算机硬件技术的日新月异以及软件技术飞速发展,测试仪器系统的设计思想发生了重大改变。部分传统的专用测试设备会逐步被以计算机和应用软件为核心的虚拟仪器所代替\[1\]。虚拟仪器的出现标志着“软件即仪器(The soft is the instrument)”时代的到来。在计算机辅助测试系统(CAT,Computer Aided Test)中,以往模拟滤波器(AF,Analog Filter)的功能,可用数字滤波器(DF,Digital Filter)来替代。数字滤波器的实现不但比模拟滤波器容易的多,而且还能获得较理想的滤波器性能。

2数字滤波器的时域描述与分类
对于一个线性移不变(LSI,Linear Shift Invariant)离散时间系统,如图1所示,可用如下差分方程表示:y(n)+∑Nk=1a(k)y(n-k)=∑Mr=0b(r)x(n-r)(1)式中a(k),b(r)为方程系数。

图1LSI系统
如果a(k),k=1,2,Λ,N不全为零,该系统为无限冲击响应(IIR)系统。若a(k)均为零,并令b(0)=1,则y(n)=∑Nr=1b(r)x(n-r)+x(n)(2)该系统为有限冲击响应(FIR)系统。
由此,数字滤波器在从实现方法上,有IIR滤波器和FIR滤波器之分。这两类滤波器无论在性能上,还是在设计方法上都有着很大的区别。IIR数字滤波器与FIR滤波器相比,前者保留了模拟滤波器的优点,幅频特性较好,但存在相位失真。后者相频特性较好,可实现线性相位,但在相同指标要求下要比前者的阶数高的多。

3差分数字滤波及其存在的问题
IIR数字滤波器的设计方法主要有双线性Z变换法和冲激响应不变法;FIR数字滤波器的设计方法主要有窗函数法、频率抽样法和切比雪夫逼近法等。有关数字滤波器设计的详细方法见文献\[2\],这里就不再赘述。
对于设计好的滤波器,确定出滤波器的系数,通过对差分方程式(1)或式(2)的叠代算法,可以实现IIR滤波器或FIR滤波器的数字滤波。考虑到程序的通用性,这里就按式(1)编写一个差分滤波函数DiffFilter(b,a,x),调用参数为三个数组,b用于存放滤波器的系数b(r)(r=0,1,…,M);a用于存放滤波器的系数a(k)(k=0,1,…,N),且a(0)=1;x用于存放输入信号,返回后用于存放滤波后的输出信号。如果将调用参数a均赋零值,则可实现FIR滤波器的数字滤波。
在此,用一实例进行说明。图2为某型坦克发动机转速1000rpm时,在排气口测得的噪声信号(采样点数1024,采样频率4KHz)。从信号的波形可以看出,它具有一定的周期性,主要是以发动机周期性排气产生的噪声为主。

图2某型坦克发动机噪声信号
采用窗函数(Hanning窗)法设计出某200阶FIR低通滤波器,截止频率为200Hz,分析频率为2KHz,其幅频曲线及相频曲线如图3所示。

图3低通滤波器的幅频特性和相频特性
利用该FIR低通数字滤波器对图2所示发动机噪声信号进行差分滤波,滤波后的波形如图4所示。

图4差分滤波后的发动机噪声信号
对比图3和图4所示波形可以看出,差分滤波后,信号变得“光滑”了许多,原来的“毛刺”被滤掉了。但同时也可以看出差分滤波方法存在两个问题:一是滤波后的信号相对与原信号而言,发生了相移;二是滤波后的信号在起始部分,波形畸变较为严重。在信号处理中,如果对信号的相位有特殊的要求,相移问题需要引起高度的注意。而起始部分的畸变是由于叠代过程中,没有考虑滤波器的初始条件,刚开始点数少,没能用到滤波器全部系数的缘故。大多情况下,这种畸变可以接受,但当数据较短,而滤波器的阶数又较高时,这种畸变会带来较大的负面影响。
如果输入信号为一单位脉冲信号,即
x(n)=1,n=1
0,n≠1
那么,滤波器的输出为其脉冲响应。本文所用200阶FIR低通数字滤波器的脉冲响应如图5所示。

图5滤波器的脉冲响应3零相位数字滤波算法及其实现
3.1零相位数字滤波的算法
为了克服差分数字滤波中存在的上述两个问题,可以采用一种零相位滤波的方法,该方法的基本思路是:先确定出滤波器的初始条件,然后将原序列的首尾进行扩展,把扩展后序列通过滤波器,将所得结果反转后再次通过滤波器,最后将所得结果再反转,并去掉首尾的扩展部分,即可得到零相位滤波后的输出序列\[3\]。本文采用四次差分滤波方式给出一种便于实现的详细算法,假设输入信号为x(n),n=0,1,…,P。
(1) 编写差分滤波函数DiffFilter(b,a,x),调用参数如前所述。
(2) 对于IIR滤波器通常有M=N,求滤波器的初始条件e(q),q=0,1,…,N-1,这里记E=[e(0),e(1),…,e(N-1)]T,则有
E=1+a(1)1-1…0
a(2)01…0
MMMOM
a(N)00…-11× b(1)-b(0)a(0)
b(2)-b(0)a(1)
M
b(Nn)-b(0)a(N)(3)
(3) 对原输入序列x(n)的首尾进行扩展,在x(n)的前面添加3N个数,在后面添加3N个数,扩展后的序列记为x′(n),n=0,1,…,P+6N。
x′(n)=2x(0)-x(3N-n)
x(n-3N)
2x(P)-x(P-1-(n-P-3N-n))
n<3N
3Nn<P+3N
P+3NnP+6N(4)
(4) 进行正向滤波:先用b,a和x′(n)调用DiffFilter(b,a,x)函数,计算x′(n)通过
H(z)=∑Mm=0b(m)z-m/(1+∑Mm=1a(m)z-m)(5)
的输出y′(n),然后生成一长度为P+6N+1的单位脉冲信号h(n),用z,a和h(n)调用DiffFilter(b,a,x)函数,计算h(n)通过
H(z)=∑M-1m=0y′(0)e(m)z-m/(1+∑Mm=1a(m)z-m)(6)
的输出y′(n),并记y(n)=y′(n)+y″(n)。
(5) 进行反向滤波:将正向滤波结果反转,记x′(n)=y(P+6N-n),重复步骤4°,得到反向滤波后的结果。
(6) 将反向滤波的结果反转,并删除首尾的扩展部分,即可得到最后的滤波结果。
3.2零相位数字滤波的实现
Borland公司推出的Delphi编程语言,具有合理的单元化结构、优化的编译环境,开发速度快、编程效率高。在实现同样功能的情况下与其它语言相比,不仅编写的代码量少、程序可移植性强,而且还有许多优秀的组件包可供使用。最为方便的是可以使用动态数组,随时能够改变数组的长度,这一点非常适合数字信号处理。
作者利用Delphi7编写了利用双线性Z变换法设计Butterworth型IIR滤波器和利用窗函数法设计FIR滤波器,以及差分数字滤波算法和零相位数字滤波算法应用程序,并作为集成测试软件平台的一个虚拟仪器。其中零相位数字滤波算法程序设计流程如图6所示。

图6零相位数字滤波算法的流程图
图7所示为图2所示信号零相位数字滤波后的波形,通过与原信号(图2)和差分滤波后的信号(图4)对比不难看出:零相位数字滤波后的输出与原信号中的相位基本一致,并且起始部分没有畸变。但不可否认,零相位数字滤波算法相对于普通差分滤波算法计算量要大许多,但以目前计算机的运算能力,计算量稍大并不是什么主要问题。

                                     图7零相位滤波后的波形

4结束语
本文介绍了一种利用四次差分滤波算法,实现零相位数字滤波的方法,并利用Delphi7编写了应用软件。通过与普通差分滤波器的实例对比分析,说明零相位数字滤波不仅能够避免相移,而且还能改善差分滤波起始部分的波形畸变。这一点在数字信号处理中具有重要的应用价值。
参考文献
\[1\] 程 虎. 虚拟仪器的现状和发展趋势.现代科学仪器,1999(4):6~9
\[2\] 胡广书编.数字信号处理—理论、算法与实现.清华大学出版社,1997
\[3\] 纪跃波,秦树人,汤宝平.零相位数字滤波器.重庆大学学报,2000.23(6):4

点击此处查看原文 >>

系统分类: 单片机   |    用户分类:    |    来源: 无分类

评论(1) | 阅读(160)
发表于:2008-4-22 16:25:00
标签:无标签

2

FIR 滤波器FAQ

Part 1: Basics

1.1 什么是FIR滤波器?

  FIR 滤波器是在数字信号处理(DSP)中经常使用的两种基本的滤波器之一,另一个为IIR滤波器.

1.2 FIR代表什么?

  FIR是有限冲激响应(Finite Impulse Response)的简称.

1.3 FIR(有限冲激响应)中的有限该如何理解?

  冲激响应是有限的意味着在滤波器中没有发反馈.

1.4 FIR 怎么发音?

  有些人直接读字母音 F-I-R; 也有人发做fir的音[:], fir是冷杉树.

1.5 FIR 滤波器外有什么其他选择?

  DSP滤波器还有一类: IIR(无限冲激响应,Infinite Impulse Response).IIR滤波器使用反馈,因此当信号输入后,输出是根据算法循环的.

1.6 FIR滤波器与IIR滤波器比较?

   每一种都有优缺点.但总得来说, FIR滤波器的优点远大于缺点,因此在实际运用中,FIR滤波器比IIR滤波器使用的比较多.

1.6.1 相对于IIR滤波器, FIR滤波器有什么优点?

  相较于IIR滤波器, FIR滤波器有以下的优点:

  * 可以很容易地设计线性相位的滤波器. 线性相位滤波器延时输入信号,却并不扭曲其相位.

  * 实现简单. 在大多数DSP处理器, 只需要对一个指令积习循环就可以完成FIR计算.

  * 适合于多采样率转换,它包括抽取(降低采样率), 插值(增加采样率)操作. 无论是抽取或者插值, 运用FIR滤波器可以省去一些计算, 提高计算效率. 相反,如果使用IIR滤波器,每个输出都要逐一计算,不能省略,即使输出要丢弃.

  * 具有理想的数字特性. 在实际中,所有的DSP滤波器必须用有限精度(有限bit数目)实现,而在IIR滤波器中使用有限精度会产生很大的问题,由于采用的是反馈电路,因此IIR通常用非常少的bit实现,设计者就能解决更少的与非理想算术有关的问题。

  * 可以用小数实现. 不像IIR滤波器,FIR滤波器通常可能用小于1的系数来实现。(如果需要,FIR滤波器的总的增益可以在输出调整)。当使用定点DSP的时候,这也是一个考虑因素,它能使得实现更加地简单。

1.6.2 相较于IIR滤波器, FIR滤波器的缺点是什么?

  相比较于IIR滤波器, 有时FIR滤波器为了得到一个给定的滤波响应特性,需要花费更多的存储器或者计算. 当然,用FIR滤波器去实现某些响应也是不实际的.

1.7 在描述FIR滤波器的时候,都要提到什么术语?

  * 冲激响应 - FIR滤波器的冲激响应实际上是FIR的系数.

  * 抽头(Tap) - FIR的抽头是系数或者延时对.FIR抽头的个数(通常用N来表示)意味着:1)实现滤波器所需要的存储空间, 2) 需要计算的数目, 3) 滤波器能滤掉的数量, 实际上,越多的抽头意味着有更多的阻带衰减, 更少的波纹,更窄的滤波等等.

  * 乘累加 (MAC) - 在FIR方面考虑,MAC是指把延时的数据采样与相应的系数相乘,然后累加结果。通常,FIR每一个抽头都需要一个MAC。大多数DSP微处理器实现MAC操作都是单指令周期。

  * 跃迁带(Transition Band) -在通带和阻带边沿之间的频带。跃迁带越窄,需要更多的抽头去实现滤波器。也有说,小的跃迁带就是一个sharp滤波器。

  * 延时线- 一组存储器单元,实现在FIR计算中的Z^-1延时。

  * 环形缓存 - 一个特殊的缓存,是首尾相连的。通常由DSP微处理器实现。


Part 2: Properties

2.1 线性相位

2.1.1 FIR滤波器和线性相位之间有什么关系?

  大多数的FIR滤波器是线性相位滤波器. 当需要设计线性相位滤波器时, 通常使用FIR滤波器.

2.1.2 什么是线性相位滤波器?

  线性相位是指滤波器的相位响应是频率的线性函数(在+/-180度)。因此滤波器的延时后,所有的频率相位相同。因而滤波器不会产生相位和延迟扭曲。在某些领域,比如数字解调器,没有相位或者延迟扭曲是FIR滤波器相对于其他IIR和模拟滤波器的一个关键优点

2.1.3 线性滤波器的条件是什么?

  FIR滤波器经常被设计成为线性相位的,当然不是必须要这么做。如果滤波器的系数是关于中心系数对称的,也就是说第一个系数和最后一个系数相同,第二个系数和倒数第二个相同,那么FIR滤波器就是线性的。有奇数个系数的FIR滤波器,中心单独的系数没有对应的。

2.1.4 什么是线性相位FIR滤波器的延时?

  非常简单的公式: 给定FIR滤波器有N个抽头,那么延时是(N - 1) / (2 * Fs), 这里Fs是采样频率. 比如, 21抽头的线性相位滤波器运行在1kHz, 那么延时就是(21 - 1) / (2 * 1 kHz)=10 微秒.

2.1.4 除了线性相位,还可以选择什么?

  当然是非线性的了。实际上,最流行的选择是最小相位滤波器。小相位滤波器,也叫最小延时滤波器,比线性相位滤波器具有更少的延时,当两者的幅度响应相同时以非线性相位特性。低通滤波器在它的冲击响应中心有最大的系数。而最小相位滤波器的最大系数在开始部分。

2.2 频率响应

2.2.1 什么是FIR滤波器的Z变换r?

  对于N抽头的滤波器, 系数为h(k), 那么输出由:        

  y(n)=h(0)x(n) + h(1)x(n-1) + h(2)x(n-2) + ... h(N-1)x(n-N-1),

滤波器的z变换就是:       

  H(z)=h(0)z-0 + h(1)z-1 + h(2)z-2 + ... h(N-1)z-(N-1) , or

        http://blog

2.2.2 FIR滤波器的频率响应公式是什么?

  H(z)中的变量z为连续的复数变量,可以描述为 z="r"·ejw,这里r是幅度,w是z的角度。如果令r=1,H(z)就变成了滤波器频率响应H(jw)。这也就意味着替代z为ejw,得到了滤波器频率响应H(w)。       

  H(jw)=h(0)e-j0w + h(1)e-j1w + h(2)e-j2w + ... h(N-1)e-j(N-1)w , or

使用欧拉公式, e-ja=cos(a) - jsin(a), 我们可以把H(jw)写成矩形表示:      

  H(jw)=h(0)[cos(0w) - jsin(0w)] + h(1)[cos(1w) - jsin(1w)] + ... h(N-1)[cos((N-1)w) - jsin((N-1)w)] , or

   http://blog

2.2.3 能用离散傅立叶变换(DFT)来计算FIR的频率响应么?

  可以。对于N抽头的FIR,可以得到N  evenly-spaced points of the frequency response by doing a DFT on the filter coefficients.但是,为了得到任意频率的频率响应,需要使用上边的公式。

2.2.4 FIR滤波器的DC增益指的是什么?

  DC(0 Hz)输入信号包含每个采样都为1.0。通过延时线后,输出是所有系数的和。因而,在DC处滤波器的增益就是所有系数之和。  

  可以通过上边的公式进行验证。问我们设w为0, cos项就一直为1,而sin项则一直为0。因此频率响应就变成了:

       http://blog

2.2.5 如何调整FIR滤波器的增益?

  简单地在系数上乘上因子.

2.3 数字性质

2.3.1 FIR滤波器是固有稳定的?

  是的,因为没有反馈,任何有限的输入产生有限的输出。

2.3.2 什么使FIR滤波器的数字性质变好?

  缺少反馈是关键。在计算机中实现FIR滤波器时,每个计算都产生数字错误。由于FIR滤波器没有反馈,因此不能够记住以前的错误。相反,IIR滤波器的反馈可能导致错误的积累。这个实际的影响就是,可以用更少的bit去实现与IIR滤波器相同精度的滤波器。比如,FIR滤波器通常用16位来实现的话,IIR滤波器就通常需要32位,或者更多。

2.4 为什么通常在多采样率系统中采用FIR滤波器而不采用IIR滤波器?

  因为只有一小部分的计算需要用减采样或者插值滤波器来实现。

  由于FIR滤波器不使用反馈,因而只有那些实际需要使用的输出才需要计算。比如,在减采样的时候(N个输出中只有一个有效),那么其他的N-1输出就不会进行计算。类似的,对于插值滤波器(在采样点中插入0来提高采样率),你不必实际地用FIR滤波器乘以系数,求和得到,你只需要忽略和这些值有关的乘加(因为它们不会改变结果)。

  相反,因为IIR滤波器使用反馈,每个输入都必须使用,每个输入必须计算,因为所有的输入和输出对滤波器的反馈都有影响。

2.5 有哪些特殊的FIR滤波器?

  Aside from "regular" and "extra crispy" there are:

  *  矩形 -矩形 FIR 滤波器是每个系数都是1.0的简单的滤波器。因而对于N个抽头的矩形滤波器,它的输出仅仅是过去N个采样之和。由于矩形FIR只能实现加法,因此当乘法器实现比较昂贵时,在硬件实现中会考虑。         

  * 希尔伯特变换(Hilbert Transformer) - 希尔伯特变换是把信号相移90度。它们经常被用在给定实数部分,产生虚数部分。  

   * 差分(Differentiator) -差分器的幅度响应是频率的线性函数。现在已经不流行了,但是以前曾经在FM解调器上使用过。 

  *  Lth-Band - 也叫做“Nyquist"滤波器,这些滤波器是在多速率应用中特殊的一类滤波器。主要的卖点是,每L个系数有一个为0,那么就将减少乘累加操作的实现(著名的半带滤波器就是这一种)。 

   * Raised-Cosine - 这是一种特殊类型的滤波器,有时会用在数字数据应用方面。(通带上的频率响应是被上移一个常数的cos形状)。


Part 3: Design

3.1 有哪些设计FIR滤波器的方法?

三种最流行的设计方法:

  • Parks-McClellan: Parks-McClellan 方法( MATLAB里用Remez)是设计FIR滤波器中可能是使用最光的.method (inaccurately called "Remez" by Matlab) is probably the most widely used FIR filter design method. It is an iteration algorithm that accepts filter specifications in terms of passband and stopband frequencies, passband ripple, and stopband attenuation. The fact that you can directly specify all the important filter parameters is what makes this method so popular. The PM method can design not only FIR  "filters" but also FIR "differentiators" and FIR "Hilbert transformers".
  •  Windowing:. In the windowing method, an initial impulse response is derived by taking the Inverse Discrete Fourier Transform (IDFT) of the desired frequency response. Then, the impulse response is refined by applying a data window to it.
  •  Direct Calculation: The impulse responses of certain types of FIR filters (e.g. Raised Cosine and Windowed Sinc) can be calculated directly from formulas.

3.2 如何实际地设计FIR滤波器?

  当然是用FIR设计程序呀. 虽然可以使用手工亲自的方法进行设计滤波器,但是使用FIR滤波器程序比较简单.


Part 4: Implementation

4.1 实现FIR滤波器基本的方法是什么?

  FIR滤波器的结构上包含两个东西:一个是采样点延迟线,一个是系数. 可以由以下方法实现FIR滤波器:

  1. 把输入的采样点放入到延迟线中.

  2. 把延迟线中的数与相应的系数相乘并累加.

  3. 移位, 使下一个输入采样能进入延迟线.

4.2 用C语言如何实现FIR滤波器?

  为了展示众多的方法和技巧,这里提供用C语言实现的FIR滤波器算法。

http://blog fir_algs_1-0.c C 源码

http://blog fir_algs_1-0.zip C 源码( MS Visual C++ 6.0 工程文件)


包括以下功能模块:

  1. fir_basic: 实现基本的FIR滤波器

  2. fir_circular: 说明环行buffer是如何实现FIR的。

  3. fir_shuffle: 一些TI的处理器上使用的shuffle down技巧

  4. fir_split: 把FIR滤波器展开为两块,避免使用环行缓存。

  5. fir_double_z: 使用双精度的延迟线,使可以使用一个flat buffer。

  6. fir_double_h: 使用双精度的系数,使可以使用一个flat buffer。

4.3 用汇编如何实现FIR滤波器?

  FIR滤波器的汇编算法是跟处理器对应的,但是大多数普通的系统会使用一个DSP处理器提供的环行缓存。

  1. 配置环行缓存。加载系数和延迟线指针。然后对每个采样点执行以下操作:

  2. Store the incoming data in the delay line; increment the delay-line pointer.Digital

  3. Clear the multiplier-accumulator.

  4. Loop over all coefficients/delays; accumulate the values obtained by multiplying the coefficients by the delayed samples.

  5. Round or truncate the result as the FIR output.   

  Alternatively, a "shuffle down" method is used in Texas Instruments' older fixed-point processors to implement circular buffers. The processor literally moves each sample delay values by one slot during each multiply-accumulate (via the "MACD" instruction).    

  Each DSP microprocessor manufacturer provides example FIR assembly code in its data books or its application handbooks, so be sure to look at those before you "reinvent the circular buffer".

4.4 如何测试以及实现的FIR滤波器? 

  Here are a few methods:

  •  Impulse Test: A very simple and effective test is to put an impulse into it (which is just a "1" sample followed by at lest N - 1 zeroes.) You can also put in an "impulse train", with the "1" samples spaced at least N samples apart. If all the coefficients of the filter come out in the proper order, there is a good chance your filter is working correctly. (You might want to test with non-linear phase coefficients so you can see the order they come out.) We recommend you do this test whenever you write a new FIR filter routine.
  •  Step Test: Input N or more "1" samples. The output after N samples, should be the sum (DC gain) of the FIR filter.
  •  Sine Test: Input a sine wave at one or more frequencies and see if the output sine has the expected amplitude.
  •  Swept FM Test: From Eric Jacobsen: "My favorite test after an impulse train is to take two identical instances of the filter under test, use them as I and Q filters and put a complex FM linear sweep through them from DC to Fs/2. You can do an FFT on the result and see the complete frequency response of the filter, make sure the phase is nice and continuous everywhere, and match the response to what you'd expect from the coefficient set, the precision, etc."

4.5 在实现FIR滤波器的过程中有什么有用的技巧?   

  FIR tricks center on two things 1) not calculating things that don't need to be calculated, and 2) "faking" circular buffers in software.

4.5.1 如何跳过不必要的计算?   

  First, if your filter has zero-valued coefficients, you don't actually have to calculate those taps; you can leave them out. A common case of this is "half-band" filter, which have the property that every-other coefficient is zero.   

  Second, if your filter is "symmetric" (linear phase), you can "pre-add" the samples which will be multiplied by the same coefficient value, prior to doing the multiply. Since this technique essentially trades an add for a multiply, it isn't really useful in DSP microprocessors which can do a multiply in a single instruction cycle. However, it is useful in ASIC implementations (in which addition is usually much less expensive than multiplication); also, some newer DSP processors now offer special hardware and instructions to make use of this trick.

4.5.2 How do I fake circular buffers in software?   

  When hardware support for circular buffers isn't available, you have to "fake" them. Also, since ANSI C has no construct to describe circular buffers, most C compilers can't generate code to use them, even if the target processor has them.   

  You can always implement a circular buffer by duplicating the logic of a circular buffer in software (and many have), but the overhead can be prohibitive; the circular-fake might take several instructions to implement, compared to just a single instruction to do the multiply-accumulate operation. Therefore you need to fake it.   

  Here are several basic techniques to fake circular buffers:      

  1. Split the calculation: You can split any FIR calculation into its "pre-wrap" and "post-wrap" parts. By splitting the calculation into these two parts, you essentially can do the circular logic only once, rather than once per tap. (See fir_double_z in FirAlgs.c above.)      

  2. Duplicate the delay line: For a FIR with N taps, use a delay line of size 2N. Copy each sample to its proper location, as well as at location-plus-N. Therefore, the FIR calculation's MAC loop can be done on a flat buffer of N points, starting anywhere within the first set of N points. The second set of N delayed samples provides the "wrap around" comparable to a true circular buffer. (See fir_double_z in FirAlgs.c above.)      

  3. Duplicate the coefficients: This is similar to the above, except that the duplication occurs in terms of the coefficients, not the delay line. Compared to the previous method, this has a calculation advantage of not having to store each incoming sample twice, and it also has a memory advantage when the same coefficient set will be used on multiple delay lines. (See fir_double_h in FirAlgs.c above.)      

  4. Use block processing: In block processing, you use a delay line which is a multiple of the number of taps. You therefore only have to move the data once per block to implement the delay-line mechanism. When the block size becomes "large", the overhead of a moving the delay line once per block becomes negligible.

点击此处查看原文 >>

系统分类: 单片机   |    用户分类:    |    来源: 转贴

评论(0) | 阅读(158)
发表于:2008-4-22 10:15:00
标签:pic  

2

PIC单片机引脚中断程序的设计技巧

1 简 述
    所有的中档系列PIC单片机,PORTB端口最高的4个引脚(RB7~RB4)在设为输入模式时,当输入电平由高到低或由低到高发生变化时,可以让单片机产生中断。这就是通常所说的引脚状态变化中断。

    在设计引脚中断程序时,有三个需要特别注意的地方。一是,在清除P0RTB中断标志位RBIF之前,必须安排一条必不可少的,以PORTB端口数据寄存器PORTB为源寄存器的读操作指令。放置这一指令的目的有时并不只是为了读取有用的数据,而是为了取消状态变化的硬件信号,以便顺利清除RBIF标志位,为下一次中断做好准备。二是,由于端口PORTB是引脚电子变化中断,即无论引脚出现上升沿还是下降沿都会产生中断请求,所以必须处理好不需要的虚假中断。三是,一般都利用PIC单片机的引脚功能来检测按键,所以必须处理好按键消抖的问題。

2 引脚中断程序设计
    在主程序里先设置有关的寄存器。
    ◇设置TRISB寄存器,使RB7~RB4相关的引脚处于输入状态;
    ◇如果需要弱上拉,通过OPTION_REG的第7位设置;
    ◇RBIF=O;
    ◇RBIE=1;
    ◇GIF=1。

    响应状态变化后的中断服务程序。
    ◇检查RBIF是否为l,为l则是引脚变化引起的中断;
    ◇调用延时程序,延时20~30 ms,目的是为了按键去抖;
    ◇判断是引脚出现上升沿还是下降沿引起的中断;
    ◇调用按键处理程序;
    ◇读PORTB口的值,取消状态变化的硬件信号;
    ◇清除RBIF标志。

    笔者认为上面程序设计最大的问题是在中断程序里调用延时程序。大家知道,中档PIC单片机只有8层深度的硬件堆栈,在中断里调用于程序出现极易堆栈溢出的情况。另外,PIC单片机中断程序人口只有一个,在响应中断的请求时,PIC单片机就会自动把全局中断的使能位(INTCON的第7位GIF)清除,这样其他中断就暂时不能被响应(此时,如果别的中断发出的中断请求,标志位将一直保留着),直到这个中断程序退出后才会得到响应。这就要求我们设计中断程序的时候必须尽量短,避免调用子程序,更不要在中断里进行复杂的运算。

    下面给出笔者设计程序时的思路。

    当引脚状态变化引起中断时,在中断子程序里首先判断引起中断的原因是不是我们需要的变化引起的中断。如果是,不要在这里延时,而是设置一个标志位,接着清除中断标志,退出中断。中断程序如下:
else if((RBIE&RBlF)==1){ //如果引脚变化引起中断
    if(RB4==0){ //RB4上的按钮接地
    key="1"; //按键标志位置位
    }
    RBIF="0"; //清除引脚中断标志位
    }

    其中,if(RB4==0)语句相当于读取了PORTB端口数据寄存器,取消了状态变化的硬件信号。

    下面详细介绍怎么样进行按键去抖。

    首先,在定时器中断里设置一个lms的时间基准标志位“SYSlms”,每到lms,“SYSlms”便置位。程序如下:
    unsigned char count;
    if((ToIE&TOIF)==1){ //定时器中断
    TMRO+=0x09; //每250μs中断一次
    if(count==4){
    count="0";
    SYSlms="l"; //系统时间标志
    couot++;
    }    

    T0IF=0; //清除时钟中断标志位
    }

    有了这个时间基准,便可以在主程序里进行按键去抖处理了。为了更好地利用这个时间基准,定义一个消息标志SYSTime,笔者把它称作时间消息。为了让这个消息有自我发布和自我消失的功能.定义了如下一个宏:
    bit SYSTime;
    #defincTimeEnahle()SYSTime=0,if(SYSlms){SYSTime=l;SYSlms=0;)

    可以把TimeEnable()放到主程序死循环的任何地方,每当程序执行这个宏,SYSTime就会清零,这就是标志位的自我消失.如果在定时器时间基准标志位SYSlms已经置位的话,SYSTime就会置1,这样别的程序就可以利用这个时间消息了,这就是消息的自我发布。下面就是利用这个时间消息来进行按键延时去抖的,首先看一下按键扫描子程序;
    void seaakey(){
    unsigned char KeyTime,KeyTask;//定义任务时间参数、
    //任务参数
    switch(KeyTask){
    case0:if(key){
    KeyTime="30"; //准备延时30 ms
    KeyTask++; //准备好下一个任务
    kcy="0";
    }
    break;
    case I:KeyTime--; //延时30 ms
    if(KeyTime==0)Key+ask++;
    break;
    case2;if(RB4==o){
    //调按键处理程序
    KeyTask="0";
    }
    else KeyTask="0";//退出任务
    break;
    }
}

    在主程序的死循环中这样用:
    while(1){
    TimeEnable();
    If(SYSTime==1){scankey();)
    //在此可以添加其他程序

    只有有时问消息的时候才执行按键扫描程序。可以看到,进入扫描程序执行第一次的时候,程序首先判断按键标志位有没有置位,置位的话(也就是有按键按下的话),任务时间参数(KeyTime)赋值为30,这是延时30ms,去抖,当然你也可以设置为其他的时间值;同时任务参数 (KeyTask)加1。1ms后,再进入扫描程序,这个时候扫描程序执行casel的语句,这样30次后(延时了30ms),任务参数(KeyTask)加1,值为2。lms后,再进入扫描程序,将执行case 2的语句,首先在这里再次判断是不是按键还在按下,如果是就调按键的处理程序,如果不是。就退出按键扫描程序。在这里,还可以加入按键是否抬起的判断程序。

    这样设计的引脚变化程序,CPU开销小,效率高,不会出现堆浅溢出的问题,提高了系统的实时性。

点击此处查看原文 >>

系统分类: 单片机   |    用户分类:    |    来源: 转贴

评论(0) | 阅读(157)
发表于:2008-4-22 10:14:00
标签:pic  

2

PIC中档单片机的中断总结

与51或者其他系列的单片机相比,PIC单片机的中断机制有其特殊之处,针对我们一些初学者存在的一些问题和疑惑,我在此做一个个人总结,不当的地方,请站友们指正。sO100
     先摘引三个对PIC中断理解的回帖,然后我再对中断活动的过程、应该注意的事项、及一个疑惑进行较详细的总结和解释。
     ---------------
     johnfrank:关于pic中断有些不明白的地方
     借用大虾的程序;
     ;********************中断服务代码
     btfssINTCON,T0IE;判断是否为T0中断
     gotoother_int
     btfssINTCON,T0IF;it’sthetimeofT0int
     gotoother_int
     bcfINTCON,T0IF;是T0中断,清除中断标志
     movlw0x10;微秒的高位字节加上定时时间256x16分频=4096=0x1000的高位(0x10)
     addwfus+1
     gotoend_int
     other_int;可添加其他中断服务代码
     nop;otherisrcodecanbeadded
     ;**********************************
     end_int;恢复现场
     =================
     假如又有新的中断正好在这段程序中间产生
     btfssINTCON,T0IF
     gotoother_int
     bcfINTCON,T0IF
     程序岂不是要出错跑飞了
     johnfrank:
     谢谢你的关注。
     我讲一下自己的理解,权做回答,不当之处,还请站友们指点。
     pic中档单片机系列没有“硬件中断优先级别”(请允许我这样说),含义是指:当内核正在处理当前的中断服务A时,在这个期间里,其他任何中断的产生,只能使其标志位xxIF置1,不能剥夺当前中断服务对CPU的占用权(反应在PC指针不能被新的中断改变指向),必须等到当前中断服务处理A完毕,然后,根据gotoother_int语句的转向,依次判断。若新发生的中断处理代码在中断服务A之后(前、后指代码在ROM中地址顺序,越大越后),则进行新发生的中断处理;若恰好新发生的中断服务代码在刚被处理完毕的中断服务A代码之前,则将不予理会,(即程序指针PC不会在中断处理代码空间中又返回到0004H的入口),等到执行到retfie后返回主程序,然后再次进入中断入口0004H...
     之所以说其无“硬件中断优先级别”是与“软件中断优先级别”对应的,通过中断服务代码对中断标志和IE的检测的先后,可设立优先级。
     当然,准确地说,这是一种顺序,而非级别,呵呵。
     如果了解一下51的中断系统,相信你能更好地理解PIC的中断的级别:
     将会出现你说的情况,当优先级更高的中断来临时,内核将暂时停止当前中断服务,保存当前中断服务的现场,执行优先级更高的中断服务,处理完成后,恢复现场,执行未处理完成的中断服务....,最后,返回主程序。
     小弟讲得有点烦琐,并不形象,可能还有纰漏和谬误之处,请大家指正,相信johnfrank在仔细看书之后,应该可以形成自己的正确看法。
     zdtdl:小弟说两句~~
     简单地说,当系统响应一个中断时,GIE位将被自动清零以禁止其他的中断,在执行中断返回指令RETFIE后系统再自动置GIE位1开放中断。只要不在中断程序中对GIE置1,就不会产生反复进入中断的现象,靠查询方式决定响应谁。PIC也有中断嵌套,可以形成多级嵌套,甚至自身嵌套,不过嵌套的级数绝对不能超过硬件堆栈的深度。
     -------------------------
     PIC中档单片机的中断总结正文
     一、中断活动的过程
     对于PIC单片机来说,一次中断的过程大致有下列阶段:
     为了使得说明形象和直观,本文采用一些诙谐的语句来比喻说明:
     中断请求---------比喻成申请买经济适用房的请求
     中断标志-------一份申请书
     本中断使能xxIE-----本单位领导
     PEIE-------------户口办公室主任
     GIE--------------银行的管理信贷的科长
     1.中断请求:房子太少,儿子要结婚了,得买房了,可资源和财力有限,不能卖商品房,只好按特殊情况处理,写一份申请书(中断标志位IF置1);
     2.本单位领导xxIE看了之后,如果给你盖了一个戳:(即该中断使能位IE=1),那么恭喜你,这份申请书可以提交到更高一级的部门;如果没盖(xxIE=0),那么对不起,先放我这里吧,等我们研究研究好后再说。如果你不开心,要拿回申请书撕掉,呵呵,那么IF=0;你的购房请求之梦破灭;
     3.xxIE领导将根据户口,将这些请求书给分类,一类是外地迁来的户口,提交给户口办公室PEIE主任审查,PEIE主任如果给你盖了个戳(PEIE=1),那么,他将会把申请书提交给银行的GIE科长批准,否则就是放在这里再研究研究或者你要回来撕毁;一类是本地户口,可直接提交给银行的GIE科长批准,然后你将申请书带到GIE科长的办公室。
     4. GIE科长盖了章之后(GIE=1),然后,你就可以拿着申请书去找房地产商要房子了(此时PC指针=0004H),因为GIE科长有很多事情要做,所以他每盖了一次戳之后(注意是一次不是一个,因为也许有多个中断同时发生,也就是说有其他地方的人来请GIE盖戳),就在办公室门外挂了个牌子:请勿打扰。他自己则休息去了,直到接到RETFIE的电话或者有人打他的手机。

  5. 房地产商准备给房子了,不过你最好得先把各项手续给填好,叫5w押金,另外协议阿,合同阿,都得自己搞定,这叫“保护现场”。

  6. 房地产商开始上班了,于是挨个查“申请书”是谁提交的,以便给你安排你预定的房子。这个叫“中断查询”。

  7. 查到是你的后,然后打电话让你过来,带你去看房子,把钥匙给你。这个交“中断处理”。

  8. 钥匙交给你之后,房子你是到手了,不过这份申请书就失效了,房地产商将该申请书销毁。这个叫“清除中断标志”。

  9. 好啦,现在你可以去房地产商自己去要回以前交的押金,身份证啊等等。这个叫“恢复现场”。

  10. 最后,房地产商办完了,让RETFIE小姐打个电话给GIE科长(执行RETFIE指令),GIE科长才起来,把“请勿打扰”的牌子取下,让其他的带着申请书的人进来。当然,如果你的事情还没搞定,GIE科长的关系户打了他的手机(你在办事时-处理中断时,若有GIE被置1),他也会开门取下“请勿打扰”的牌子,让关系户进来,给他盖好章。这下就对不起了,人家有关系,所以你的事情要马上停下来,先等关系户办完他的事情之后,再给你办你的事情。这个叫“中断嵌套”,要注意GIE科长有8个关系户(硬件堆栈的深度为8级)哦。


二、需要注意的问题:


1. 中断现场的保护(可以参考以前的帖子,在xieyubing版主的指点下,有恰当的例子);

2. 初次上电复位、电源跌落复位和其他情况下的复位,均使得全局中断位GIE和其他中断使能位xxIE=0;

3. 中断标志位的状态与该中断源是否被屏蔽无关,与全局中断使能位GIE也无关。
4. 当开放某一中断源时,该中断源就是通过中断标志向CPU申请中断的,无论什么原因,只要标志位IF置1(可以用软件强行置1),均会产生中断请求。

5. 当中断标志位为1,如果该中断被屏蔽或者被禁止了,只要不清除标志位,那么该中断请求会被潜伏下来,一旦屏蔽解除,立即产生中断响应。反之,如果在屏蔽/禁止条件解除之前清除了该标志位,那么则无中断请求。

6. 当CPU响应任一中断时,全局中断使能位GIE会自动清零;当中断返回时,它有自动置1。如果在中断处理期间,用软件将已经清零的GIE位又重新置位,这个时候若再出现中断请求,就可以形成了中断嵌套。即:在处理某一中断期间又响应了其他中断请求,就形成了中断嵌套,此时,前一中断处理过程会被暂停而进入新的中断处理,当新中断处理完毕后,才会继续处理前一个被搁置的中断。此方式可以形成多级嵌套,但不能超过硬件堆栈的深度8级,以免造成堆栈溢出而不能正常返回。

7. 如果同时发生多个中断请求,则中断处理的顺序取决于中断程序中的检查中断源的顺序。

8. 若要防止中断请求被丢失:则要注意下面两种情况:如果同一中断源的中断发生间隔时间大于该中断服务的处理时间,则可能出现中断事件被忽略(体现在中断服务的过程中,标志位被连续发生来两次置位),例如:中断事件发生的时间间隔为30ms,中断服务处理加上跳转判断的时间为50ms,则情况将会如下所示:

   [中断次数----------1][中断次数----------2][中断次数----------3][中断次数----------4]
   [处理次数------------------------1][处理次数------------------------2][处理次数------------------------4]
如果在中断处理一开始就清除IF,那么如上图所示,中断事件3、4 在处理次数2的过程中发生来两次,那么即使IF清除发生在中断次数3发生之前,也将丢失第三次中断。


另外,即使中断出现的时间间隔大于中断服务的时间间隔,如果清除中断标志位的指令安排在中断服务子程序的尾部,就有可能造成丢失该中断请求(即两次中断标志置位的事件只对应一条清除指令和一次中断处理。

9. 在进行查表操作时必须禁止CPU响应中断,以避免中断返回时跳转到不希望的地址上去。

三、一个疑惑


一个疑问:一些书上提到:如果对寄存器INTCON进行“读-改-写”操作的时候,要事先将GIE清0,再对INTCON进行操作,然后将GIE恢复为1
即BCF INTCON,GIE
  BSF INTCON,XX
  BSF INTCON,GIE
所提到的理由是:当CPU正在执行一条对INTCON寄存器进行“读-改-写”操作的指令时,如果恰好发生了中断请求,则中断服务程序会被执行两次。这是因为当中断请求发生后INTCON寄存器的GIE寄存器会被硬件自动清零(屏蔽所有中断),并且程序转入中断例程入口(0004h)。当GIE被清零后,这时如果CPU正在执行一条对INTCON“读-改-写”的指令时,则GIE位还会被写会操作重新置1,这样就会造成CPU两次进入中断服务程序。


该段解释晦涩难懂,根据中断发生过程的时序(PICmicro中档单片机系列参考手册的第8-2页):在第n个指令周期里,CPU检测到IF标志位为1,则在n+1个周期内将自动使得GIE=0,该周期内既不取指也不执行指令,然后在n+2个指令周期里,0004h指针装入PC指针,该周期也不运行其他指令,只完成0004H->(PC)的取指过程,第n+3个指令周期里,CPU执行0004h地址的指令码,并同时取0005h的指令码。

显然,作者提到的“当GIE被清零后,这时如果CPU正在执行一条对INTCON“读-改-写”的指令时,则GIE位还会被写会操作重新置1,这样就会造成CPU两次进入中断服务程序。”的解释存在下面的问题:GIE被硬件自动清零时的那个周期,是一个空运行周期,CPU并不执行指令,下一个周期也是空运行周期,不过是完成将0004h地址中的代码取指操作。然后就开始了0004h地址的代码的执行操作和0005h地址代码的取指过程。那么GIE在被硬件自动清零后要想置会1,只有两种方法:RETFIE指令使GIE自动置1;通过软件指令对GIE人为置1。显然,如果对GIE人为置1的指令执行在对该标志位清零前,那么会出现前文所述的中断嵌套(设该中断为A),如果没有其他中断发生且执行顺序先于中断A且对中断A的标志清零的话,那么中断A的嵌套是一个死循环。就不是执行两次的问题了----因为同一个中断嵌套时,GIE在自动清零被软件置一永远都发生在清除IF之前,那么IF一直得不到清除,而GIE又几乎一直都是1。


作者所说的情况似乎是这样的:读改写INTCON指令按如下过程分解:读INTCON的时候,GIE先是为1的,此时发生了中断,GIE被硬件清零,开始执行中断服务程序,然后再IF标志没有清除之前,执行INTCON的其他位的修改和写回操作,也将中断发生前的GIE读为1的信息写回GIE,这样,CPU被迫发生了第二次中断。显然,这样是将BSF  INTCON, XX指令分解得支离破碎---本来一个指令周期可以完成的指令被跨了多个指令周期;而且一个指令周期的指令被CPU在不同地址处分解执行读改写过程。

如果不是这样的话,那么作者的解释就自相矛盾:“当CPU正在执行一条对INTCON寄存器的‘读-改-写’操作的指令时,如果恰好发生了中断请求  ”与“当GIE被清零后,这是如果CPU正在执行一条对INTCON‘读-改-写’的指令时”相互矛盾。

总之,我对这里的理解存在一些疑惑,请斑竹及各位前辈指点。

点击此处查看原文 >>

系统分类: 单片机   |    用户分类:    |    来源: 转贴

评论(0) | 阅读(122)
总共 , 当前 /,2345678910>>下一页