学长,我看了您的FOC一步步代码,请问从STMF4移植到STMH7需要注意什么问题呢?我按您说的移植了开环电机不转。
配置能够产生6路pwm波的定时器,改变定时器的占空比即可控制电机转速或转矩。
1.GPIO初始化配置
需要一个能够产生6路PWM波的高级定时器,定时器1或定时器8,对应6个GPIO口,同时需要一个刹车GPIO,共计需要7个GPIO。配置为复用推挽模式。
代码如下:
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = RHEOSTAT_TIM1_GPIO_PIN1 | RHEOSTAT_TIM1_GPIO_PIN2 | RHEOSTAT_TIM1_GPIO_PIN3 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(RHEOSTAT_TIM1_GPIO_PORT, &GPIO_InitStructure);
//TIM1N
GPIO_InitStructure.GPIO_Pin = RHEOSTAT_TIM1N_GPIO_PIN1 | RHEOSTAT_TIM1N_GPIO_PIN2 | RHEOSTAT_TIM1N_GPIO_PIN3;
GPIO_Init(RHEOSTAT_TIM1N_GPIO_PORT, &GPIO_InitStructure);
2.定时器的初始化配置
定时器的初始化代码如下:
//定时器初始化
TIM_DeInit(TIM1);
TIM_TimeBaseStructInit(&TIM1_TimeBaseStructure);
TIM1_TimeBaseStructure.TIM_Prescaler = PWM_PRSC; //1
TIM1_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1;
TIM1_TimeBaseStructure.TIM_Period = PWM_PERIOD; //PWM_PERIOD ARR 顶点值 2500
TIM1_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV2; //和死区时间计算有关
TIM1_TimeBaseStructure.TIM_RepetitionCounter = REP_RATE; //溢出2次触发中断
TIM_TimeBaseInit(TIM1, &TIM1_TimeBaseStructure);
3.输出捕获模式的配置
定时器的四个通道都配置为中央对齐模式
代码如下:
//配置TIM的PWM输出
TIM_OCStructInit(&TIM1_OCInitStructure);
TIM1_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //PWM1 向上计数时cnt<crr有效
TIM1_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM1_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM1_OCInitStructure.TIM_Pulse = 0x505; //crr
TIM1_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //通道低电平有效
TIM1_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; //互补通道低电平有效
TIM1_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; //设置输出空闲状态
TIM1_OCInitStructure.TIM_OCNIdleState = LOW_SIDE_POLARITY; //reset
TIM_OC1Init(TIM1, &TIM1_OCInitStructure); //配置通道1
TIM_OC2Init(TIM1, &TIM1_OCInitStructure); //配置通道2
TIM_OC3Init(TIM1, &TIM1_OCInitStructure); //配置通道3
GPIO_StructInit(&GPIO_InitStructure);
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);
//TIM1通道4的PWM配置
TIM_OCStructInit(&TIM1_OCInitStructure);
TIM1_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM1_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //使能主通道
TIM1_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
TIM1_OCInitStructure.TIM_Pulse = PWM_PERIOD-1; // // 在PWM波的正中间采样
TIM1_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //主通道高电平有效
TIM1_OCInitStructure.TIM_OCNPolarity =TIM_OCNPolarity_Low; //互补通道低电平有效 没有用 互补通道关闭
TIM1_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; //主通道输出空闲状态
TIM1_OCInitStructure.TIM_OCNIdleState = LOW_SIDE_POLARITY; //互补通道输出空闲状态
TIM_OC4Init(TIM1, &TIM1_OCInitStructure);
TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);
4.刹车和死区配置
刹车可以通俗的理解为停止产生PWM波,当改变刹车位的电平时,会启动或停止PWM的产生。
死区是为了保证mos开关电路不在同一时刻导通,烧毁电路。
代码如下:
//刹车和死区配置
TIM1_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; //当定时器不工作时,一旦CCxE=1或CCxNE = 1(即主通道捕获比较或互补捕获比较通道使能),首次开启OC/OCN并输出无效电平,然后置OC/OCN使能输出信号=1
TIM1_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; //当定时器不工作时,一旦主通道或互补通道使能,OC/OCN首先输出其空闲电平,然后OC/OCN使能输出信号=1
TIM1_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; //锁定级别1,不能写入TIMx_BDTR寄存器的DTG、BKE、BKP、AOE、和TIMx_CR2寄存器的OISx/OISxN位
TIM1_BDTRInitStructure.TIM_DeadTime = DEADTIME; //死区 4
TIM1_BDTRInitStructure.TIM_Break = TIM_Break_Disable; //刹车功能使能
TIM1_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low; //刹车输入低电平有效
TIM1_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable; //关闭自动输出 只能由软件置1
TIM_BDTRConfig(TIM1, &TIM1_BDTRInitStructure);
//设置更新事件为TIM1的TRGO 设置ADC触发为TIM1的TRGO时,即使用TIM1的更新作为触发
TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update); //选择定时器1的更新事件被选为触发输入(TRGO) 定时器1位主模式
TIM_ClearITPendingBit(TIM1, TIM_IT_Break); //清除刹车中断标记位
TIM_ITConfig(TIM1, TIM_IT_Break,ENABLE); //使能刹车中断
TIM_Cmd(TIM1, ENABLE); //使能定时器1
// Resynch to have the Update evend during Undeflow
TIM_GenerateEvent(TIM1, TIM_EventSource_Update); //重新初始化计数器,并产生一个更新事件,注意预分频器的计数器也被清0(但是预分频系数不变!若在中心对称模式下
//或向上计数则计数器被清0,若向下计数则取TIMx_ARR的值。
//Clear Update Flag
TIM_ClearFlag(TIM1, TIM_FLAG_Update); //清除中断标志位
TIM_ITConfig(TIM1, TIM_IT_Update, DISABLE); //关闭更新中断
TIM_ITConfig(TIM1, TIM_IT_CC4,DISABLE); //关闭捕获/比较中断