飞思卡尔光电编码器测速程序
飞思卡尔智能车电路

注释:一字型排布,中间对称发射接收:电路图激光传感控制电路速度检测模块硬件板速度检测模块由一对红外对管配以编码盘实现,可以实现一圈24点分辨率。
电路上只有一个电阻结构十分简单。
在编码盘的设计上,我们直接用薄的PCB板嵌入在车模的后轮轴上,简单、牢固。
编码盘外观图如图1.2所示。
车速测定(红外对管)光电编码器与电路板和单片机的接口:图4.11 车速采集模块接口图测速:光电编码器摄像头信号采样电路图:图5.3 摄像头信号采样电路图:5v电压电路光电(两层排布)光栅盘测速,如图3.10 所示。
光栅盘是从机械鼠标上拆下来,总共有50个齿。
将栅盘直接用热熔胶粘接在后轮传动轴上,避免了打滑的可能。
在栅盘的正下方安装槽型光耦(又称光断续器,实际也是红外光电对管)。
当发射的光线被栅齿挡住,接受端管子应该截止,但该栅齿附近间隙仍有光透过并被接受到,所以截止的不够彻底;同理,本该完全导通时也没有完全导通。
所以接收端接受到的信号实际是连续变化的信号,类似于正弦波,而不是理想的脉冲方波信号。
需要在后级信号调理电路中,加上放大级和比较级电路就可得到与TTL电平兼容的脉冲方波信号。
单个传感器检测电路速度检测:ST150为单光束直射取样式光电传感器,它由高输出的红外光电二极管与高灵敏度光敏晶体管组成直射型光电传感器方案。
由速度传感器可以获得一个脉冲信号,该信号直接进入S12 芯片的ETC 模块,经程序计算后便可获得当前车速,其电路原理图如上。
VCC+5图 2.3 红外接收电路红外发射管不是同时点亮,而是隔足够远的距离的两个发射管同时点亮。
这样就可以把邻近干扰降到最底了。
实际测量中使用1.6cm长,直径为3mm的黑色套管套住红外接收管时,发射管发射的红外线对相隔一个管的红外接收的干扰几乎已经很小了。
飞思卡尔程序

