超's profile朱雀陛下的空间PhotosBlogListsMore ![]() | Help |
朱雀陛下的空间笃信好学,守死善道。危邦不入,乱邦不居。天下有道则见,无道则隐。 |
||||||
|
December 02 我的高中MM97年9月由于中考失利,我不得不背上干粮来到离家40里外的一所普通中学开始我的高中生涯。但到了高中我惊奇地发现,不上重点高中也有不上重点高中的好处。。 December 12 软件实现滤波的几种方法1、限幅滤波法(又称程序判断滤波法) A、方法: 根据经验判断,确定两次采样允许的最大偏差值(设为A) 每次检测到新值时判断: 如果本次值与上次值之差<=A,则本次值有效 如果本次值与上次值之差>A,则本次值无效,放弃本次值,用上次值代替本次值 B、优点: 能有效克服因偶然因素引起的脉冲干扰 C、缺点 无法抑制那种周期性的干扰 平滑度差 2、中位值滤波法 A、方法: 连续采样N次(N取奇数) 把N次采样值按大小排列 取中间值为本次有效值 B、优点: 能有效克服因偶然因素引起的波动干扰 对温度、液位的变化缓慢的被测参数有良好的滤波效果 C、缺点: 对流量、速度等快速变化的参数不宜 3、算术平均滤波法 A、方法: 连续取N个采样值进行算术平均运算 N值较大时:信号平滑度较高,但灵敏度较低 N值较小时:信号平滑度较低,但灵敏度较高 N值的选取:一般流量,N=12;压力:N=4 B、优点: 适用于对一般具有随机干扰的信号进行滤波 这样信号的特点是有一个平均值,信号在某一数值范围附近上下波动 C、缺点: 对于测量速度较慢或要求数据计算速度较快的实时控制不适用 比较浪费RAM 4、递推平均滤波法(又称滑动平均滤波法) A、方法: 把连续取N个采样值看成一个队列 队列的长度固定为N 每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据.(先进先出原则) 把队列中的N个数据进行算术平均运算,就可获得新的滤波结果 N值的选取:流量,N=12;压力:N=4;液面,N=4~12;温度,N=1~4 B、优点: 对周期性干扰有良好的抑制作用,平滑度高 适用于高频振荡的系统 C、缺点: 灵敏度低 对偶然出现的脉冲性干扰的抑制作用较差 不易消除由于脉冲干扰所引起的采样值偏差 不适用于脉冲干扰比较严重的场合 比较浪费RAM 5、中位值平均滤波法(又称防脉冲干扰平均滤波法) A、方法: 相当于“中位值滤波法”+“算术平均滤波法” 连续采样N个数据,去掉一个最大值和一个最小值 然后计算N-2个数据的算术平均值 N值的选取:3~14 B、优点: 融合了两种滤波法的优点 对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差 C、缺点: 测量速度较慢,和算术平均滤波法一样 比较浪费RAM 6、限幅平均滤波法 A、方法: 相当于“限幅滤波法”+“递推平均滤波法” 每次采样到的新数据先进行限幅处理, 再送入队列进行递推平均滤波处理 B、优点: 融合了两种滤波法的优点 对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差 C、缺点: 比较浪费RAM 7、一阶滞后滤波法 A、方法: 取a=0~1 本次滤波结果=(1-a)*本次采样值+a*上次滤波结果 B、优点: 对周期性干扰具有良好的抑制作用 适用于波动频率较高的场合 C、缺点: 相位滞后,灵敏度低 滞后程度取决于a值大小 不能消除滤波频率高于采样频率的1/2的干扰信号 8、加权递推平均滤波法 A、方法: 是对递推平均滤波法的改进,即不同时刻的数据加以不同的权 通常是,越接近现时刻的数据,权取得越大。 给予新采样值的权系数越大,则灵敏度越高,但信号平滑度越低 B、优点: 适用于有较大纯滞后时间常数的对象 和采样周期较短的系统 C、缺点: 对于纯滞后时间常数较小,采样周期较长,变化缓慢的信号 不能迅速反应系统当前所受干扰的严重程度,滤波效果差 9、消抖滤波法 A、方法: 设置一个滤波计数器 将每次采样值与当前有效值比较: 如果采样值=当前有效值,则计数器清零 如果采样值<>当前有效值,则计数器+1,并判断计数器是否>=上限N(溢出) 如果计数器溢出,则将本次值替换当前有效值,并清计数器 B、优点: 对于变化缓慢的被测参数有较好的滤波效果, 可避免在临界值附近控制器的反复开/关跳动或显示器上数值抖动 C、缺点: 对于快速变化的参数不宜 如果在计数器溢出的那一次采样到的值恰好是干扰值,则会将干扰值当作有效值导 入系统 10、限幅消抖滤波法 A、方法: 相当于“限幅滤波法”+“消抖滤波法” 先限幅,后消抖 B、优点: 继承了“限幅”和“消抖”的优点 改进了“消抖滤波法”中的某些缺陷,避免将干扰值导入系统 C、缺点: 对于快速变化的参数不宜 C语言关键字解释以前有网友在论坛上提出这个问题,后来我逐一做了解释。现在转发到空间,如果有不准确的地方请指正! auto :声明自动变量 一般不使用 double :声明双精度变量或函数 int: 声明整型变量或函数 struct:声明结构体变量或函数 break:跳出当前循环 else :条件语句否定分支(与 if 连用) long :声明长整型变量或函数 switch :用于开关语句 case:开关语句分支 enum :声明枚举类型 register:声明积存器变量 typedef:用以给数据类型取别名(当然还有其他作用) char :声明字符型变量或函数 extern:声明变量是在其他文件正声明(也可以看做是引用变量) return :子程序返回语句(可以带参数,也看不带参数) union:声明联合数据类型 const :声明只读变量 float:声明浮点型变量或函数 short :声明短整型变量或函数 unsigned:声明无符号类型变量或函数 continue:结束当前循环,开始下一轮循环 for:一种循环语句(可意会不可言传) signed:生命有符号类型变量或函数 void :声明函数无返回值或无参数,声明无类型指针(基本上就这三个作用) default:开关语句中的“其他”分支 goto:无条件跳转语句 sizeof:计算数据类型长度 volatile:说明变量在程序执行中可被隐含地改变 do :循环语句的循环体 while :循环语句的循环条件 static :声明静态变量 if:条件语句 September 05 学习PIC笔记从上个星期开始看PIC资料。主要是一些datasheet。看的也不是很明白。后来在网上下了编译工具(MPLAB IDE v7.10+PICC8。05)开始学习使用这些工具。再后来打电话申请了3片PIC12F675。自己搭了一很简单的电路。如图所示。又写了一段程序,本来我打算先学写汇编的,能够更好的熟悉寄存器,但是由于我以前一直用C写51的程序,现在突然要改写汇编,反而有些不顺手,于是我放弃计划,直接写C,程序如下:
#include <pic.h>
#define led1 GPIO0
#define led2 GPIO1 void delay(unsigned int i); void readkey(); void keyrun(); unsigned char key=0; bit ledflag1,ledflag2; volatile bit gpio; // Configuration Bits __CONFIG(
UNPROTECT & // Data memory code protection is disable & Program Memory code protection is disable BOREN & // Brown-out Detect Enabled MCLRDIS & // memory clear function disabled PWRTEN & // Power-up Timer enabled WDTDIS & // Watchdog Timer enabled INTIO // use internal oscillator : GP4 pin and GP5 pin used by I/O pin ); // Initialize PIC Function void init(void){ BOD = 1; // Brown-out Reset Enable POR = 1; // Power-on Reset Enable OSCCAL = _READ_OSCCAL_DATA(); // Oscillatior calibration function
CMCON = 0b00000111; // Comparator Off
ANSEL = 0;//b00000000; WPU = 0b00010100; // GP2,GP4 Weak pull-up
TRISIO = 0b00111100;
// GP0 : output // GP1 : output // GP2 : input // GP3 : input // GP4 : input // GP5 : intput GPIO = 0xff;
} void main(void){ init(); CLRWDT(); led1=0; led2=0; delay(200); led1=1; led2=1; while(1){ CLRWDT(); readkey(); keyrun(); } } void readkey(){
if(GPIO2)return; else{ delay(50); if(GPIO2) return; else{ if(key<7) key++; else key=0; } } while(!GPIO2){CLRWDT();} return; } void keyrun(){ switch(key){
case 0: led1=1; led2=1; break; case 1: led1=0; led2=1; break; case 2: led1=1; led2=0; break; case 3: led1=0; led2=0; break; case 4: led2=1; led1=0; delay(200); led1=1; delay(200); break; case 5: led1=1; led2=0; delay(200); led2=1; delay(200); break; case 6: led1=0; led2=0; delay(200); led1=1; led2=1; delay(200); break; case 7: led1=0;led2=1; delay(200); led1=1;led2=0; delay(200); break; } } void delay(unsigned int i){ unsigned int j; // i=500; while(i--){ for(j=0;j<255;j++) asm("clrwdt"); } }
程序功能很简单,就是通过一个键来控制两个LED的状态。我想用这个程序来入门那是很合适的。 编译后烧片,运行结果还不错,但是不一会就出现问题了。发现key值似乎回自动变化。用万用表一量发现GIIO2脚电压才2点几伏。后来我在这个脚上加了一个10K的上拉电阻,问题解决。至此,我的第一个PIC程序成功完成。 |
||||||
|
|