本帖最后由 子曰好人 于 2018-9-5 08:55 编辑
继续做实验,任务3和旋钮控制转速。 首先来看看任务3的要求: 这个可通过代码实现也可以通过上位机实现,已经有坛友做过这样的事情了。通过上位机做就是快速拨弄圆盘,这样系统不能在短时间内反转,造成观测器不能收敛,触发速度反馈错误报警,其实我个人觉得这里也是有过流报警存在的,这就看系统优先响应哪一个报警了。 我这里通过代码来实现task3。 任务3代码: - void task_3(void)
- {
- MC_ProgramSpeedRampMotor1(-3000/6,1000); //设置-3000rpm的转速,在一秒之内达到
- MC_StartMotor1(); //启动电机
- HAL_Delay(500); //运行500ms
- while(RUN != MC_GetSTMStateMotor1()); //等待电机处于运行状态,可有可无
- MC_ProgramSpeedRampMotor1(3000/6,1000); //切换到3000rpm转速
- MC_StartMotor1(); //启动电机
- while(MC_SPEED_FDBK != STM_GetFaultState(&STM[M1])); //等待错误触发
- HAL_Delay(1000); //延时一秒,方便可以在上位机上看见错误是否发生
- MC_AcknowledgeFaultMotor1(); //清除错误
- HAL_Delay(100); //延时0.1秒
- MC_ProgramSpeedRampMotor1(MC_GetLastRampFinalSpeedMotor1(),1000); //重新设置上一次速度值
- MC_StartMotor1(); //启动电机
- HAL_Delay(5000); //运行5秒
- MC_StopMotor1(); //停机
- HAL_GPIO_WritePin(LED11_GPIO_Port,LED11_Pin,GPIO_PIN_RESET); //拉低LED引脚,表示任务结束
- }
复制代码主函数代码: - /* Infinite loop */
- /* USER CODE BEGIN WHILE */
- while (1)
- {
-
- if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))
- {
- task_3();
- }
- else
- {
- MC_StopMotor1();
- }
- /* USER CODE END WHILE */
复制代码实验现象:
通过速度变化趋势可以看到任务成功实现了,我对比了PPT的预期结果图,有一些差距。当速度设置为3000rpm时,speed reference并没有跟随代码变为3000。另外,我做了延迟清除错误信息,所以在图中可以看到一截零速状态。
好了,任务3完成。
--------------------------------------------------------- 现在分享一个开放性实验,旋钮控制转速,我把这个任务定为任务4吧,用旋钮来控制电机转速我觉得才是真正的一个电机控制系统。 由于SDK中并没有考虑旋钮ADC的初始化,所以如果要使用旋钮电位器首先要通过cubemx对ADC进行初始化,在我的第二篇帖子中已经讲过关于套件的硬件资源,也知道了旋钮电位器连接的是PB1引脚。 创建全局变量: - int32_t Speed_Adc = 0;
- int32_t Speed_ref = 0;
- PWMC_Handle_t * MC_SPEED_REF;
复制代码任务4代码: - void task_4(void)
- {
- Speed_Adc = R3_1_F30X_ExecRegularConv(MC_SPEED_REF,ADC_CHANNEL_12);
- Speed_ref = (15500*Speed_Adc)>>16;
- if(Speed_ref > 0)
- {
- MC_ProgramSpeedRampMotor1((Speed_ref+1500)/6,1000);
- MC_StartMotor1();
- }
- else
- {
- MC_StopMotor1();
- }
- HAL_Delay(100);
- }
复制代码 主函数代码:
- /* Initialize interrupts */
- MX_NVIC_Init();
- /* USER CODE BEGIN 2 */
- MC_SPEED_REF = &PWM_Handle_M1._Super;
- /* USER CODE END 2 */
- /* Infinite loop */
- /* USER CODE BEGIN WHILE */
- while (1)
- {
- if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))
- {
- task_4();
- }
- else
- {
- MC_ProgramSpeedRampMotor1(0,0);
- MC_StopMotor1();
- }
- /* USER CODE END WHILE */
- /* USER CODE BEGIN 3 */
- }
- /* USER CODE END 3 */
复制代码在这里稍微解释一下代码: Speed_Adc是存储ADC采样值的变量,Speed_ref变量通过ADC采样值转化为速度设定值,MC_SPEED_REF是一个指针变量,用于获取ADC初始化设置,R3_1_F30X_ExecRegularConv这个函数在r3_1_f30x_pwm_curr_fdbk,c这个文件中,用于处理规则ADC采样。速度换算这里可以没什么说的。速度设定的时候加1500偏移是有原因的,当设定速度过低的时候电机系统根本不能正常启动,这是我尝试设置的时候所能达到的最低启动速度。
实验现象: 从实验结果看来,这份代码默认速度PID能很好的跟踪给定转速。 我发现一个问题,代码里面在电机运行结束之后有些变量好像没有清零,这个问题留到后面在研究吧。
本帖两个任务分享就到这里,欢迎大家留言讨论。
|