飞思卡尔程序#include <hidef.h> /* common defines andmacros */#include <mc9s12dg128.h> /* derivativeinformation *///#include "PWM.h"//#include "AD.h"#include "control.h"#pragma LINK_INFO DERIVATIVE "mc9s12dg128b"word AD_wData[9]; //全局变量存放 AD0,AD1,AD2的结果word sum[9]; //初始化时为求平均值,全白中,各个灯的FF次的电压和word avrg0[9]; //全白时各个灯的平均电压word summ[9];//初始化时为求平均值,全黑中,各个灯的FF次的电压和word avrg1[9]; //全黑时各个灯的平均电压word ss[9]; //实际采集来的各个灯的电压word s[9]; // 实际采集来的各个灯的电压word sum2[8];//用于存放两两灯电压之和word k; //用于存放比较出的最大值uint h=1500;//转角大小int flag = 0;//标志中间灯是否第一次在黑道附近int flagg=0;//标志0灯从哪边感应到黑道int flagg1=0;//标志8灯从哪边感应到黑道int flagg0=0;//标志是左边还是右边出道int j=0;dword i;dword m;dword s0;dword s1;dword p11=0;//以下四个变量用于记录黑道处于同一侧的时间dword p12=0;dword p21=0;dword p22=0;word max0[9]=0;//初始化时采集来的黑道的值int g=0;//为过滤算法使用word cha[9];//用来存放黑白电压差int ffgg0=0;//标志是否用中间板采的数据int ffgg1=0;//标志是否用中间板采的数据word sum0=0; //初始化时采集来9个灯的全白电压和//word sum1=0; //实际采集来的左4个灯的电压和//word sum22=0; //实际采集来的右4个灯的电压和int fla=0;//标志是出道还是入道void AD_Init();void PWM_Init();void PWM_Init1();//void PID();void AD_Init(void) //AD初始化{//控制寄存器2:上电,标志位快速清零,开中断ATD0CTL2 =(ATD0CTL2_ADPU_MASK|ATD0CTL2_AFFC_MASK|ATD0CTL2_ASCIE_MASK) ;ATD1CTL2 =(ATD1CTL2_ADPU_MASK|ATD1CTL2_AFFC_MASK|ATD1CTL2_ASCIE_MASK) ;//控制寄存器3:转换序列长度为3ATD0CTL3 =0x78;//(ATD0CTL3_S2C_MASK|ATD0CTL3_S1C_MASK);ATD1CTL3 =0x78;//(ATD1CTL3_S2C_MASK|ATD1CTL3_S1C_MASK);//控制寄存器4:ATD0CTL4 =(ATD0CTL4_SRES8_MASK|ATD0CTL4_PRS1_MASK|ATD0CTL4_PRS0_MASK) ;ATD1CTL4 =(ATD1CTL4_SRES8_MASK|ATD1CTL4_PRS1_MASK|ATD1CTL4_PRS0_MASK) ;//控制寄存器5:ATD0CTL5 =(ATD0CTL5_DJM_MASK|ATD0CTL5_SCAN_MASK|ATD0CTL5_MULT_MASK);ATD1CTL5 =(ATD1CTL5_DJM_MASK|ATD1CTL5_SCAN_MASK|ATD1CTL5_MULT_MASK); ATD0DIEN=0x00; // 禁止数字输入缓冲ATD1DIEN=0x00; // 禁止数字输入缓冲}#pragma CODE_SEG NON_BANKED //中断服务程序#pragma TRAP_PROCvoid interrupt 22 Int_AD0(void){AD_wData[0] = ATD0DR0; //将结果寄存器中的值存放到数组中AD_wData[1] = ATD0DR1; //将结果寄存器中的值存放到数组中AD_wData[2] = ATD0DR2; //将结果寄存器中的值存放到数组中AD_wData[3] = ATD0DR3;AD_wData[4] = ATD0DR4;AD_wData[5] = ATD0DR5;AD_wData[6] = ATD0DR6;AD_wData[7] = ATD0DR7;AD_wData[8] = ATD1DR0;}#pragma CODE_SEG DEFAULTword max(word a,word b,word c,word d,word e,wordf,word r,word w) {word maxx=0;if(a>maxx)maxx=a;if(b>maxx)maxx=b;if(c>maxx)maxx=c;if(d>maxx)maxx=d;if(e>maxx)maxx=e;if(f>maxx)maxx=f;if(r>maxx)maxx=r;if(w>maxx)maxx=w;return maxx;}void delay0(){for(i=0;i<0xFFFF;i++)for(m=0;m<0x05;m++);}void delay1(){for(i=0;i<0xFFFF;i++);// for(i=0;i<0xFFFF;i++);}void main(void){AD_Init(); //AD 初始化DDRB = 0xFF;DDRA_BIT6=0; //A_BIT6口作为第二块板左边传感器的输入口 DDRA_BIT7=0; //A_BIT7口作为第二块板右边传感器的输入口 PORTB = 0xFF;p=0;for(j=0;j<9;j++){AD_wData[j] = 0; //全局变量初始化sum[j]=0;avrg0[j]=0;avrg1[j]=0;summ[j]=0;}for(j=0;j<9;j++) {max0[j]=0;ss[j]=0;}for(j=0;j<8;j++)sum2[j]=0;EnableInterrupts; //开AD中断for(i=0;i<0xFFFF;i++);for(i=0;i<0xFF;i++) //只能是FF,防止下面sum溢出 {for(j=0;j<9;j++)//采集白道路信息{sum[j]=sum[j]+AD_wData[j];}}for(i=0;i<9;i++) {sum0=sum0+sum[i]/0xFF;avrg0[i]=sum[i]/0xFF;}PORTB=sum[0]/0xFF; //显示0通道采集到的值delay0();PORTB=0x00;//显示马上得进行黑道信息采集了delay1();for(j=0;j<9;j++){for(m=0;m<0xFF;m++){summ[j]=summ[j]+AD_wData[j];}avrg1[j]=summ[j]/0xFF;PORTB=avrg1[j]; //显示采来的黑道信息cha[j]=avrg1[j]-avrg0[j];delay0();PORTB=0x00; //显示马上得进行下一次黑道信息采集了 delay1();}PORTB=0x00;//灯全亮,提示车马上就可以跑了delay1();PWM_Init() ;PWM_Init1(1500,1,200);for(i=0;i<0xFFF;i++);// delay1();for(;;){int f=0;u3=100;if(flagk1==1){p21=0;flagk2=0;p11++;if(p11==0xFFF)flagkk1=1;}else if(flagk2==1){p11=0;flagk1=0;p21++;if(p21==0xFFF)flagkk2=1;}for(f=0;f<9;f++){s[f]=AD_wData[f];ss[f]=s[f]-(avrg0[f]-0x50); //当前值减去初始白道值,以便比较}for(f=0;f<8;f++)sum2[f]=ss[f]+ss[f+1]; //两两灯电压之和//减去1.6V防止溢出*******************if(AD_wData[0]<0xC0&& AD_wData[1]<0xC0&&AD_wData[2]<0xC0&&AD_wData[3]<0xC0&&AD_wData[4]<0xC0&&AD_wData[5]<0xC0&&AD_wData[6]<0xC0&&AD_wD ata[7]<0xC0&&AD_wData[8]<0xC0){if(sum2[0]<0xC0&&sum2[1]<0xC0&&sum2[2]<0xC0&&sum2[3]<0xC0&&sum2[4]<0xC0&&sum2[5]<0xC0&&sum2[6]<0xC0&&sum2[7]<0xD0){fla=1;if(flagg0==1){for(i=0;i<0xFF;i++);PWM_Init1(1140,u1,200);flagk1=1;flagkk2=0;for(;;){if(AD_wData[4]>0xB0||AD_wData[5]>0xB0||AD_wData[6]>0xB0|| AD_wData[7]>0xB0||AD_wData[8]>0xB0){flagg0=0;break;}}}else if(flagg0==2){for(i=0;i<0xFF;i++);PWM_Init1(1860,u1,200);flagk1=0;flagkk2=1;for(;;)if(AD_wData[0]>0xB0||AD_wData[1]>0xB0||AD_wData[2]>0xB0||AD_wData[3]>0xB0||AD_wData[4]>0xB0){flagg0=0;break;}}}else{}}else{if(s[0]-(avrg0[0]-0x13)<0x40 &&s[1]-(avrg0[1]-0x13)<0x40 &&s[2]-(avrg0[2]-0x13)<0x40 && s[3]-(avrg0[3]-0x13)<0x40 &&s[4]-(avrg0[4]-0x13)<0x40 && s[5]-(avrg0[5]-0x13)<0x40 &&s[6]-(avrg0[6]-0x13)<0x40 && s[7]-(avrg0[7]-0x13)<0x40 &&s[8]-(avrg0[8]-0x13)<0x40)///////////注意调整该值36***************{/* if(PORTA_BIT6!=0||PORTA_BIT7!=0){if(PORTA_BIT6!=0&&PORTA_BIT7==0)PWM_Init1(1900,200,1);else if(PORTA_BIT7!=0&&PORTA_BIT6==0)PWM_Init1(1100,200,1);}*/}else{k=max(sum2[0],sum2[1],sum2[2],sum2[3],sum2[4],sum2[5],sum2[ 6],sum2[7]);//谁两和最大,黑道就在谁两之间if(k==sum2[0]){p=0;flagg0=2;if(fla==1)control_11();else if(fla==0) control_1();}else{if(k==sum2[1]){p=0;p1=0;fla=0;control_2(s[1],s[2],ss[1],ss[2],cha[1],cha[2],avrg0[1],avrg 0[2]);}else{if(k==sum2[2]){p=0;p1=0;fla=0;control_3(s[2],s[3],ss[2],ss[3],cha[2],cha[3],avrg0[2],avrg 0[3]);}else{if(k==sum2[3]){p=0;p1=0;fla=0;control_4(s[3],s[4],ss[3],ss[4],cha[3],cha[4],avrg0[3],avrg 0[4]);}else{if(k==sum2[4]){fla=0;p1=0;control_5(s[4],s[5],ss[4],ss[5],cha[4],cha[5],avrg0[4],avrg 0[5]);}else{if(k==sum2[5]){fla=0;p1=0;control_6(s[5],s[6],ss[5],ss[6],cha[5],cha[6],avrg0[5],avrg 0[6]);}else{if(k==sum2[6]){p=0;p1=0;fla=0;control_7(s[6],s[7],ss[6],ss[7],cha[6],cha[7],avrg0[6],avrg 0[7]);}else{if(k==sum2[7]){p=0;flagg0=1;if(fla==0)control_8(); elseif(fla==1)control_88(); } else{}}}}}}}}}}}}。
飞思卡尔单片机程序调试方法说明

