当前位置: 首页 > news >正文

【嵌入式电机控制#17】电流环(四):电流闭环控制

一、电流闭环控制的算法框图

        前面介绍了很多电流相关的代码,内容比较乱,但其实是循序渐进的,这里整理出电流闭环控制所需的所有算法以及对应流程,帮助大家加深印象。

        

        常见电机电流控制系统以上流程调节是不会出现明显问题的。但不代表这个系统设计能有效调节所有电机系统,我这里只给了一个方法论,在大型产品研发过程中,控制算法工程师常会利用自己的控制理论、嵌入式、数学等知识设计新的算法。所以我们需要具体问题具体分析。

        注:过采样处理的依据是香农定理和奈奎斯特采样定理,在第一平均时进行刻意的漏除,在实际值计算时将倍数补偿回来。(类似3D游戏的DLSS)

二、关键环节驱动解析 

        接下来进行关键代码解析,默认硬件层过压过流保护已经生效,驱动层不再处理。

        1. DAC的DMA中断处理函数

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)  
{uint16_t ConvCnt = 0;int32_t ADConv = 0 ; // ADC进入次数初始化(动态窗口样本量),//本次ADC结果初始化HAL_ADC_Stop_DMA(hadc);//停掉DMA,即使丢掉部分数据,但也不影响时序for(ConvCnt = 0; ConvCnt < ADC_BUFFER; ConvCnt++){ADConv += ((int32_t)ADC_ConvValueHex[ConvCnt]);//从DMA寄存器中依次读出数据}ADConv >>= ADC_Base;//进行首次均值,注意刻意漏移2位,也就是漏除2^2AverSum += ADConv;//本次ADC结果累加进动态窗口的数据总和AverCnt++;//动态窗口样本量,注意这个量是动态使用的,没有固定值,使用一次即销毁HAL_ADC_Start_DMA(hadc,(uint32_t*)ADC_ConvValueHex,ADC_BUFFER);//重新开启DMA接收
}

     2. 任意定时器的中断回调

        注意初始化时频率必须比ADC采样频率高,并且最好把优先级设置低于ADC中断,不然ADC还没采集完就一直被定时器中断打断

