电机编码器解码
- 格式:docx
- 大小:21.75 KB
- 文档页数:17
直流电机编码器原理
直流电机编码器是一种用于测量电机旋转位置和速度的装置。
它通常由光电传感器、光栅和计数器组成。
光电传感器是编码器的核心部件。
它由一个发光二极管和一个光敏二极管组成,安装在电机轴上。
光栅是由多个透明和不透明的带状条纹组成的圆盘,固定在电机端部。
当电机转动时,光栅上的条纹会依次通过光电传感器。
每当一根条纹通过时,光敏二极管会检测到光线的变化,并将其转换为电信号。
由于光栅上的条纹数量是已知的,所以可以通过计数器来记录通过光电传感器的条纹数量,从而确定电机的旋转角度和速度。
编码器通常可以提供单向编码和双向编码两种模式。
在单向编码模式下,只能检测电机的旋转方向,无法确定准确的位置。
在双向编码模式下,可以通过正反转的光栅条纹变化来确定电机的旋转位置和速度。
通过对编码器输出的电信号进行处理和解码,可以得到准确的电机转速和位置信息。
这些信息可以用来控制电机的转动,实现精确的控制。
总之,直流电机编码器利用光电传感器和光栅的特性来测量电机的旋转位置和速度,并通过计数器记录光栅条纹的变化来确定电机的旋转角度和速度。
这种编码器为实现电机的精确控制提供了重要的数据基础。
无刷电机编码器测量技术的原理与操作方法无刷电机编码器是一种广泛应用于无刷电机系统中的测量技术。
它可以实时反馈电机的位置和速度信息,为无刷电机系统提供精确而可靠的控制。
本文将重点介绍无刷电机编码器测量技术的原理和操作方法,并探讨其在实际应用中的优缺点。
一、无刷电机编码器原理无刷电机编码器是通过检测电机转子上的物理标记来测量位置和速度的。
这些物理标记通常是由磁铁或光电传感器构成的,可以在电机转子周围形成一个编码盘。
编码盘上的标记根据转子的运动而改变位置,编码器通过检测标记位置的变化来计算电机的位置和速度。
在基本原理上,无刷电机编码器可以分为磁性编码器和光电编码器两种类型。
1.磁性编码器:磁性编码器是利用磁铁的磁场来进行测量的。
磁铁固定在电机转子上,编码器通过检测磁铁位置的变化来计算电机的位置和速度。
由于磁铁的位置相对稳定,磁性编码器具有较高的准确性和精度。
2.光电编码器:光电编码器是利用光电传感器来进行测量的。
在光电编码器中,转子上会有一个透明的编码盘,光电传感器通过检测编码盘上的透明和不透明部分来计算电机的位置和速度。
由于光电传感器的灵敏度较高,光电编码器具有较高的分辨率和响应速度。
二、无刷电机编码器的操作方法无刷电机编码器的操作方法相对简单,主要包括安装和连接两个步骤。
1.安装:首先,将编码器的底座固定在电机上。
根据编码器的类型,可以选择磁铁或透明编码盘。
确保编码器与电机的转子轴是同轴的,以确保准确的位置和速度测量。
另外,还需注意编码器的防水性能,确保在潮湿或恶劣环境中正常工作。
2.连接:通过连线将编码器与电机控制器相连接。
根据编码器的类型,可以选择模拟信号输出或数字信号输出。
模拟信号输出需要通过模数转换器将信号转换为数字信号,而数字信号输出则直接连接到控制器的数字输入口。
这里需要注意的是,根据编码器的规格和控制器的输入方式,选择合适的连接方式。
三、无刷电机编码器测量技术的优缺点无刷电机编码器测量技术在无刷电机系统控制中具有重要作用,它可以提供精确的位置和速度反馈信息,实现高效的控制。
电机编码器工作原理
电机编码器是一种用于测量电机旋转角度或位置的装置。
它由编码盘和传感器构成。
编码盘通常固定在电机轴上,与电机一起旋转。
编码盘上刻有等距分隔的光电传感器条纹。
传感器是固定在电机外壳上的光电开关,用于监测光电传感器条纹的移动。
当电机旋转时,编码盘上的光电传感器条纹会接触到传感器。
此时,传感器会产生电信号,信号的频率和变化规律与编码盘的旋转速度和方向有关。
传感器产生的电信号通过编码器的解码器进行处理,转换为数字信号。
解码器根据接收到的信号来确定电机的旋转角度或位置,并将结果输出给控制系统。
电机编码器工作原理基于光电效应和数字信号处理。
通过监测光电传感器条纹与传感器之间的变化,可以准确地测量电机的旋转角度和位置。
电机编码器在控制系统中广泛应用,用于实现闭环控制、位置反馈和精确定位等功能。
它可以提高电机系统的精度、稳定性和响应速度,适用于各种工业自动化领域。
电机编码器工作原理电机编码器是一种能够将电机转动位置转换成数字信号的装置,它在工业自动化领域中扮演着非常重要的角色。
了解电机编码器的工作原理对于掌握电机控制技术至关重要。
本文将介绍电机编码器的工作原理,希望能够帮助读者更好地理解和应用这一技术。
电机编码器的工作原理主要基于光电传感技术。
在电机编码器中,通常会使用光栅编码器或者磁性编码器来实现位置信号的检测。
这些编码器会将电机转动的位置转换成相应的数字信号,从而实现对电机位置的准确控制。
在光栅编码器中,光源会发出光线,经过光栅盘后被光电传感器检测。
光栅盘上的光栅条会根据不同的位置遮挡或透过光线,从而形成不同的光电信号。
这些信号经过解码处理后,就可以得到电机的位置信息。
而磁性编码器则是利用磁性传感器来检测磁性标记的位置,原理类似于光栅编码器,只是采用了不同的传感技术。
通过检测磁性标记的位置,磁性编码器也可以实现对电机位置的准确测量。
电机编码器的工作原理也涉及到信号解码和处理的过程。
通过解码器对从编码器中读取的信号进行解析和处理,可以得到准确的电机位置信息。
这些信息可以被用来控制电机的转速、位置和方向,从而实现精确的运动控制。
在实际应用中,电机编码器的工作原理还需要考虑到信号的稳定性和抗干扰能力。
特别是在工业现场环境中,可能会受到电磁干扰、振动、温度变化等因素的影响,因此对于编码器的设计和选择都需要考虑到这些因素,以确保其稳定可靠地工作。
总的来说,电机编码器的工作原理是基于光电传感或磁性传感技术,通过对电机位置信号的检测和处理,实现对电机位置的精确控制。
了解电机编码器的工作原理对于工程师和技术人员来说是非常重要的,它不仅可以帮助他们更好地应用电机控制技术,还可以为工业自动化领域的发展提供有力支持。
希望本文能够帮助读者更好地理解电机编码器的工作原理,为相关领域的工作和研究提供帮助。
交流电机编码器工作原理
嘿,朋友们!今天咱就来好好聊聊交流电机编码器的工作原理,这可真是个超有趣的东西!
想象一下哈,交流电机就像是一辆动力十足的赛车,而编码器呢,那就是赛车里精确的仪表盘。
比如说,你开着赛车在赛道上飞驰,你得知道自己跑了多远、速度有多快吧,这时候仪表盘就起作用啦!编码器就是这样,时刻监测着交流电机的各种信息。
它是怎么做到的呢?其实啊,编码器里面有很多精巧的部件。
就好像一个小团队,大家齐心协力地工作。
其中有个关键的部分叫做光栅盘,这就好比是团队里的核心成员,它上面有很多细细的条纹。
当电机转动的时候,这些条纹就和其他部件相互作用,产生各种信号。
咱说,这不就像我们在生活中,每个人都有自己的职责,大家一起配合才能把事情做好嘛!然后编码器把这些信号传递出去,就像是给外界发送重要情报一样。
收到这些“情报”的控制系统,就能清楚地知道电机的状态啦,多神奇呀!
再举个例子,你想想,如果你是个指挥家,编码器就是告诉你乐团每个乐器演奏情况的小助手,让你能完美地掌控整个演奏。
交流电机编码器不就是这样为各种设备提供精确的运行信息嘛!
哎呀,交流电机编码器真的是太重要啦!有了它,交流电机才能高效、稳定地运行,我们的各种设备才能正常工作呀!这真的是科技的神奇之处,让我们的生活变得更加便捷和精彩!。
伺服电机编码器原理
伺服电机编码器是一种用于测量转动角度和精确定位的设备。
它在伺服电机系
统中起到非常关键的作用,能够提供反馈信息,使电机能够实时掌握自身运动状态,并进行精确控制。
伺服电机编码器由光电传感器和代码盘组成。
当电机旋转时,代码盘上的刻线
会经过光电传感器的探测,产生相应的信号。
这些信号被转化为数字脉冲,然后通过解码器进行解码,以获取位置和速度数据。
编码器一般分为增量式编码器和绝对式编码器两种类型。
增量式编码器在每个
旋转周期内产生一组脉冲信号,并通过计数器记录脉冲数量,从而计算出转动角度和速度。
而绝对式编码器可以直接读取输出的二进制编码,能够提供实时的位置信息。
伺服电机编码器的工作原理是基于光电原理和数字信号处理技术。
光电传感器
的发光二极管照射到代码盘上的刻线上,光电二极管接收到反射的光线并将其转化为电信号。
这些电信号经过放大和滤波处理后,通过编码电路输出给控制器。
控制器根据接收到的信号进行计数和解码,可以实时了解电机的位置和速度,
并与预设的目标位置进行比较。
根据误差信号,控制器会调整输出电压,使电机按照预设的路径和速度进行精确控制。
这种闭环反馈系统能够保证电机的运动稳定性和位置精度。
总结一下,伺服电机编码器是一种用于测量转动角度和精确定位的设备。
它通
过光电原理和数字信号处理技术,将旋转运动转化为反馈信号,实现对电机位置和速度的闭环控制。
它对于许多需要高精度定位和控制的应用非常重要,如机器人、自动化设备和CNC机床等。
永磁同步电机编码器原理“永磁同步电机编码器原理”是指永磁同步电机中所使用的一种用于测量转子位置和速度的装置。
在本文中,将详细讲解永磁同步电机编码器的工作原理,并逐步回答与该主题相关的问题。
一、什么是永磁同步电机编码器?永磁同步电机编码器是一种用于定位和测量电机转子位置的装置。
它通常由一套光学或磁性传感器组成,通过与转子上的编码盘相互作用,可以实时测量转子的角度和速度。
二、永磁同步电机编码器的工作原理永磁同步电机编码器的工作原理基于编码盘和传感器之间的相互作用。
编码盘是固定在电机转子上的一种具有特定线条图案的圆盘。
传感器通常分为两类,光学传感器和磁性传感器。
1. 光学传感器:光学传感器通常由一个发射器和一个接收器组成。
发射器通过发射一束光束,照射到编码盘上的线条图案上。
当编码盘转动时,光束会被图案的间隙遮挡或反射,进而产生光电信号。
接收器会接收到这些光电信号,并将其转化为电信号。
2. 磁性传感器:磁性传感器通常使用霍尔传感器,通过感知磁场的变化来测量转子位置。
编码盘上的线条图案通常由磁性材料制成。
当编码盘转动时,磁场的变化会被传感器感知到,并转化为电信号。
两种传感器的工作原理类似,都是通过感知编码盘上图案的变化来测量转子的位置和速度。
三、永磁同步电机编码器的应用永磁同步电机编码器广泛应用于各种需要精准控制和定位的领域。
主要应用包括:1. 工业机械:永磁同步电机编码器可以用于控制机械设备的位置和速度,实现精准控制和定位。
2. 自动化工程:在自动化设备中,永磁同步电机编码器可以用于定位和控制机器人、输送带和自动装配线等。
3. 医疗设备:在医疗领域,永磁同步电机编码器可以用于控制精密仪器和机器人,如手术机器人和扫描仪等。
4. 机床和加工设备:永磁同步电机编码器能够提供高精度的位置和速度反馈,用于控制切割和加工设备。
5. 液压和气动设备:在液压和气动系统中,永磁同步电机编码器可以用于测量缸体和阀门位置,实现精准的控制。
电机控制中的编码器信号解析方法详解编码器是电机控制中常用的一种传感器,用于测量电机转动角度和速度。
编码器通过产生脉冲信号来反映电机的转动情况,然后通过解析这些信号,可以获取电机的准确位置和速度信息。
本文将详细介绍电机控制中常用的编码器信号解析方法。
一、基本原理编码器通常由一个固定的部分和一个旋转的部分组成。
固定部分安装在电机或机械系统中,旋转部分与电机转子或机械系统的旋转部分连接。
当旋转部分转动时,编码器会产生脉冲信号。
编码器的脉冲信号可以分为两种类型:增量式和绝对式。
增量式编码器的脉冲信号是根据传感器的旋转产生的。
每旋转一定角度,编码器会产生一个脉冲信号。
通过计算脉冲信号的数量和方向,可以推算出电机的位置和速度。
然而,由于增量式编码器脉冲信号只提供了相对位置信息,因此对于电机的绝对位置无法直接获取。
相比之下,绝对式编码器的脉冲信号可以直接反映出电机的绝对位置。
绝对式编码器通常有多个通道,每个通道对应一个二进制码。
每当电机转动时,编码器将会输出当前的二进制码,通过解析这些码可以准确获取电机的位置。
绝对式编码器的优点是不会对电机的位置信息进行积累误差,相比于增量式编码器更加精准。
二、编码器信号解析方法1. 增量式编码器信号解析方法增量式编码器的脉冲信号通常由两个通道组成,称为A相和B相。
这两个通道的脉冲信号相位差为90度,可以通过观察A相和B相脉冲信号的变化来推算电机的方向和位置。
在解析增量式编码器的脉冲信号时,可以使用两种主要方法:计数器法和相位差法。
计数器法是最简单的解析方法,通过计数A相和B相脉冲信号的上升沿或下降沿来统计转动的角度。
当计数值增加时,电机转动的方向为正;当计数值减小时,电机转动方向为负。
计数器方法简单直观,适用于大部分应用场景,但需要注意计数器的溢出问题。
相位差法是一种更精确的解析方法,它通过记录A相和B相脉冲信号的相位差来计算旋转角度。
通常情况下,电机转动1个角度单位,A相和B相的相位差为90度。
电机编码器的使&STM32的定时器编码器模式一、基础知识:编码器是小车测速反馈必不可少的模块,在做自平衡和速度的精确控制需要有编码器读取电机的转速和方向上图为编码器的示意图,中间是一个带光栅的码盘,光通过光栅,接收管接收到高电平,没通过,接收到低电平。
电机旋转一圈,码盘上有多少光栅,接受管就会接收多少个高电平。
我们做的自平衡是用的是SK3530高性能直流减速电机采用光栅测速单圈输出448*30个AB相脉冲也就是13440相位差90度接线说明:从白线到蓝线一次为:白线:A相;绿线:B相;红线:3.3V-5V;黑线;GND黄线和蓝线为电机两根接线柱的线,通常接电机驱动。
正转A相超前B相90度,也就是说,A相进入下降沿的时候,B相是高电平,反转的时候A相落后B 相90度,也就是说A相进入下降沿的时候,B相是低电平,通常用法:A相接入单片机的中断IO口,B相接入单片机的普通IO口。
二、stm32编码器模式接口:在通用定时器和高级定时器中有这个功能从图上中可以看出,TI1波形先于TI2波形90°时,每遇到一个边沿变化是,计数器加1(可以通过寄存器设置加减),可以看出一个光栅,被计数了4次。
TI1波形后于TI2波形90°时,每遇到一次边沿变化,计数器减1。
也就是说13440个脉冲计数了13440*4=53760次简单的计数显示程序:由于DJ_jishu_L是int16_t即(signed)int类型数据范围-32768~32767 TIM_GetCounter返回值是unsigned int类型转换为int类转动一圈DJ_jishu_L变化情况:即从0到-32768到32767到11579计数器变化值=32768+(32767-11579)= 53956与之前的53760相差不大程序如下两个定时两个通道PA6PA7左电机PB6PB7右电机。
电机霍尔编码器的零位校准步骤如下:
1. 定义电机绕组U、V、W:电机绕组U、V、W反电动势需满足U超前V超前W。
2. 检测编码器定义旋转正方向是否与电机旋转正方向一致。
3. 判断转子位置:编码器读数头获得的霍尔U、V、W信号将转子位置划分为6个区域,霍尔信号,转子位于0-60°位置,则定子给出一与30°位置垂直的磁场使之旋转。
此磁场方向初始一直保持不变,直至遇到第一个霍尔上升下降沿,便进行改变。
此后便根据A、B信号判断转子位置,使定子磁场一直保持与转子磁场垂直。
4. 一边调整,一边观察编码器的U相信号上升沿和电机U相反电势波形由低到高的过零点,最终使上升沿和过零点重合,锁定编码器与电机的相对位置关系,完成对齐。
如需了解更多关于电机霍尔编码器零位校准的信息,建议咨询专业技术人员或者查阅相关的技术手册。
/*功能名称 IM3_PWM_Init(u16 arr,u16 psc)描述 TIM3产生四路PWM*/void TIM3_PWM_Init(u16 arr,u16 psc){GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_OCInitTypeDef TIM_OCInitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE); //使能GPIO外设和AFIO复用功能模块时钟使能GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE); //Timer3全映射GPIOC-> 6,7,8,9 //用于TIM3的CH2输出的PWM通过该LED显示//设置该引脚为复用输出功能,输出TIM3 CH1 CH2 CH3 CH4 的PWM脉冲波形GPIO_InitStructure.GPIO_Pin =GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 |GPIO_Pin_9; //初始化GPIOGPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOC, &GPIO_InitStructure);GPIO_ResetBits(GPIOC,GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 |GPIO_Pin_9);//默认电机使能端状态:不使能TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值这里是72分频,那么时钟频率就是1MTIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS =Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式1TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM 输出比较极性高TIM_OC1Init(TIM3, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMxTIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIMx在CCR1上的预装载寄存器TIM_OC2Init(TIM3, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMxTIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIMx在CCR2上的预装载寄存器TIM_OC3Init(TIM3, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMxTIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIMx在CCR3上的预装载寄存器TIM_OC4Init(TIM3, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMxTIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIMx在CCR4上的预装载寄存器TIM_ARRPreloadConfig(TIM3, ENABLE); //使能TIMx在ARR上的预装载寄存器 TIM_Cmd(TIM3, ENABLE); //使能TIMx外设}/*功能名称 TIM4_PWMINPUT_INIT(u16 arr,u16 psc)描述 PWM输入初始化*/void TIM4_PWMINPUT_INIT(u16 arr,u16 psc){TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //TIM的初始化结构体NVIC_InitTypeDef NVIC_InitStructure; //中断配置TIM_ICInitTypeDef TIM4_ICInitStructure; //TIM4 PWM配置结构体 GPIO_InitTypeDef GPIO_InitStructure; //IO口配置结构体RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //Open TIM4 clockRCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //open gpioB clock GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //GPIO 7GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS =Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位/*配置中断优先级*/NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);TIM4_ICInitStructure.TIM_Channel = TIM_Channel_2;TIM4_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;TIM4_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;TIM4_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;TIM4_ICInitStructure.TIM_ICFilter = 0x3; //Filter:过滤TIM_PWMIConfig(TIM4, &TIM4_ICInitStructure); //PWM输入配置TIM_SelectInputTrigger(TIM4, TIM_TS_TI2FP2); //选择有效输入端TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Reset); //配置为主从复位模式TIM_SelectMasterSlaveMode(TIM4, TIM_MasterSlaveMode_Enable);//启动定时器的被动触发TIM_ITConfig(TIM4, TIM_IT_CC2|TIM_IT_Update, ENABLE); //中断配置TIM_ClearITPendingBit(TIM4, TIM_IT_CC2|TIM_IT_Update); //清除中断标志位TIM_Cmd(TIM4, ENABLE);}void TIM4_IRQHandler(void){if (TIM_GetITStatus(TIM4, TIM_IT_CC2) != RESET)//捕获1发生捕获事件 {duty_TIM4 = TIM_GetCapture1(TIM4); //采集占空比if (TIM_GetCapture2(TIM4)>600) period_TIM4 =TIM_GetCapture2(TIM4);//简单的处理CollectFlag_TIM4 = 0;}TIM_ClearITPendingBit(TIM4, TIM_IT_CC2|TIM_IT_Update); //清除中断标志位}/*功能名称 TIM1_PWMINPUT_INIT(u16 arr,u16 psc)描述 PWM输入初始化*/void TIM1_PWMINPUT_INIT(u16 arr,u16 psc){TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //TIM的初始化结构体NVIC_InitTypeDef NVIC_InitStructure; //中断配置TIM_ICInitTypeDef TIM1_ICInitStructure; //PWM配置结构体GPIO_InitTypeDef GPIO_InitStructure; //IO口配置结构体RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); //Open TIM1 clockRCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); //open gpioE clockGPIO_PinRemapConfig(GPIO_FullRemap_TIM1, ENABLE); //Timer1完全重映射TIM1_CH2->PE11GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; //GPIO 11GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOE, &GPIO_InitStructure);TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS =Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位/*配置中断优先级*/NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn; //TIM1捕获中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);TIM1_ICInitStructure.TIM_Channel = TIM_Channel_2;TIM1_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;TIM1_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;TIM1_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;TIM1_ICInitStructure.TIM_ICFilter = 0x03; //Filter:过滤TIM_PWMIConfig(TIM1, &TIM1_ICInitStructure); //PWM输入配置TIM_SelectInputTrigger(TIM1, TIM_TS_TI2FP2); //选择有效输入端TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Reset); //配置为主从复位模式TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);//启动定时器的被动触发// TIM_ITConfig(TIM1, TIM_IT_CC2|TIM_IT_Update, ENABLE); //中断配置TIM_ITConfig(TIM1, TIM_IT_CC2, ENABLE); //通道2 捕获中断打开//TIM_ClearITPendingBit(TIM1, TIM_IT_CC2|TIM_IT_Update); //清除中断标志位 TIM_Cmd(TIM1, ENABLE);}void TIM1_CC_IRQHandler(void){{if (TIM_GetITStatus(TIM1, TIM_IT_CC2) != RESET)//捕获1发生捕获事件 {duty_TIM1 = TIM_GetCapture1(TIM1); //采集占空比if (TIM_GetCapture2(TIM1)>600) period_TIM1 = TIM_GetCapture2(TIM1);CollectFlag_TIM1 = 0;}}TIM_ClearITPendingBit(TIM1, TIM_IT_CC2|TIM_IT_Update); //清除中断标志位}/*功能名称 TIM2_PWMINPUT_INIT(u16 arr,u16 psc)描述 PWM输入初始化*/void TIM2_PWMINPUT_INIT(u16 arr,u16 psc){TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //TIM的初始化结构体NVIC_InitTypeDef NVIC_InitStructure; //中断配置TIM_ICInitTypeDef TIM2_ICInitStructure; //TIM2 PWM配置结构体GPIO_InitTypeDef GPIO_InitStructure; //IO口配置结构体RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //Open TIM2 clock// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //open gpioB clockRCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); //使能GPIO外设和AFIO复用功能模块时钟GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); //关闭JTAGGPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE); //Timer2完全重映射TIM2_CH2->PB3GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //GPIO 3GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //浮空输入上拉输入GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS =Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位/*配置中断优先级*/NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);TIM2_ICInitStructure.TIM_Channel = TIM_Channel_2;TIM2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;TIM2_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;TIM2_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;TIM2_ICInitStructure.TIM_ICFilter = 0x3; //Filter:过滤TIM_PWMIConfig(TIM2, &TIM2_ICInitStructure); //PWM输入配置TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2); //选择有效输入端TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset); //配置为主从复位模式TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);//启动定时器的被动触发TIM_ITConfig(TIM2, TIM_IT_CC2|TIM_IT_Update, ENABLE); //中断配置TIM_ClearITPendingBit(TIM2, TIM_IT_CC2|TIM_IT_Update); //清除中断标志位TIM_Cmd(TIM2, ENABLE);}void TIM2_IRQHandler(void){{if (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET)//捕获1发生捕获事件{duty_TIM2 = TIM_GetCapture1(TIM2); //采集占空比if (TIM_GetCapture2(TIM2)>600) period_TIM2 = TIM_GetCapture2(TIM2);CollectFlag_TIM2 = 0;}}TIM_ClearITPendingBit(TIM2, TIM_IT_CC2|TIM_IT_Update); //清除中断标志位}/*功能名称 TIM5_PWMINPUT_INIT(u16 arr,u16 psc)描述 PWM输入初始化*/void TIM5_PWMINPUT_INIT(u16 arr,u16 psc){TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //TIM的初始化结构体NVIC_InitTypeDef NVIC_InitStructure; //中断配置TIM_ICInitTypeDef TIM5_ICInitStructure; //TIM4 PWM配置结构体 GPIO_InitTypeDef GPIO_InitStructure; //IO口配置结构体RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); //Open TIM4 clockRCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //open gpioB clock GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //GPIO 1GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //浮空输入上拉输入GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS =Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位/*配置中断优先级*/NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);TIM5_ICInitStructure.TIM_Channel = TIM_Channel_2;TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;TIM5_ICInitStructure.TIM_ICFilter = 0x3; //Filter:过滤TIM_PWMIConfig(TIM5, &TIM5_ICInitStructure); //PWM输入配置TIM_SelectInputTrigger(TIM5, TIM_TS_TI2FP2); //选择有效输入端TIM_SelectSlaveMode(TIM5, TIM_SlaveMode_Reset); //配置为主从复位模式TIM_SelectMasterSlaveMode(TIM5, TIM_MasterSlaveMode_Enable);//启动定时器的被动触发TIM_ITConfig(TIM5, TIM_IT_CC2|TIM_IT_Update, ENABLE); //中断配置TIM_ClearITPendingBit(TIM5, TIM_IT_CC2|TIM_IT_Update); //清除中断标志位TIM_Cmd(TIM5, ENABLE);}void TIM5_IRQHandler(void){{if (TIM_GetITStatus(TIM5, TIM_IT_CC2) != RESET)//捕获1发生捕获事件 {duty_TIM5 = TIM_GetCapture1(TIM5); //采集占空比if (TIM_GetCapture2(TIM5)>600) period_TIM5 = TIM_GetCapture2(TIM5);CollectFlag_TIM5 = 0;}}TIM_ClearITPendingBit(TIM5, TIM_IT_CC2|TIM_IT_Update); //清除中断标志位}PID部分typedef struct{int setpoint;//设定目标int sum_error;//误差累计float proportion ;//比例常数float integral ;//积分常数float derivative;//微分常数int last_error;//e[-1]int prev_error;//e[-2]}PIDtypedef;float Kp = 0.32 ; //比例常数float Ti = 0.09 ; //积分时间常数float Td = 0.0028 ; //微分时间常数#define T 0.02 //采样周期#define Ki Kp*(T/Ti) // Kp Ki Kd 三个主要参数#define Kd Kp*(Td/T)PID.Hvoid PIDperiodinit(u16 arr,u16 psc); //PID 采样定时器设定void incPIDinit(void); //初始化,参数清零清零int incPIDcalc(PIDtypedef*PIDx,u16 nextpoint); //PID计算void PID_setpoint(PIDtypedef*PIDx,u16 setvalue); //设定 PID预期值void PID_set(float pp,float ii,float dd);//设定PID kp ki kd三个参数void set_speed(float W1,float W2,float W3,float W4);//设定四个电机的目标转速int incPIDcalc(PIDtypedef *PIDx,u16 nextpoint){int iError,iincpid;iError=PIDx->setpoint-nextpoint; //当前误差/*iincpid= //增量计算PIDx->proportion*iError //e[k]项-PIDx->integral*PIDx->last_error //e[k-1]+PIDx->derivative*PIDx->prev_error;//e[k-2]*/iincpid= //增量计算PIDx->proportion*(iError-PIDx->last_error)+PIDx->integral*iError+PIDx->derivative*(iError-2*PIDx->last_error+PIDx->prev_error);PIDx->prev_error=PIDx->last_error; //存储误差,便于下次计算PIDx->last_error=iError;return(iincpid) ;}void TIM6_IRQHandler(void) // 采样时间到,中断处理函数{if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET)//更新中断{frequency1=1000000/period_TIM4 ; //通过捕获的波形的周期算出频率frequency2=1000000/period_TIM1 ;frequency3=1000000/period_TIM2 ;frequency4=1000000/period_TIM5 ;/********PID1处理**********/PID1.sum_error+=(incPIDcalc(&PID1,frequency1)); //计算增量并累加 pwm1=PID1.sum_error*4.6875 ; //pwm1 代表将要输出PWM的占空比frequency1=0; //清零period_TIM4=0;/********PID2处理**********/PID2.sum_error+=(incPIDcalc(&PID2,frequency2)); //计算增量并累加Y=Y+Y'pwm2=PID2.sum_error*4.6875 ; //将要输出PWM的占空比frequency2=0;period_TIM1=0;/********PID3处理**********/PID3.sum_error+=(incPIDcalc(&PID3,frequency3)); //常规PID控制pwm3=PID3.sum_error*4.6875 ; //将要输出PWM的占空比frequency3=0;period_TIM2=0;/********PID4处理**********/PID4.sum_error+=(incPIDcalc(&PID4,frequency4)); //计算增量并累加pwm4=PID4.sum_error*4.6875 ; //将要输出PWM的占空比frequency4=0;period_TIM5=0;}TIM_SetCompare(pwm1,pwm2,pwm3,pwm4); //重新设定PWM值 TIM_ClearITPendingBit(TIM6, TIM_IT_Update); //清除中断标志位}。