飞思卡尔单片机程序调试方法说明对于飞思卡尔单片机编程,常用的调试方法有3种:调试方法1:在线调试法(Debug模式)CodeWarrior 10.3 开发环境下,可启动Debug模式,利用step into, step over, step return ,run to line 按钮,程序中设置断点,修改变量的值,查看寄存器的值等,进行调试。
有关调试窗口的按钮定义和调试方法,可查看帮助中debug View 和Debug information的说明。
调试方法2:串口调试法通过将程序运行过程中的数据、变量值等发送到PC机上查看,同时也可从PC机上通过串口发送数据到单片机,修改程序运行的参数(或步骤)进行调试。
智能车运行过程中常用用串口调试的方法。
调试方法3:硬件调试法通过连接在芯片外部的硬件或电路的变化或响应,查看程序运行的结果或状态(例如,在程序的某一位置点亮小灯、开蜂鸣器、发数据到LCD等)。
理解和掌握概念:单步调试相信任何调试人员对单步调试非常的熟悉。
CodeWarrior(与Eclipse基本一致)提供step into、step over、step return三个命令来支持单步调试。
三者的具体区别是:step into(快捷键F5)就是单步执行,遇到子函数就进入并且继续单步执行;step over(快捷键F6)是在单步执行时,在函数内遇到子函数时不会进入子函数内单步执行,而是将子函数整个执行完再停止,也就是把子函数整个作为一步。
step return(快捷键F7)就是单步执行到子函数内时,用step return就可以执行完子函数余下部分,并返回到上一层函数。
说的通俗点就是,step into:进入子函数,step over:越过子函数,但子函数会执行,step return:跳出子函数。
此外,Eclipse还提供了Run to line(快捷键Ctr + R)功能,从开始处运行程序,到正在执行的断点暂停。
一种基于光电编码器和matlab曲线拟合的测速

