TIME TABLE

  • 11.1 学习Git并学习完毕
  • 11.2 使用Git并开始学习SolidWorks,且学习完毕,开始看的6.3 ~ 6.8 / 9.1 ~ 9.5
  • 11.3 6.3~6.8学习完毕,开始着手编写代码
  • 11.4 9.1 ~ 9.5学习完毕,开始着手编写代码
  • 11.5 调试代码,调试不成功
  • 11.6 调试成功

难点总结

1 初始化不到位

一定要搞清楚的是,一旦你在GPIO口输出或者输入,就一定要初始化!一定要初始化!我不知道被这个浪费了多少时间,每次以为初始化好了,结果都有疏漏!所以我才会写这么多封装好的初始化函数。这样不仅方便,在测试后也能防止以后初始化再出错。

	//控制电机方向的口
	AutoInitGPIO(GPIOB,GPIO_Mode_Out_PP,GPIO_Pin_12,GPIO_Speed_50MHz);
	AutoInitGPIO(GPIOB,GPIO_Mode_Out_PP,GPIO_Pin_13,GPIO_Speed_50MHz);
	AutoInitGPIO(GPIOB,GPIO_Mode_Out_PP,GPIO_Pin_14,GPIO_Speed_50MHz);
	AutoInitGPIO(GPIOB,GPIO_Mode_Out_PP,GPIO_Pin_15,GPIO_Speed_50MHz);
2 中断开启与中断配置

另一个消耗了我很长时间的是中断的开启和配置,OC是可以和定时中断同时存在的! 然后,ITConfig一定要记得打开,不然你以为IT是什么?是Interrupt! 中断优先级的配置更是逆天,这里就提一嘴

3 代码逻辑性问题

说实话,我从一开始就没太搞清楚代码的逻辑,导致编的时候一直处于一种混乱的状态,建议以后先想清楚了要先干什么,达到什么样的目的,再编写下一部分代码

4 PID不清楚

这个等下我专门开一个PID来讲把,我对其有一些独到的理解

float PID_Control(MotorTypeDef * Motor , PIDTypeDef * PID){
	
	PID->error = Motor->Target_Speed - Motor->Cur_Speed;
	
	// 比例,相当于往哪里动,动多少,是最主要的推动力
	float proportional_score = PID->KP * PID->error;
    
	// 积分,把最后一点偏差去除掉
	PID->I += PID->error;
	// 积分限幅
	if(PID->I > PID->I_Lim) PID->I = PID->I_Lim;
	if(PID->I < -PID->I_Lim) PID->I = -PID->I_Lim;
	float integral_score = PID->KI * PID->I;
	
	// 微分,看看现在多块,好刹车
	float derivative_score = PID->KD * (PID->error - PID->prev_error);
	
	// 总输出
	float output = proportional_score + integral_score + derivative_score;
		
	// 输出限幅
	if(output > PID->Output_Lim) output = PID->Output_Lim;
	if(output < -PID->Output_Lim) output = -PID->Output_Lim;
	
	PID->prev_error = PID->error;
	
    return output;
}
5 单位量纲问题

这个是我一直忽略,也是卡我时间卡的最久的。我一直没有意识到SetSpeed函数里填入的实际上是CCR的值,他是一个无向量纲,而我们计算出来的转速实际上是pulse / ms的单位,这两个根本对不上!所以为了解决这个问题,我们需要把速度转化为CCR,也就是除以满转的pulse / ms,得到一个比例,最后乘以Period就可以了

void Cal_Current_Speed(MotorTypeDef * Motor , TIM_TypeDef * TIMx){
		
	Motor->Prev_Count = Motor->Cur_Count;
	Motor->Cur_Count = TIM_GetCounter(TIMx);
    
	// 计算脉冲差值(处理溢出)
	int32_t pulse_diff = (int32_t)Motor->Cur_Count - (int32_t)Motor->Prev_Count;
	if(pulse_diff > 32767) pulse_diff -= 65536;
	else if(pulse_diff < -32768) pulse_diff += 65536;
        
	// 转换为实际转速(转/秒)
	// 10ms内的脉冲数 → 1秒内的脉冲数 → 转数
	Motor->Cur_Speed = (( (float)pulse_diff * 100 / PULSES_PER_REV ) / MAX_RPS) * 1000; // 这里得到的就应该是和CCR量纲一样的东西了
}
6 VOFA上位机问题的解决

这个还好,我注意到一直启用的是RawInput模式,很自然想到的是FireWater应该可以自动读取数据,本来我还说会不会需要自己写一个接收包的程序

7 没有开启降压模块电源

我说为什么我电机不转,原来是电源没开啊😓 由于纯理论派的学习,我把lsh的面包板拿过来之后,很长一段时间都在研究电机为什么没有转,结果是因为降压电源模块没有开!我都不知道要开!这耗费了我两个多小时无意义的纠错

我是傻逼