void HAL_SYSTICK_Callback(void)
{__IO int32_t ADC_Resul= 0;__IO float Volt_Result = 0;__IO float ADC_CurrentValue;// 不用volitile变量其实也可以,如果你用纯寄存器写代码,那还是建议加上吧if((uwTick % 50) == 0)//这里用了个寄存器与HAL库混合写法,意思就是50ms中断一次{if(AverCnt < 0)ADC_Resul  = 0;elseADC_Resul = AverSum/AverCnt ;//注意清除ADC异常值,如果出现负值一定是出错了,如果带进我们的动态偏差里,后果比较严重OffsetCnt_Flag++;//状态机标志位++,进行状态切换if(OffsetCnt_Flag >= 16){//如果大于等于16进入一个处理判断if(OffsetCnt_Flag == 16){//其中如果等于16则取它为动态偏差//这个16是我们不断结合万用表测试获得的,表示采样电路稳定工作前一时刻的采样值,换了硬件后需要重新确定OffSetHex = ADC_Resul;}//取了动态偏差后,给标志位赋32,以严格区分它和未取偏差时的状态OffsetCnt_Flag = 32;//减去偏差值获取优化值ADC_Resul -= OffSetHex;//¼õȥƫ²îÖµ}//换算电流采样电阻两头的电压,在换算电流,注意把过采样处理补偿回去Volt_Result = ( (float)( (float)(ADC_Resul) * VOLT_RESOLUTION) );ADC_CurrentValue = (float)( (Volt_Result / GAIN) / SAMPLING_RES);//这个ADC电流值就是我们真正的反馈信号if(Volt_Result<0)Volt_Result = 0;//动态窗口参数清零AverCnt = 0;AverSum = 0;//如果PID标志位使能则进行PID运算if(start_flag == 1){PWM_Duty = CurPIDCalc( (int32_t)ADC_CurrentValue);//PID获取占空比if(PWM_Duty >= BDCMOTOR_DUTY_FULL)PWM_Duty = BDCMOTOR_DUTY_FULL;//进行PID输出限幅,避免输出错误值if(PWM_Duty <=0)PWM_Duty = 0;//异常值处理__HAL_TIM_SET_COMPARE(&htimx_BDCMOTOR,TIM_CHANNEL_1,PWM_Duty);//PWM输出}#ifdef USE_PRINTF         printf("Volt: %.1f mV -- Curr: %d mA\n",Volt_Result,(int32_t)ADC_CurrentValue);
#else CaptureNumber = (int32_t)ADC_CurrentValue;Transmit_FB(&CaptureNumber);
#endif}
}

         3. 位置PID

        不详细解释了,最好再做个积分限幅

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)  
{uint16_t ConvCnt = 0;int32_t ADConv = 0 ; /* ADC²É¼¯Ì«¿ì,ÐèÒªÏÈÍ£Ö¹ÔÙ´¦ÀíÊý¾Ý */HAL_ADC_Stop_DMA(hadc);/* ȡƽ¾ù */for(ConvCnt = 0; ConvCnt < ADC_BUFFER; ConvCnt++){ADConv += ((int32_t)ADC_ConvValueHex[ConvCnt]);}/* ¼ÆËãÆ½¾ùÖµ,²ÉÑùÊý¾ÝÉèÖÃΪ2µÄÕûÊý±¶,»ñµÃ14bitsADCÖµ*/ADConv >>= ADC_Base;/* ÀÛ¼Ó²ÉÑù½á¹û²¢¼Ç¼²ÉÑù´ÎÊý*/AverSum += ADConv;AverCnt++;HAL_ADC_Start_DMA(hadc,(uint32_t*)ADC_ConvValueHex,ADC_BUFFER);
}

http://www.dtcms.com/a/304796.html

相关文章:

  • 汽车品牌如何用直播“开出去”?从展厅到售后,一站式解决方案
  • 智慧园区系统引领未来:一场科技与生活的完美融合
  • 微信小程序无法构建npm,可能是如下几个原因
  • linux内核报错汇编分析
  • C++学习之继承
  • 【IQA技术专题】纹理相似度图像评价指标DISTS
  • 编写一个markdown文本编辑器工具
  • 7月29号打卡
  • 无需反复登录!当贝AI聚合通义Qwen3-235B等14大模型
  • 大文件的切片上传和断点续传前后端(Vue+node.js)具体实现
  • JetBrains IDE插件开发及发布
  • java导入pdf(携带动态表格,图片,纯java不需要模板)
  • 15K的Go开发岗,坐标北京
  • 第七章 MCP协议
  • Wndows Docker Desktop-Unexpected WSL error错误
  • 报告研读——80页数据资产化实践指南报告-2024【附全文阅读】
  • 天铭科技×蓝卓 | “1+2+N”打造AI驱动的汽车零部件行业智能工厂
  • 为什么全景渲染更耗时?关键因素解析
  • 3D游戏引擎的“眼睛“:相机系统深度揭秘与技术实现
  • 【ARM】FPU,VFP,ASE,NEON,SVE...是什么意思?
  • Synopsys:消息管理
  • 2025年1中科院1区顶刊SCI-投影迭代优化算法Projection Iterative Methods-附完整Matlab免费代码
  • Vivado常用IP
  • GaussDB 数据库架构师修炼(十) 性能诊断常用视图
  • Rust基础-part8-模式匹配、常见集合
  • 嵌入式开发问题:warning: #177-D: variable “key“ was declared but never referenced
  • 2025年Solar应急响应公益月赛-7月笔记ing
  • Generative AI in Game Development
  • Class24AlexNet
  • STM32——HAL库