一种基于光电编码器和Matlab曲线拟合的测速方法作者:广东海洋大学电子信息工程系王嘉斌大家都知道,对于电机速度的测量方法有很多种,其中比较经典有M法测速、T法测速和MT法测速。
而在这里,我要介绍的是一种非常适合于飞思卡尔智能车的基于光电编码器的测速方法。
这里以200P/R的为例,它每转一周就会输出200个脉冲,通过单片机的脉冲捕捉功能就能检测到编码器输出的脉冲数。
众所周知,电机的转速是通过PWM的占空比来控制,想到这里,我们可以提出这样的一个疑问:既然占空比决定电机转速,而转速可以通过编码器输出的脉冲个数来表示,那么电机的PWM占空比跟编码器输出的脉冲个数是不是有某种必然的关系呢?答案是肯定的。
没错,占空比跟脉冲个数之间一定有种必然的关系!这种关系可能是线性的,也可能是非线性的。
在偏差允许的范围内,我们一般会选择线性的。
原因很简单,线性的让单片机计算起来肯定要快一些。
既然怀疑这两者之间有某种联系,那么我们就要想办法去找出它们之间的关系来。
首先,我们得先做一件事——测量。
通过测量不同占空比所对应的脉冲个数,再通过一定的数据处理(例如多次测量求平均值),得到两组对应的数据。
本人是通过先编写好程序,在程序中设置6种不同的速度值,即6种电机的PWM占空比值,然后通过每10ms的中断来读取编码器输出的脉冲个数。
因为都是10ms,所以每次读取到的脉冲个数都相差不大,最多差9个脉冲,为了减小测量误差,我取了4组数,然后对这4组数取平均值。
这样,就得到了一组电机PWM占空比跟编码器脉冲个数的数据。
对所得到的数据,我们可以借助Matlab这个强大的数学工具来处理。
主要用的是Matlab 的曲线拟合功能。
下面我将为大家介绍一下相关的操作步骤。
首先,我们把得到的占空比和脉冲个数以数组的形式输入到Matlab中(x代表占空比,y为脉冲个数):x=[100,200,300,400,500,600];y=[123,350,560,763,970,1206]; 然后再输入曲线拟合工具箱cftool(x,y)命令,此时Matlab会自动弹出一个新的窗口(如下图1)进入曲线拟合工具箱界面“Curve Fitting tool”后,按下面步骤操作:(1)点击“Data”按钮,弹出“Data”窗口;(2)利用X data和Y data的下拉菜单读入数据x,y,可修改数据集名“Data set name”,然后击“Create data set”按钮窗口,退出“Data”,返回工具箱界面,这时会自动画出数据集的曲线图(图2);图2(3)点击“Fitting”按钮,弹出“Fitting”窗口;(4)点击“New fit”按钮,可修改拟合项目名称“Fit name”,通过“Data set”下拉菜单选择数据集,然后通过下拉菜单“Type of fit”,选择拟合曲线的类型,在这里我们直接选择Polynomial:多形式逼近中的liner类型;(5)类型设置完成后,点击“Apply”按钮,就可以在Results框中得到拟合结果(图3)。
光电编码器测量电机转速的方法

