|
- /**
- * 函数功能: 主函数.
- * 输入参数: 无
- * 返 回 值: 无
- * 说 明: 无
- */
- int main(void)
- {
- /* 复位所有外设,初始化Flash接口和系统滴答定时器 */
- HAL_Init();
- /* 配置系统时钟 */
- SystemClock_Config();
- /* 配置GPIO作为按键使用 */
- KEY_GPIO_Init();
- /* 配置串口输出 */
- USARTx_Init();
- /* 无限循环 */
- while (1)
- {
- if(KEY1_StateRead() == KEY_DOWN)
- {
- /* 计算S型加减速曲线的加速段速度值*/
- CalcSpeed(0,10,4); // 从0加速到10r/min,加速时间是4s
- }
- }
- }
- /**
- * 函数功能:速度表计算函数
- * 输入参数:V0 初速度,单位:转/min
- * Vt 末速度,单位:转/min
- * Time 加速时间 单位: s
- * 返 回 值:无
- * 说 明: 根据速度曲线和加速时间,将数据密集化,即计算每一步的速度值
- */
- void CalcSpeed(int Vo, int Vt, float Time)
- {
- int32_t i = 0;
-
- int32_t Vm =0; // 中间点速度
- float Jerk = 0; // 加加速度
- float Tn = 0; // 时间间隔
- float DeltaV = 0; // 速度的增量dv
- float TimeDel = 0;
- /* 这里采用的数学模型是匀变速直线运动
- * 加速段的曲线有两部分组成,第一是加速度递增的加加速段,
- * 第二是加速度递减的减加速段,两段曲线可以视为关于中心对称(中心是中点速度).这两段曲线所用时间相等
- * 所以中点速度 Vm = (Vt + Vo)/2;
- * 加加速段:
- * 加加速段的加速度曲线是一条过原点的递增的直线,对加速度积分得到的就是速度的增加量
- * 所以有:Vm - Vo = 1/2 * Jerk * t^2,得到加加速度Jerk.
- * 最后得到位移方程 S = 1/6 Jerk * t^3
- * :分析过程请结合工程文件夹下得曲线图理解.
- * 由于S型曲线是V-t曲线,所以这里对时间进行等分,然后根据每一份的时间计算出速度表
- */
- Speed.Vo = ROUNDPS_2_STEPPS(Vo); // 起速:Step/s
- Speed.Vt = ROUNDPS_2_STEPPS(Vt); // 末速:Step/s
- Time = ACCEL_TIME(Time); // 得到加加速段的时间
- Vm = MIDDLEVELOCITY( Speed.Vo , Speed.Vt ); // 计算中点速度
- Jerk = ACCELL_INCREASE( Speed.Vo, Vm, Time ); // 根据中点速度计算加加速度
- Speed.AcceleratingStep = (int32_t)ACCEL_DISPLACEMENT(Jerk,Time);// 加加速需要的步数
-
- /* 申请内存空间存放速度表 */
- Speed.AcceleratingStep = abs(Speed.AcceleratingStep ); // 减速计算的时候防止出现负数
- if( Speed.AcceleratingStep % 2 != 0) // 由于浮点型数据转换成整形数据带来了误差,所以这里加1
- Speed.AcceleratingStep += 1;
- Speed.AccelStep = Speed.AcceleratingStep * 2; // 加速段的步数
- Speed.VelocityTab = (float*)(malloc( Speed.AccelStep * sizeof(float) + 1 ));//申请内存
- if(Speed.VelocityTab == NULL)
- {
- printf("内存不足!请修改曲线参数!\n");
- return ;
- }
-
- /* 目标的速度曲线是对时间的方程,所以这里对时间等分成Speed.S份,根据时间,计算出对应的速度 */
- TimeDel = Time / Speed.AcceleratingStep;
- for(i = 0; i <= Speed.AcceleratingStep; i++)
- {
- Tn = i * TimeDel; // 计算第n个时刻t
- DeltaV = 0.5 * Jerk * pow(Tn,2); // dv = 1/2 * Jerk * t^2;
- Speed.VelocityTab[i] = Speed.Vo + DeltaV; // 得到每一时刻对应的速度 // 加加速过程与减加速是中心对称,可以直接求出后半段速度
- Speed.VelocityTab [ Speed.AccelStep - i] = Speed.Vt - DeltaV ; // 减加速过程对称点的速度
- }
-
- /* 串口打印输出速度表 */
- for(i = 0; i <= Speed.AccelStep ; i++)
- {
- printf("VelocityTab[%d] = %.3f\n",i,Speed.VelocityTab[i]);
- }
- free((void*)Speed.VelocityTab);
- Speed.VelocityTab = NULL;
- }
- /******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/
复制代码
|
|