有哪些常用的推挽电路最简单的芯片,要200KHz的,谢谢

一工频逆变器用SG3525驱动,既然是推挽,何必设置死区?其用意何在?另外,可否用80NF70取...
问题描述:
一工频逆变器用SG3525驱动,既然是推挽,何必设置死区?其用意何在?另外,可否用80NF70取...一工频逆变器用SG3525驱动,既然是推挽,何必设置死区?其用意何在?另外,可否用80NF70取代75NF75?五个管子并联使用,如果用同一批,不配对,栅极防振电阻用470欧姆的,请赐教!
问题解答:
不设置死区,上管导通还没完全关断时下管也导通,会致损耗加大烧管.你说的管子可以代替用,只要防振电阻不共用即可.
我来回答:
剩余:2000字
设置死区是为了保护驱动管的,防止一个没有完全关闭而另一个就开通了,用80NF70取代75NF75是没有问题的,不配对也可以用,但考到安全最好还是配对
可以 不过3525频率最低才100hz,
逆变器是自激还是它激的,首先将高频变压器更换成工频变压器,电路的振荡频率也做调整. 再问: 逆变器用的是高频,ZVS驱动 再答: 哦!那要改成工频很麻烦的,为什么要改工频,是理论探讨?
原因是你的交流电有频率吧,也就是正负极颠倒的频率,那么很简单,我只要把我的电机加上换向器,初中课本电动机一章有讲到,频率和交流电一致,每当交流电的正负极交换,我的换向器就交换电机接入口的正负极,正好使此时正负极反向接入,负负得正,以此类推,电机就能沿一个方向继续转下去!
五脚电容和六脚电阻,的大小直接影响着频率,想要详细的不妨你加我,一一帮你解答
两块电池板串联以后可以接在48伏电瓶上面但是24伏发电机不能接在电瓶组的24伏抽头上面因为有发电机供电的电瓶要比没有发电机供电的电瓶充电电流要多,会引起人为的充电不均衡,会使整个电池组使用寿命急剧下降.应该考虑把24伏风力发电机组成单独系统即:24伏电瓶组,24伏逆变器.
正弦波逆变器好
能是能,但是功率好像达不到要求的,它的电流太小了,如果太大,就要烧毁的.小心了
第一;你的换能器的中心频率是250K,你的MOS管的频率是2.75Khz,这个肯定有问题,探头的信号几乎发射不出去.探头的频率是多少,你就要加跟他频率一样的信号给它.这样它的性能才能处于最佳状态.第二:发射的时候有正弦震荡,这个震荡频率是因为变压器输出端的电感引起的,频率跟电感量有关.
用马克思发生器 再问: 那个驱动ZVS的电源有什么要求啊? 再答: 最大联压36伏 再答: 3000伏安 再答: 谢谢啦!
解题思路: 逆变器解题过程: 光伏逆变器600W正弦波逆变器制作详解(组图) (发布日期: 10:29:00) 浏览人数:1029 自从公布了1KW正弦波逆变器的制作过程后,有不少朋友来信息,提这样那样的问题,很多都是象我这样的初学者。为此,我又花了近一个月的时间,制作了这台600W的正弦波逆变器,
逆变器方法:1- 设法产生一对高低交叉的数字震荡信号,相位差180度,注意设置死区.震荡信号最低频率一般要按照1000Hz设计.2- 震荡信号分别去控制一个开关管,一般用VMOS管,型号取决于你系统的参数.可在IRF打头的管子中选取.3- 开关管后接自设计的高频变压器,注意:不是通常的工频那种.4- 根据85%的转换效
逆变器(inverter)是把直流电能(电池、蓄电瓶)转变成交流电(一般为220v50HZ正弦或方波).应急电源,一般是把直流电瓶逆变成220V交流的. 通俗的讲,逆变器是一种将直流电(DC)转化为交流电(AC)的装置.它由逆变桥、控制逻辑和滤波电路组成. 利用TL494组成的400W大功率稳压逆变器电路.它激式变换部
设计功率、频率大小?磁芯大小?3205吧?单边5个共10个?这个要加三极管才行,先测空载,注意推挽两路平衡,单边肯定是烧的,静态电流小于0.3A为佳,频率也不能过高过低,磁芯空隙或滤波不好都可能损坏管.输出符合灯泡电压,看管的温度慢慢加负载.
一.管子温度高.(开机,空载情况下) 1.可能在变压器的制作与材料的选取上.2.驱动电路没加低通放电与快充电电路.3.IC电压直接取于电池,没在IC正负供电两边接上35v100uf滤波电容.(这个很有必要)4.栅极信号接入电阻过大,一般在10欧姆到100欧姆间选取.二.滤波电容温度过高.原因在于电路中没加入吸收电路或是
变压器做不好.你的可能是界限接错了.两个初级线圈是要构成推挽的,还有不能先绕一个,应该两根线并绕.我不知道你用多大的磁心做的,反正我用EE42做的都是绕3圈,你绕8圈做什么?还有用KA3525的驱动频率我是做在20K-35KHZ的.你的是不是频率低了.
一:多功能逆变器简介OR系列多功能工频逆变器可为商务,家用,工作站提供可靠的正弦波电源.可选择1000W到6000W的型号,它可以用在最常见的电力电器,如轮船,重型卡车,工业设备,空调,电视机,收银机,冰箱,洗衣机,电脑,电动工具.逆变器的高过载能力,使它能够启动较大的电机负载.一旦启动,所有逆变功能是完全自动的.OR
逆变器是个统称.它包括方波逆变器、正弦波逆变器,修正弦波逆变器、工频逆变器正弦波RONZ电源逆变器输出的是同我们日常使用的电网一样甚至更好的正弦波交流电,因为它不存在电网中的电磁污染.方波RONZ电源逆变器输出的则是质量较差的方波交流电,其正向最大值到负向最大值几乎在同时产生(见下图),这样,对负载和RONZ电源逆变器
纯正弦波逆变器的输出电压就是AC220V,50HZ,跟市电波形一样.但是价格要高于修正波.纯正弦波又分高频和工频,高频逆变器家庭用(电机类)就可以,如果是通信工程就得用工频逆变器.两者价格差距也是很大的.我是专业销售蓄电池、逆变器、充电机等电源设备,
也许感兴趣的知识1.7K146 条评论分享收藏感谢收起赞同 2915 条评论分享收藏感谢收起原文地址:http://www.amobbs.com/thread--1.html
硬件部分:控制系统的控制对象是4个空心杯直流电机,电机带光电编码器,可以反馈转速大小的波形。电机驱动模块是普通的L298N模块。芯片型号,STM32F103ZET6软件部分:PWM输出:TIM3,可以直接输出4路不通占空比的PWM波PWM捕获:STM32除了TIM6 TIM7其余的都有捕获功能,使用TIM1 TIM2 TIM4 TIM5四个定时器捕获四个反馈信号PID的采样和处理:使用了基本定时器TIM6,溢出时间就是我的采样周期,理论上T越小效果会越好,这里我取20ms,依据控制对象吧,如果控制水温什么的采样周期会是几秒几分钟什么的。上面的PWM输出和捕获关于定时器的设置都有例程,我这里是这样的:TIM3输出四路PWM,在引脚 C 的 GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9输出四路捕获分别是TIM4&&TIM1&&TIM2&&TIM5& &,对应引脚是:&&PB7 PE11 PB3 PA1高级定时器tim1的初始化略不同,它的中断&名称&和通用定时器不同,见代码:
/*功能名称?IM3_PWM_Init(u16 arr,u16 psc)
& & & & 描述& && &TIM3产生四路PWM
void TIM3_PWM_Init(u16 arr,u16 psc)
& & & & GPIO_InitTypeDef GPIO_InitS
& & & & TIM_TimeBaseInitTypeDef&&TIM_TimeBaseS
& & & & TIM_OCInitTypeDef&&TIM_OCInitS
& & & & 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; //初始化GPIO
& & & & GPIO_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 = //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
& & & & TIM_TimeBaseStructure.TIM_Prescaler = //设置用来作为TIMx时钟频率除数的预分频值&&这里是72分频,那么时钟频率就是1M&
& & & & TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
& & & & TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;&&//TIM向上计数模式
& & & & TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
& & & & TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式1
& & & & TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_E //比较输出使能
& & & & TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值
& & & & TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_H //输出极性:TIM输出比较极性高
& & & & TIM_OC1Init(TIM3, &TIM_OCInitStructure);&&//根据TIM_OCInitStruct中指定的参数初始化外设TIMx
& & & & TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);&&//使能TIMx在CCR1上的预装载寄存器
& & & & TIM_OC2Init(TIM3, &TIM_OCInitStructure);&&//根据TIM_OCInitStruct中指定的参数初始化外设TIMx
& & & & TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);&&//使能TIMx在CCR2上的预装载寄存器
& & & & TIM_OC3Init(TIM3, &TIM_OCInitStructure);&&//根据TIM_OCInitStruct中指定的参数初始化外设TIMx
& & & & TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);&&//使能TIMx在CCR3上的预装载寄存器
& & & & TIM_OC4Init(TIM3, &TIM_OCInitStructure);&&//根据TIM_OCInitStruct中指定的参数初始化外设TIMx
& & & & TIM_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_TimeBaseS& & & & //TIM的初始化结构体
& & & & NVIC_InitTypeDef NVIC_InitS& & & & & & & & & & & & //中断配置
& & & & TIM_ICInitTypeDef&&TIM4_ICInitS& & & & & & & &&&//TIM4&&PWM配置结构体
& & & & GPIO_InitTypeDef GPIO_InitS& & & & & & & & & & & &&&//IO口配置结构体
& & & & RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);& &&&//Open TIM4 clock
&&RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);&&//open gpioB clock
& & & & GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;& && && && & //GPIO 7
&&GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;& & & && &//上拉输入
&&GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
&&GPIO_Init(GPIOB, &GPIO_InitStructure);
& & & & TIM_TimeBaseStructure.TIM_Period = //设置在下一个更新事件装入活动的自动重装载寄存器周期的值&&
& & & & TIM_TimeBaseStructure.TIM_Prescaler = //设置用来作为TIMx时钟频率除数的预分频值&&
& & & & TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
& & & & TIM_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_R& && &&
&&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_TimeBaseS& & & & //TIM的初始化结构体
& & & & NVIC_InitTypeDef NVIC_InitS& & & & & & & & & & & & //中断配置
& & & & TIM_ICInitTypeDef&&TIM1_ICInitS& & & & & & & &&&//PWM配置结构体
& & & & GPIO_InitTypeDef GPIO_InitS& & & & & & & & & & & &&&//IO口配置结构体
& & & & RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);& &&&//Open TIM1 clock
&&RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);&&//open gpioE clock
& &GPIO_PinRemapConfig(GPIO_FullRemap_TIM1, ENABLE); //Timer1完全重映射&&TIM1_CH2-&PE11& & & &&
& & & & GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;& && && && & //GPIO 11
&&GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;& & & && &//上拉输入
&&GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
&&GPIO_Init(GPIOE, &GPIO_InitStructure);
& & & & TIM_TimeBaseStructure.TIM_Period = //设置在下一个更新事件装入活动的自动重装载寄存器周期的值&&
& & & & TIM_TimeBaseStructure.TIM_Prescaler = //设置用来作为TIMx时钟频率除数的预分频值&&
& & & & TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
& & & & TIM_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_R& && &&
&&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_TimeBaseS& & & & //TIM的初始化结构体
& & & & NVIC_InitTypeDef NVIC_InitS& & & & & & & & & & & & //中断配置
& & & & TIM_ICInitTypeDef&&TIM2_ICInitS& & & & & & & &&&//TIM2&&PWM配置结构体
& & & & GPIO_InitTypeDef GPIO_InitS& & & & & & & & & & & &&&//IO口配置结构体
& & & & RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);& &&&//Open TIM2 clock
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);&&//open gpioB clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB&&| RCC_APB2Periph_AFIO, ENABLE);&&//使能GPIO外设和AFIO复用功能模块时钟
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);& && && & //关闭JTAG
& & & & GPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE); //Timer2完全重映射&&TIM2_CH2-&PB3
& & & & GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;& && && && & //GPIO 3
& & & & GPIO_InitStructure.GPIO_Mode =&&GPIO_Mode_IPU;& & & && &//浮空输入 上拉输入
& & & & GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
& & & & GPIO_Init(GPIOB, &GPIO_InitStructure);
& & & & TIM_TimeBaseStructure.TIM_Period = //设置在下一个更新事件装入活动的自动重装载寄存器周期的值&&
& & & & TIM_TimeBaseStructure.TIM_Prescaler = //设置用来作为TIMx时钟频率除数的预分频值&&
& & & & TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
& & & & TIM_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_R& && &&
&&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_TimeBaseS& & & & //TIM的初始化结构体
& & & & NVIC_InitTypeDef NVIC_InitS& & & & & & & & & & & & //中断配置
& & & & TIM_ICInitTypeDef&&TIM5_ICInitS& & & & & & & &&&//TIM4&&PWM配置结构体
& & & & GPIO_InitTypeDef GPIO_InitS& & & & & & & & & & & &&&//IO口配置结构体
& & & & RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);& &&&//Open TIM4 clock
&&RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);&&//open gpioB clock
& & & & GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;& && && && & //GPIO 1
&&GPIO_InitStructure.GPIO_Mode =&&GPIO_Mode_IPU;& & & && &//浮空输入 上拉输入
&&GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
&&GPIO_Init(GPIOA, &GPIO_InitStructure);
& & & & TIM_TimeBaseStructure.TIM_Period = //设置在下一个更新事件装入活动的自动重装载寄存器周期的值&&
& & & & TIM_TimeBaseStructure.TIM_Prescaler = //设置用来作为TIMx时钟频率除数的预分频值&&
& & & & TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
& & & & TIM_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_R& && &&
&&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部分:准备部分:先定义PID结构体:
typedef struct&
//设定目标
int sum_//误差累计
//比例常数
//积分常数
//微分常数
int last_//e[-1]
int prev_//e[-2]
这里注意一下成员的数据类型,依据实际需要来定的。在文件中定义几个关键变量:
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)
C语言好像用#define 什么什么对程序不太好,各位帮忙写个优化办法看看呢? 用const?PID.H里面主要的几个函数:
void 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);//设定四个电机的目标转速
PID处理过程:岔开一下:这里我控制的是电机的转速w,实际上电机的反馈波形的频率f、电机转速w、控制信号PWM的占空比a三者是大致线性的正比的关系,这里强调这个的目的是因为楼主在前期一直搞不懂我控制的转速怎么和TIM4输出的PWM的占空比联系起来,后来想清楚里面的联系之后通过公式把各个系数算出来了。正题:控制流程是这样的,首先我设定我需要的车速(对应四个轮子的转速),然后PID就是开始响应了,它先采样电机转速,得到偏差值E,带入PID计算公式,得到调整量也就是最终更改了PWM的占空比,不断调节,直到转速在稳态的一个小范围上下浮动。上面讲到的&得到调整量&就是增量PID的公式:
int incPIDcalc(PIDtypedef *PIDx,u16 nextpoint)
int iError,
iError=PIDx-&setpoint-&&//当前误差
/*iincpid=& & & & & & & & & & & & & & & & & & & && && &&&//增量计算
PIDx-&proportion*iError& & & && && && &//e[k]项
-PIDx-&integral*PIDx-&last_error& & & && &//e[k-1]
+PIDx-&derivative*PIDx-&prev_//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_ //存储误差,便于下次计算
PIDx-&last_error=iE
return(iincpid) ;
注释掉的是第一种写法,没注释的是第二种以Kp KI kd为系数的写法,实际结果是一样的。处理过程放在了TIM6,溢出周期时间就是是PID里面采样周期(区分于反馈信号的采样,反馈信号采样是1M的频率)相关代码:
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); //清除中断标志位& & & & & & & &&
上面几个代码是PID实现的关键部分整定过程:办法有不少,这里用的是先KP,再TI,再TD,在微调。其他的办法特别是有个尼古拉斯法我发现不适合我这个控制对象。先Kp,就是消除积分和微分部分的影响,这里我纠结过到底是让Ti 等于一个很大的值让Ki=Kp*(T/Ti)里面的KI接近零,还是直接定义KI=0,TI=0.然后发现前者没法找到KP使系统震荡的临界值,第二个办法可以得到预期的效果:即KP大了会产生震荡,小了会让系统稳定下来,当然这个时候是有稳态误差的。随后把积分部分加进去,KI=Kp*(T/Ti)这个公式用起来,并且不断调节TI 。TI太大系统稳定时间比较长。然后加上Kd& & & & =Kp*(Td/T),对于系统响应比较滞后的情况效果好像好一些,我这里的电机反映挺快的,所以Td值很小。最后就是几个参数调节一下,让波形好看一点。这里的波形实际反映的是采集回来的转速值,用STM32的DAC功能输出和转速对应的电压,用示波器采集的。
关于定时器的一些设置做在了main函数里面,上面没给出,现在贴出来!float&&Kp =& &&&0.32&&; //比例常数float&&Ti =& & & & & & & & 0.09 ; //积分常数float Td =& & & & & & & & 0.015 ;&&//微分常数#define T&&& & & & & & & & 0.02 //采样周期//#define Ka & & & & Kp*(1+(T/Ti)+(Td/T)) //另一种公式的三个参数//#define Kb& &&&(Kp)*(1+(2*Td/T))//#define Kc& & & & & & & & Kp*Td/T#define Ki& &&&Kp*(T/Ti)& & & & // Kp Ki Kd 三个主要参数#define Kd& & & & & & & & Kp*(Td/T)u8 start_flag=0;u16 pwm1=0,pwm2=0,pwm3=0,pwm4=0;&&//PWM 波形占空量 占空比=PWMx/7200u8 flag_lcd=0;//液晶屏幕更新标志u8 flag_bluetooth =0;//蓝牙验证状态& && &1:已发出验证信息&&0:未发出验证信息u8 status_bluetooth=0;//蓝牙连接状态位& &1:已连接& & & & & & & & & & & &&&0:未连接int main(void){& & & & u8 len ,t;& & & & SystemInit();& & & & delay_init(72);& & & && && && & & & & & & & //延时初始化& & & & NVIC_Configuration();&&& & & & //中断配置&&中断分组2:2位抢占优先级,2位响应优先级& & & & init_LCD_IO() ;& & & & & & & & & & & & & & & && & //初始化LCD控制引脚 PG4 5& & & & uart_init(9600);& & & & & & & & & & & & & & & & //串口初始化& &lcd_init();& & & & & & & & & & & & & & & & & & & && & //LCD显示& &LED_GPIO_Config();& && && && & // led 初始化& && &MOTOR_INIT();& && & & & Dac1_Init();& & & & & & & & & & & & & & & & //DAC初始化& && & & & incPIDinit();& && && && && && &//PID初始化 置零fuzzy_init()&&;& & KEY_Init();& & & & EXTIX_Init();& & & & & & & &&&& & & & //外部中断初始化& &&& & & & TIM3_PWM_Init(-1);& && & & & //参数1*参数2/(72e6)=1/f& & f:需要的电机频率& & & & //PWM输出&&频率:1KHZ&&pwm周期:1000us& & & & 参数: -1& & & & 定时器频率 1M&&特点;电机频率太低,电机噪音,精度Vmax/1000& & & & //PWM输出&&频率:10KHZ&&pwm周期:100us& & & & 参数: 100-1 72-1&&& & & & 定时器频率 1M&&特点;频率合适,控制精度太低& & & & //PWM输出&&频率:10KHZ&&周期:7200& & & & 参数: -1& & & & TIM4_PWMINPUT_INIT(0xffff,72-1);& &//pwm输入初始化以1M的频率捕捉& & & & TIM1_PWMINPUT_INIT(0xffff,72-1);& &//pwm输入初始化以1M的频率捕捉& & & & TIM2_PWMINPUT_INIT(0xffff,72-1);& &//pwm输入初始化以1M的频率捕捉& & & & TIM5_PWMINPUT_INIT(0xffff,72-1);& &//pwm输入初始化以1M的频率捕捉& &MOTOR_OUT(1,0,1,0,1,0,1,0);//转速全为正,速度都是0& & & & PID_set(Kp,Ki,Kd);& & & & & & & & & & & & //初始化 PID参数& & & & & & & &&&& & printf("Kp=%f\r\n",Kp);& & & && & //输出参数:便于调试观察& & printf("Ki=%f\r\n",Ki);& & printf("Kd=%f\r\n",Kd);//& &PID_setpoint(&PID1,500);& &//开机就设定轮子转动,便于调试,可注释掉//& & & & PID_setpoint(&PID2,200);//& & & & PID_setpoint(&PID3,500);//& & & & PID_setpoint(&PID4,300);& & & & PIDperiodinit(40,36000-1);& & & & & & & && &//设定PID采样周期 T=20ms& & & && & 000 = 2 KHz& & & && &和 T 对应& &//set_speed(3,3,3,3);& &TIM_Cmd(TIM6, ENABLE);&&//使能TIMx 开启PID处理& && &while(1)& &{//& &printf("Kp=%f\r\n",PID3.proportion2);& & & && & //输出参数:便于调试观察& && & & & if(USART_RX_STA&0x8000)& & & && &//如果完成一次接收& & & & & & & & {& & & &&& & & & & & & && & TIM_Cmd(TIM6, DISABLE);&&//& & & &&&关闭PID运算& & & & & & & && & stop(); //PID相关参数清零,并且小车停止运动& & & & & & & & & & & & & & & && &&& & & & & & & & & & & & len=USART_RX_STA&0x3//得到此次接收到的数据长度,本控制系统应该len==15&&或者 2& & & & & & & & & & & & printf("MCU_GET:");& & & & & & & & & & & & for(t=0;t&t++) //返回所以数值& & & & & & & & & & & & {& & & & & & & & & & & & & & & & USART_SendData(USART1, USART_RX_BUF[t]);//向串口1发送数据& & & & & & & & & & & & & & & & while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束& & & & & & & & & & & & }& & & & & & & & & & & & printf("\r\n");//插入换行& & & & & & & & & & & & if(len==15)& & & &&&//长度15的是速度控制报文& & & & & & & && &{& & & && && & & & LED1=0;// LIGHT ON& & & && && && &//报文格式 :x+正负号+x速度+y+正负号+y速度+w+正负号+w速度& && && && &//例如& &&&:x+123y+000w+000,表示只有x方向速度的,其余均为零的& & & & & & & & & & & & table1[3]=USART_RX_BUF[1];table1[4]=USART_RX_BUF[2]; table1[5]=USART_RX_BUF[3];table1[6]=USART_RX_BUF[4];& & & & //更新到LCD& & & & & & & & & & & & table2[3]=USART_RX_BUF[6];table2[4]=USART_RX_BUF[7]; table2[5]=USART_RX_BUF[8];table2[6]=USART_RX_BUF[9];& & & & & & & & & & & & table3[3]=USART_RX_BUF[11];table3[4]=USART_RX_BUF[12]; table3[5]=USART_RX_BUF[13];table3[6]=USART_RX_BUF[14];& & & & & & & & & & & & lcd_init();& & & & & & & & & & & & & & & & & & & && & //LCD显示& & & & & & & & & & & & X=(USART_RX_BUF[2]-0x30)*100+(USART_RX_BUF[3]-0x30)*10+(USART_RX_BUF[4]-0x30) ;& & & && &//得到Vx& & & & & & & & & & & & if(USART_RX_BUF[1]=='-')X=-X; //加上正负号& & & & & & & & & & & & & & & & & & & & & & & &&& & & & & & & & & & & & Y=(USART_RX_BUF[7]-0x30)*100+(USART_RX_BUF[8]-0x30)*10+(USART_RX_BUF[9]-0x30) ;& & & &&&//得到Xy& & & & & & & && &&&if(USART_RX_BUF[6]=='-')Y=-Y;& & & & & & & & & & & & & & & & & & & &&& & & & & & & & & & & & W=(USART_RX_BUF[12]-0x30)*100+(USART_RX_BUF[13]-0x30)*10+(USART_RX_BUF[14]-0x30) ; //得到w& & & & & & & & & & & & W=W/100.0;& & & && &//实际的W值缩小100倍& & & & & & & && &&&if(USART_RX_BUF[11]=='-')W=-W;& & & & & & & & & & & & & & & & & & & &&& & & & & & & & & & & & printf("X=%d\r\n",X);&&//参数反馈,便于调试& & & & & & & & & & & & printf("Y=%d\r\n",Y);& & & & & & & & & & & & printf("W=%f\r\n",W);& & & & & & & & & & & & kinematics(X,Y,W,&W1,&W2,&W3,&W4); //运动学方程计算,得到四个轮子的转速& & & & & & & & & & & & printf("W1=%f\r\n",W1);& & & & & & & & & & & & printf("W2=%f\r\n",W2);& & & & & & & & & & & & printf("W3=%f\r\n",W3);& & & & & & & & & & & & printf("W4=%f\r\n",W4);& & & & & & & & //& & & & LED0=!LED0;& & & & & & & && &//LED翻转& && && && & set_speed(W1,W2,W3,W4);&&//设定轮子转速,实际是更新了PID目标值& && & & & & & & & & & & &&&TIM_Cmd(TIM6, ENABLE);&&//使能TIMx 开启PID& & & & & & & & & & & &&&& & & & LED1=1;// LIGHT Off& & & & & & & && & }& & & & & & & && & if(len==2)& & & & & & & && & {& & & & & & & && & if ((USART_RX_BUF[0]=='B') && (USART_RX_BUF[1]=='L') && (flag_bluetooth==1))& & & & & & & & & & & & & & & &&&{&&status_bluetooth=1 ;& & & & & & & & & & & & & & & && & flag_bluetooth=0;& & & & & & & & & & & & & & & && & printf("blue_OK\r\n");& & & & & & & & & & & & & & & && &}& & & & & & & && & }& & & && & USART_RX_STA=0;& & & && &//数据处理完毕,清除状态寄存器,准备下组数据接收& & & && & len=0;}& &&}}
&(1)这种调速方法,有没有经过脉冲负载加载到电机上,看看速度调整的响应时间,还能和你示波器输出的波形差不多?
示波器显示的是反馈信号的频率f 对应的DAC电压,想不出别的办法来看响应曲线了。也用示波器观看电机过的输入电压值,发现看不出什么东西..
&(2)pwm3=PID3.sum_error*4.6875 ;& &//将要输出PWM的占空比,他的pid输出与pwm是怎么对应的?
电机反馈信号的频率f 和电机是成正比的,也就是说,我如果需要电机转速 w=2pi rad/s的话,我对应的捕获频率是电机在这个转速时光电编码器反馈波形的频率大小。所以我PID计算的其实是以这个频率为标准的调整量,PID的设定值也是频率,增量计算的也是频率,当然你用转速 w 和PWM占空比 a 做PID的计算也是可行的,只要找到 转速=(系数1)*频率=(系数2)*占空比 这个关系里面的系数就行。我来说说这个4.6875怎么来的吧,这里我把占空比看成&占空量&(占空比:在一串理想的脉冲周期序列中(如方波),正脉冲的持续时间与脉冲总周期的比值。),如果PWM周期是1000份,高电平是300份,那我的占空量就是300,在STM32里面这个占空量是可以直接作为参数设定给定时器的,用的函数就是setcompare(),你自己查一下历程看看。好,我的电机的最大转速是2rps,也就是一秒2圈,我的编码器这个时候的反馈频率应该是1536(查看编码器的参数),这个时候占空比需要100%,也就是1000的占空量。电机不转呢,反馈频率就是0,占空量就是0。简单的就是占空量对应0频率,1000占空量对应1536频率。得到 占空量=0.651*频率。那我程序是4.6875呢?我继续说!例程里面关于PWM波形输出的TIM3的初始化是:TIM3_PWM_Init(-1);这样就是72分频,定时器频率变成1M,对应成1 us计算很方便。1000是指PWM波形的周期是1000,这里正好是1000us(注意:这里1000这个参数越大,说明占空比的分辨率越高,但是在定时器频率不变的前提下,pwm周期越大,输出PWM的频率就越小)。但是这样的参数下,PWM的频率只有1K,电机产出明显的噪音,经过调试,电机在10K的频率下控制的效果比较好。也就是说我要凑个10Kpwm输出,但是pwm周期不能太小,咱要保证控制精度啊。所以通过计算:TIM3_PWM_Init(-1);//定时器72M运行,周期7200份,电机频率正好是10K好了这里的7200放到之前的计算中,系数就是4.6875了。
&(3)大哥,看了你的帖子收益很多 啊,我现在对pid的理解写给你看看,不知道对不对啊,假设我2v的电压---对应1000的占空量也就是100%,3v电压对应------0的占空量也就是0%,2v和3v是我的最大和最小温度时对应的电压,采集到的温度的电压与占空比成反比,那我根据你的方法计算,占空量=)*Vpid,我的设定值也是以电压为单位的,假设设定的温度对应的电压值为2.5v,采集到的电压为2.3v,那么把2.5v和2.3v带入pid计算也就是Vpid=pid(2.5,2.3);那么最终的pwm值=())*pid(2.5,2.3)?
&2v的电压---对应1000的占空量也就是100%,3v电压对应------0的占空量也就是0%,2v和3v是我的最大和最小温度时对应的电压&光是这句话,你下面的式子就貌似有问题了。电压以mV为单位,1000对应2000mV,0对应3000mV,那么占空量a和电压u的关系就是:3000-u=a。个人认为,我这个思路对于线性系统或者近似线性系统应该问题不大,传统PID对于线性系统是比较适用的,你这里一定要把握好各个物理量之间的变换关系。
(4)大哥,电压以mV为单位,1000对应2000mV,0对应3000mV,那么占空量a和电压u的关系就是:3000-u=a;你这里的mv吗?u是pid运算后得到的电压吗?你是把电压放大了1000倍吗?还有就是如果我的周期的份量是500,那么100%的时候占空量是500,那么他们的对应关系应该是500对应1000mv,0对应1500mv吗?也就是把500对应2v,0对应3v时的电压放大了500倍是吗?
和PID处理无关,U就是你的电压啊,a就是占空量
(5)不知楼主的电机加速过程中有加速算法没有,我一直弄不明白加速算法怎么和PID控制结合起来?我想做步进电机位置环和速度环,加速算法想用梯形加速或者S形加速。
加速算法是不是目的是让小车走出设定的轨迹啊?我样机做出来了,可能会写个矩形的运动轨迹,看看回程误差。X Y方向不停测距差不多能实现。
(6)我想问一下啊&&pwm输出时钟是72M,周期是7200,pwm捕捉又用的是1M时钟,那捕捉到的占空量为什么会是一样的啊?
捕获的频率1M能保证捕获到的信号的周期是正负1us输出PWM的定时器72M的频率。而PWM的周期是7200&份&,算一下PWM的频率是10K。捕获到的是确确实实的高电平时间,能直接用读取寄存器读出来。和我输出的时候设置的占空比或&占高量&没有直接地联系。
(7)楼主你好,void PID_setpoint(PIDtypedef*PIDx,u16 setvalue);&&//设定 PID预期值void set_speed(float W1,float W2,float W3,float W4);//设定四个电机的目标转速预期值难道不是目标转速吗?
简单回答,预期值就是目标值,就是目标转速(单位不一定是r/s)
void PID_setpoint(PIDtypedef*PIDx,u16 setvalue){&&PIDx-&setpoint=&}//确实是设定的预期转速,而且根据实际参数,执行一次的话就是改变了一个PID单元的设定值,即setpointvoid set_speed(float W1,float W2,float W3,float W4)& & & & {& & & & & & & & & & & &&&if(W1&0) & & & & & & & && &//判断W 正负,正数处理& & & && &{&& & & && && & & & motor1_out0=0;& & & && && & & & motor1_out1=1;& & & && && & & & temp=W1*122.23;& & & && && & & & PID_setpoint(&PID1,temp);& & & && &}& & & && &else& &if(W1==0) & & & & & & & & & & & & //零值& & & && &{&& & & && && & & & motor1_out0=0;& & & && && & & & motor1_out1=0;& & & && && & & &&& & & && && & & & PID_setpoint(&PID1,0);& & & && &}& & & && &else & & & & & & & & & & & & & & & && &//负数处理& & & && &{& & & && && & & & motor1_out0=1;& & & & & & & & motor1_out1=0;& & & & & & & & temp=-W1*122.23;& & & & & & & & PID_setpoint(&PID1,temp);& & & & & & & & }&&if(W2&0) & & & & & & & &&& & & && &{&& & & && && & & & motor2_out0=0;& & & && && & & & motor2_out1=1;& & & && && & & & temp=W2*122.23;& & & && && & & & PID_setpoint(&PID2,temp);& & & && &}& & & && &else& &if(W2==0) & & & & & & & &&& & & && &{&& & & && && & & & motor2_out0=0;& & & && && & & & motor2_out1=0;& & & && && & & &&& & & && && & & & PID_setpoint(&PID2,0);& & & && &}& & & && &else & & & & & & & & & & & & & & & &&& & & && &{& & & && && & & & motor2_out0=1;& & & & & & & & motor2_out1=0;& & & & & & & & temp=-W2*122.23;& & & & & & & & PID_setpoint(&PID2,temp);& & & & & & & & }if(W3&0) & & & & & & & &&& & & && &{&& & & && && & & & motor3_out0=0;& & & && && & & & motor3_out1=1;& & & && && & & & temp=W3*122.23;& & & && && & & & PID_setpoint(&PID3,temp);& & & && &}& & & && &else& &if(W3==0) & & & & & & & &&& & & && &{&& & & && && & & & motor3_out0=0;& & & && && & & & motor3_out1=0;& & & && && & & &&& & & && && & & & PID_setpoint(&PID3,0);& & & && &}& & & && &else & & & & & & & & & & & & & & & &&& & & && &{& & & && && & & & motor3_out0=1;& & & & & & & & motor3_out1=0;& & & & & & & & temp=-W3*122.23;& & & & & & & & PID_setpoint(&PID3,temp);& & & & & & & & }&&if(W4&0) & & & & & & & &&& & & && &{&& & & && && & & & motor4_out0=0;& & & && && & & & motor4_out1=1;& & & && && & & & temp=W4*122.23;& & & && && & & & PID_setpoint(&PID4,temp);& & & && &}& & & && &else& &if(W4==0) & & & & & & & &&& & & && &{&& & & && && & & & motor4_out0=0;& & & && && & & & motor4_out1=0;& & & && && & & &&& & & && && & & & PID_setpoint(&PID4,0);& & & && &}& & & && &else & & & & & & & & & & & & & & & &&& & & && &{& & & && && & & & motor4_out0=1;& & & & & & & & motor4_out1=0;& & & & & & & & temp=-W4*122.23;& & & & & & & & PID_setpoint(&PID4,temp);& & & & & & & & }}//这个函数你应该能看出,之前的PID_setpoint()已经包含在里面了。这个函数的功能是设定四个轮子的预期转速,但是转速w有正负,而我这边都是以大小来算的,电机转向就交给L298的两个方向控制线了。故需要判断正负。
(8)低惯量伺服电机空载2ms从0-3000转/分钟 ,不知道PID周期是多少?
这个采样周期我也没去研究具体去多少比较好,惯量小的话应该取采样周期短一些 为好。你可以取几个T 放进去看看效果
(9)楼主,请教2个个问题,你这里头定义了KP,Ti, Td, Ki, Kd,其中Ki,Kd是由Ti/Td/Kp计算得来的,而最开始KP/Ti/Td是手动整定得到的,那么为什么不直接整定KP/KI/Kd呢?第二个问题是你定义的控制周期就是#define T 中的T吗?,他和转速采集周期,PWM周期,需要满足什么关系?谢谢!
第一个问题,整定参数的话,你调整Td Ti 跟你直接调整Kd Ki 没什么大的差别,后者是前者变换来的。我用的是试凑法,先比例 后积分 再微分第二个问题,T是采样周期=采集转速的周期,和PWM信号没什么大的联系。PWM周期是电机决定的,比如我用1K的周期也行,但是噪音和振动方面不太好。
嗯,理解了,我想最理想的PMW周期应该是最后使转速或者温度维持到目标值得时候,占空比维持不变。而最理想的PID控制周期应该是接近PWM周期。
/**********PID参数初始化**********/void PID_Init(void){& & & & sptr-&LastError& & & & = 0;& & & & sptr-&PrevError& & & & = 0;& & & & sptr-&SumError&&= 0;& & & &&& & & & sptr-&kp& & & & & & & & = 3.5;& & & & sptr-&ki& & & & & & & & = 0.15;& & & & sptr-&kd& & & & & & & & = 0;& & & & sptr-&SetValue& & & & = 0.10;& & & &&}
&setcpmpare()是stm32的库函数啊,你学习一下用定时器输出PWM的那个知识点就行了。简单的说setcpmpare(a),a就是PWM信号周期中高电平的量,假如pwm周期用的参数是1000,72分频,那么1000代表的就是1000us了,即pwm周期是1000us,好的。下面我setcpmpare(500),那么就会输出正好50%占空比的波形了。
我也在注意这个,上位机要绘图的话数据还是从下位机来的。本来我想尝试用matlab的串口接受stm32的数据的,发现matlab这块没学好。后来就用示波器的滚动模式显示实时的波形进行观察的。如果要绘图写文章的话,可以把示波器的数据放进u盘,里面会生出excel表格,然后把数据做成数组用plot()函数绘图就行了。总结来说,前期调试和查看波形都是示波器实时看的。
库函数?我在3.5版本的库函数索引里面里没有找到setcpmpare()这函数...不过Lz你解释后我懂了setcpmpare()的意思了。就是设定占空比的吧
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;& && && && && && && && &}楼主,后来我看代码,有一点疑惑。&&period_TIM2& &=&&TIM_GetCapture2(TIM2);& &这条语句中,既然是捕获TIM2 输出的PWM周期,为什么不是用TIM_GetCaputer1() 这个函数,而是用TIM_GetCapture2().....我在库函数的文档中找到,TIM_GetCaputer1() 返回的是 TIMx_CCR1 的值;TIM_GetCapture2() 返回的是 TIMx_CCR2 的值。然后在PWM输入中,PWM周期的数值不是储存在TIMx_CCR1,PWM高电平的值储存在TIMx_CCR2 中吗? &
恩,楼主,搞定了;发现是我弄错了。上次看到你的消息,一直不知道怎么回答,因为这些细节我真心没去研究,代码部分就像是用了库函数一样移植过来的,然后你说的这段代码对着示波器看看没问题就用了你现在解决了吗?&&stm32里面,PWM的输入 和 输出 用的是不用的寄存器。后来看 stm32的手册的定时器里描述的PWM的功能时寄存器的使用情况,然后对比库函数里代码的宏定义,一层一层的把库函数剥开,看到寄存器那,发现是我没有看精细,太粗心了
阅读(...) 评论()}

我要回帖

更多关于 开关电源推挽电路原理 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信