光电编码器测量电机转速的方法光电编码器测量电机转速的方法可以利用定时器/计数器配合光电编码器的输出脉冲信号来测量电机的转速。
具体的测速方法有M法、T法和M/T法3种。
一、M法又称之为测频法,其测速原理是在规定的检测时间Tc内,对光电编码器输出的脉冲信号计数的测速方法,例如光电编码器是N线的,则每旋转一周可以有4N个脉冲,因为两路脉冲的上升沿与下降沿正好使编码器信号4倍频。
现在假设检测时间是Tc,计数器的记录的脉冲数是M1,在实际的测量中,时间Tc内的脉冲个数不一定正好是整数,而且存在最大半个脉冲的误差。
如果要求测量的误差小于规定的范围,比如说是小于百分之一,那么M1就应该大于50。
在一定的转速下要增大检测脉冲数M1以减小误差,可以增大检测时间Tc单考虑到实际的应用检测时间很短,例如伺服系统中的测量速度用于反馈控制,一般应在0.01秒以下。
由此可见,减小测量误差的方法是采用高线数的光电编码器。
M法测速适用于测量高转速,因为对于给定的光电编码器线数N机测量时间Tc条件下,转速越高,计数脉冲M1越大,误差也就越小。
二、T法也称之为测周法,该测速方法是在一个脉冲周期内对时钟信号脉冲进行计数的方法。
为了减小误差,希望尽可能记录较多的脉冲数,因此T法测速适用于低速运行的场合。
但转速太低,一个编码器输出脉冲的时间太长,时钟脉冲数会超过计数器最大计数值而产生溢出;另外,时间太长也会影响控制的快速性。
与M法测速一样,选用线数较多的光电编码器可以提高对电机转速测量的快速性与精度。
三、M/T法M/T法测速是将M法和T法两种方法结合在一起使用,在一定的时间范围内,同时对光电编码器输出的脉冲个数M1和M2进行计数。
实际工作时,在固定的Tc时间内对光电编码器的脉冲计数,在第一个光电编码器上升沿定时器开始定时,同时开始记录光电编码器和时钟脉冲数,定时器定时Tc时间到,对光电编码器的脉冲停止计数,而在下一个光电编码器的上升沿到来时刻,时钟脉冲才停止记录。
光电编码器测速

飞思卡尔智能车舵机和测速的控制设计与实现时间:2010-04-14 11:53:10 来源:电子设计工程作者:雷贞勇谢光骥五邑大学2.1 舵机工作原理舵机在6 V电压下正常工作,而大赛组委会统一提供的标准电源输出电压为7.2 V,则需一个外围电压转换电路将电源电压转换为舵机的工作电压6 V。
图2为舵机供电电路。
舵机由舵盘、位置反馈电位计、减速齿轮组、直流动电机和控制电路组成,内部位置反馈减速齿轮组由直流电动机驱动,其输出轴带动一个具有线性比例特性的位置反馈电位器作为位置检测。
当电位器转角线性地转换为电压并反馈给控制电路时,控制电路将反馈信号与输入的控制脉冲信号相比较,产生纠正脉冲,控制并驱动直流电机正向或反向转动,使减速齿轮组输出的位置与期望值相符。
从而达到舵机精确控制转向角度的目的。
舵机工作原理框图如图3所示。
2.2 舵机的安装与调节舵机的控制脉宽与转角在-45°~+45°范围内线性变化。
对于对速度有一定要求的智能车,舵机的响应速度和舵机的转向传动比直接影响车模能否以最佳速度顺利通过弯道。
车模在赛道上高速行驶,特别是对于前瞻性不够远的红外光电检测智能车,舵机的响应速度及其转向传动比将直接影响车模行驶的稳定性,因此必须细心调试,逐一解决。
由于舵机从执行转动指令到响应输出需占用一定的时间,因而产生舵机实时控制的滞后。
虽然车模在进入弯道时能够检测到黑色路线的偏转方向,但由于舵机的滞后性,使得车模在转弯过程中时常偏离跑道,且速度越快,偏离越远,极大限制车模在连续弯道上行驶的最大时速,使得车模全程赛道速度很难进一步提高。
为了减小舵机响应时间,在遵守比赛规则不允许改造舵机结构的前提下,利用杠杆原理,采用加长舵机力臂的方案来弥补这一缺陷,加长舵机力臂示意图如图4所示。
图4中,R为舵机力臂;θ为舵机转向角度;F为转向所需外力;α为外力同力臂的夹角。
在舵机输出盘上增加长方形杠杆,在杠杆的末端固定转向传动连杆,其表达式为:加长力臂后欲使前轮转动相同角度时,在舵机角速度ω相同的条件下舵机力臂加长后增大了线速度v,最终使得舵机的转向角度θ减小。
飞思卡尔卡尔曼滤波程序

卡尔曼滤波:以陀螺仪测量的角速度作为预测值的控制量,加速度传感器测量的角度作为观测值。
下面程序中angle_m为测量角度,gyro_m为测量角速度,gyro_m*dt为控制量。
以下程序是按卡尔曼滤波的五个公式来编写的。
X(k|k-1)=A X(k-1|k-1)+B U(k) (1)P(k|k-1)=A P(k-1|k-1) A’+Q (2)X(k|k)= X(k|k-1)+Kg(k) (Z(k)-H X(k|k-1)) (3)Kg(k)= P(k|k-1) H’ / (H P(k|k-1) H’ + R) (4)P(k|k)=(I-Kg(k) H)P(k|k-1) (5)对于单输入单输出系统,A、B、H、I不为矩阵且值都为1。
卡尔曼滤波参数的调整:其参数有三个,p0是初始化最优角度估计的协方差(初始化最优角度估计可设为零),它是一个初值。
Q是预测值的协方差,R是测量值的协方差。
对Q和R的设定只需记住,Q/(Q+R)的值就是卡尔曼增益的收敛值,比如其值为0.2,那么卡尔曼增益会向0.2收敛(对于0.2的含义解释一下,比如预测角度值是5度,角度测量值是10度,那么最优化角度为:5+0.2*(10-5)=6。
从这里可以看出,卡尔曼增益越小,说明预测值越可靠,最优化角度越接近预测值;相反的,卡尔曼增益越大,说明测量值越可靠,最优化角度越接近测量值)。
p0/(Q+R)反映收敛的快慢程度,该值设定越小,收敛越快,该值越大,收敛越慢(这里的p0是指初始最优角度值的协方差),因为卡尔曼增益收敛总的来说是很快的,所以该值设定大一点或小一点都没什么关系。
注:以下程序只用于说明算法,存在语法错误,初始的参数也是随意给定的。
x=0;/* 最优角度初值*/p=1;/* 最优角度对应协方差初值*/dt=0.02;Q=0.0025;R=0.25;void Kalman_Filter(float angle_m,float gyro_m) //gyro_m:gyro_measure{x=x+ gyro_m*dt; 等号右边的x表示上一次最优角度值,等号左边的x表示这一次的角度的预测值p=p+Q; 等号右边的p表示上一次最优角度值的协方差,等号左边的p表示这一次的角度预测值的协方差k=p/(p+R); k值为卡尔曼增益(k值每次计算都不一样,它会越来越趋近于Q/(Q+R)这个收敛值)x=x+k*( angle_m-x); 等号左边的x表示根据预测值和测量值计算出来的这一次的最优角度值(从这里可以看出,k越大,等号左边的最优值x与等号右边的测量值angle_m越接近;k越小,等号左边的最优值x与等号右边的预测值x越接近;)p=(1-k)*p; 等号左边的p表示这一次最优角度值的协方差}从上面的程序可以看出,卡尔曼滤波是一个递推过程,初始的最优角度值可设为x=0,初始最优角度值的协方差p一定不能设为零,dt是采样周期,Q 与R可共同决定卡尔曼增益收敛的大小。
光电编码器测速

实验三光电传感器转速测量实验实验目的1.通过本实验了解和掌握采用光电传感器测量的原理和方法。
2.通过本实验了解和掌握转速测量的基本方法。
实验原理直接测量电机转速的方法很多,可以采用各种光电传感器,也可以采用霍尔元件。
本实验采用光电传感器来测量电机的转速。
由于光电测量方法灵活多样,可测参数众多,一般情况下又具有非接触、高精度、高分辨率、高可靠性和相应快等优点,加之激光光源、光栅、光学码盘、CCD器件、光导纤维等的相继出现和成功应用,使得光电传感器在检测和控制领域得到了广泛的应用。
光电传感器在工业上的应用可归纳为吸收式、遮光式、反射式、辐射式四种基本形式。
图3.31说明了这四种形式的工作方式。
图3.31 光电传感器的工作方式图3.32直射式光电转速传感器的结构图直射式光电转速传感器的结构见图3.32。
它由开孔圆盘、光源、光敏元件及缝隙板等组成。
开孔圆盘的输入轴与被测轴相连接,光源发出的光,通过开孔圆盘和缝隙板照射到光敏元件上被光敏元件所接收,将光信号转为电信号输出。
开孔圆盘上有许多小孔,开孔圆盘旋转一周,光敏元件输出的电脉冲个数等于圆盘的开孔数,因此,可通过测量光敏元件输出的脉冲频率,得知被测转速,即n=f/N式中:n - 转速f - 脉冲频率N - 圆盘开孔数。
反射式光电传感器的工作原理见图3.33,主要由被测旋转部件、反光片(或反光贴纸)、反射式光电传感器组成,在可以进行精确定位的情况下,在被测部件上对称安装多个反光片或反光贴纸会取得较好的测量效果。
在本实验中,由于测试距离近且测试要求不高,仅在被测部件上只安装了一片反光贴纸,因此,当旋转部件上的反光贴纸通过光电传感器前时,光电传感器的输出就会跳变一次。
通过测出这个跳变频率f,就可知道转速n。
n=f如果在被测部件上对称安装多个反光片或反光贴纸,那么,n=f/N。
N-反光片或反光贴纸的数量。
图3.33 反射式光电转速传感器的结构图实验仪器和设备1. 计算机 n台2. DRVI快速可重组虚拟仪器平台 1套3. 并口数据采集仪(DRDAQ-EPP2)1台4. 开关电源(DRDY-A)1台5. 光电转速传感器(DRHYF-12-A) 1套6. 转子/振动实验台(DRZZS-A)/(DRZD-A) 1 台实验步骤及内容1.光电传感器转速测量实验结构示意图如图3.34所示,按图示结构连接实验设备,其中光电转速传感器接入数据采集仪A/D输入通道。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
//time-out period = (PITMTLD + 1) * (PITLD + 1) / fBUS.
//For example, for a 50 MHz bus clock, the maximum time-out period equals:
//256 * 65536 * 20 ns = 419.43 ms.
#include <hidef.h> /* common defines and macros */
#include <MC9S12XS128.h> /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12xs128"
volatile uint speed_back=0,temp=0;
/* please make sure that you never leave this function */
}
#pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt 68 timer2(void)
{
_asm(MOVB #$07,PITTF); //clear interrupt falg
void Init_PLL(void)
{
CLKSEL = 0X00;//disengage PLL to system
PLLCTL_PLLON = 1;//turn on PLL
SYNR = (0xc0|0x18); //SYDIV=0X18=24
REFDV = (0x40|0x07); //REFDIV=0X07=7
SCI0BDH=0x01;
SCI0BDL=0x46;
实际波特率是:9585
****************************************************/
}
void UART_Send(uchar data)
{
while(!(SCI0SR1&0x80));//keep waiting when not empty
SCI0DRL = data;
}
void main(void) {
Init_PLL();
UART_Init();
Init_Event_Count();
Init_PIT_Timer();
/* put your own code here */
EnableInterrupts;
for(;;) {} /* wait forever */
}
void Init_Event_Count(void)
{
PACTL = (1<<6);//脉冲累加器启动,外部发生一次下降沿就计数一次。外部编码器连接到IOC7.
//在中断里读取PACNT的值就是脉冲个数。读取后清零PACNT。
}
void UART_Init(void)
{
SCI0CR2 = 0x0C;
_asm(nop);
while(!(CRGFLG_LOCK==1));//when pll is steady ,then use it;
CLKSEL_PLLSEL = 1;//engage PLL to system;
}
//500us one interrupt
void Init_PIT_Timer(void)
SCI0BDH = 0x00;
SCI0BDL = 0xa2;
/****************************************************
当波特率为19200,主频为50MHZ时:
SCI0BDH=0x00;
SCI0BDL=0xa2;
实际波特率是:19170
当波特率为9600,主频为50MHZ时:
void delay_ms(uint ms)
{
volatile uint x=0;
while(ms--)
{
for(x=2800;x>0;x--)
{
_asm(nop);
_asm(nop);
_asm(nop);
_asm(nop);
_asm(nop);
_asm(nop);
}
}
}
//注意外接16M晶体。
//飞思卡尔推荐配置,主频道50MHZ,速度更快!
temp++;
if(temp>3) //10MS读取一次速度
{
speed_back = PACNT;//返回速度值
PACNT = 0;//速度归零
UART_Send(speed_back&0X00FF);
speed_back=0;
temp=0;
}Байду номын сангаас
}
#pragma CODE_SEG DEFAULT
POSTDIV = 0x00; //pllclock=2*osc*(1+SYDIV)/(1+REFDIV)=100MHz;
_asm(nop); //BUS CLOCK=50M
_asm(nop);
_asm(nop);
_asm(nop);
_asm(nop);
_asm(nop);
_asm(nop);
_asm(nop);
{
PITCFLMT=0X00;
PITCE|=0X07;
PITMUX|=0X04;//BASED 0 timer2 based 1
PITMTLD1=49; //
PITLD2=2499; //temer 2 2.5MS一次中断
PITTF|=0x07; //clear interrupt falg
PITINTE|=0X07;//ENABLE TIMER0 INTERRUPT