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

【嵌入式电机控制#16】电流环(三):过采样提高采集精度看门狗监测总线电压

一、香农采样定律

        为不失真的复现信号的变化,采样频率至少应大于等于连续信号最高频率分量的二倍

        采样定律只能确定采样周期的上限(采样频率的下限),实际采样周期的选择受多方面影响。

        一般情况下:

        1. 对于响应快波动大、易受干扰(压力、流量)的过程,应该选较高的采样频率

        2. 对于过程响应慢,滞后大(温度、化学成分等)选取较低采样频率

        当过程的纯滞后时间较长时,选取采样周期为纯滞后时间的1/4到1/8

        

        STM32的ADC分辨率为12bit,假设PWM脉冲频率为20KHz,则理论上讲采样频率达到40Khz就能正确采集波形。

二、代码改进

        注意看写的注释,不然干看代码是看不懂的

        (1)adc.h修改配置     

                       VoltageResolution = ADC(Hex) * 3.3 / 2^n *1000 mV

        根据香农采样定律,采样频率选取的最小值应该为PWM的两倍

        再由过采样理论, 实际采样率 > 两倍PWM频率 *  4^2 

        所以采样频率能够拉到14bit,公式中应该改为除以2^14也就是16384

#define VOLT_RESOLUTION     ((float)((VOLT_REF/(float)(16384))*(float)1000))
#define VOLTBUS_RESOLUTION  ((float)( 3.3f/(float)4096) * (42.4f+2.0f) / 2.0f)

       (2)adc.c 采样DMA                

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)  
{uint16_t ConvCnt = 0;int32_t ADConv = 0 ; 
//定义采样次数计数器,定义采样结果寄存器(注意,这次移到中断里成动态量了)
//这里注意防止采样次数AverCnt溢出HAL_ADC_Stop_DMA(hadc);
//先停止DMA,目的是不干扰时序SetChannelAsRank1(hadc,ADC_VOLT_CHANNEL);
//设置电压采样优先,为电压提供专属的数据采集时机,为电流保留了数据处理的机会
//此时DMA只采集电压,电流DMA被维护HAL_ADC_Start(hadc);
//ADC重新开启,此时正式开始采集电压,与此同时处理电流for(ConvCnt = 0; ConvCnt < (ADC_BUFFER ); ConvCnt++){ADConv += ((int32_t)ADC_ConvValueHex[ConvCnt]);}
//进行电流采集量累加,一共1024次ADConv >>= ADC_Base;
//进行取平均,注意这里只移动了8位,也就是256,故意少除以2^2,为12bit->14bit的过采样处理AverSum += ADConv;
//进行采样结果累加AverCnt++;
//采样次数自增 HAL_ADC_Stop(hadc);
//停止ADC,并把ADC权限留给电流,电压后续在窗口看门狗中进行总线电压监测SetChannelAsRank1(hadc,ADC_CURRENT_CHANNEL);HAL_ADC_Start_DMA(hadc,(uint32_t*)ADC_ConvValueHex,ADC_BUFFER);
//这句话不仅有重新开始DMA的含义,也有重启ADC的意思
}

        (3) 定时器中断采样数据进一步处理

void HAL_SYSTICK_Callback(void)
{__IO int32_t ADC_Resul= 0;__IO float Volt_Result = 0;__IO float ADC_CurrentValue;//定义ADC结果寄存器,电流采样电压结果寄存器,最终实际电流值寄存器if((uwTick % 50) == 0){ADC_Resul = AverSum/AverCnt ;
//每一次中断,进行动态窗口滤波,窗口长度根据此前DMA次数调整OffsetCnt_Flag++;if(OffsetCnt_Flag >= 16){//经过实际测试,17次进入定时器中断时,电流波形才稳定//那么我们就把前一次的值当作零漂if(OffsetCnt_Flag == 16){OffSetHex = ADC_Resul;}//标准的状态机写法,以固定的32代表电流采样进入正常状态,每次进来都会被赋为32//那么我们如果需要在控制日志中导出电流数据,就可以在这个大判断后print它的flagOffsetCnt_Flag = 32;//adc结果减去偏差才是真正的采样值ADC_Resul -= OffSetHex;}
//计算进入单片机的电压模拟量Volt_Result = ( (float)( (float)(ADC_Resul) * VOLT_RESOLUTION) );
//计算电机端实际的电流ADC_CurrentValue = (float)( (Volt_Result / GAIN) / SAMPLING_RES);
//对动态窗口的计数值、累加值清零AverCnt = 0;AverSum = 0;printf("Volt: %.1f mV -- Curr: %d mA\n",Volt_Result,(int32_t(ADC_CurrentValue+10));}
}

          (4) 窗口看门狗实现总线电压监测

        这段代码实现了一个逻辑:如果电压异常被WD连续检测出六次,则强制关闭电机,然后关闭定时器PWM输出。

void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc)
{//给一个计数值i,并定义为静态量//注意这种用法,下一次触发看门狗时,i的值还保留,效果类似全局静态static uint8_t i = 0;i++;//这里直接自增了 ,说明一切从i==1开始if(ADC_VoltBus > VOLT_LIMIT_MIN  && ADC_VoltBus < VOLT_LIMIT_MAX)//如果总线电压大于最小供电,并小于最大电压限制i = 0 ;else if(i>=6){SHUTDOWN_MOTOR();//禁用驱动HAL_TIM_PWM_Stop(&htimx_BDCMOTOR,TIM_CHANNEL_1);HAL_TIMEx_PWMN_Stop(&htimx_BDCMOTOR,TIM_CHANNEL_1);//关闭输出PWM_Duty = 0;//这里可以直接做PID清理
//    ADC_VoltBus = (float)ADC_VoltBus * VOLTBUS_RESOLUTION;//如果需要在控制日志中查看危险电压到底是多少,可以算一下ADCprintf("Bus Voltage is out of range!!\n");//汇报控制日志printf("Please Reset the Target!\n");//死循环,等待用户resetwhile(1);}
}

(5)以上三个中断的优先级配置建议

        为了安全起见,看门狗的中断优先级必须是三个中最高的。这样单片机才能在安全环境下稳定工作。

        其次,ADC采样速率要求较快,并且是定时器数据处理的基础,所以我们安排次高优先级。

        最后,当ADC数据处理完毕后,再将数据送给数据处理中断,所以它安排最低。

        总结:

                最高:窗口看门狗中断

                适中:ADC的DMA中断

                最低:数据处理的定时器中断

http://www.lryc.cn/news/593498.html

相关文章:

  • C++类和对象(一)基础内容讲解
  • 【项目分享】动手做一个TypeC转TTL模块(附带原理图)
  • Spring MVC @RequestParam注解全解析
  • 数据库第四次作业
  • 【C++】初识C++(2)
  • 完美解决 Ubuntu 中自定义启动器图标重复的问题(以 MATLAB 为例)
  • nginx.conf模版
  • 基于GEE与哨兵2号的土地覆盖分类方法及实现
  • python网络爬虫之selenium库(二)
  • uview-ui使用u-row+u-avatar居中布局
  • uview-ui使用u-icon文字图标展示
  • react+antd 可拖拽模态框组件
  • Python之--元组
  • RabbitMQ01——基础概念、docker配置rabbitmq、内部执行流程、五种消息类型、测试第一种消息类型
  • Java学习--------消息队列的重复消费、消失与顺序性的深度解析​
  • I/O 多路复用select,poll
  • Java 中的继承与多态
  • 5.组合模式
  • 3.5软件开发活动[2-系统设计]面向对象设计-UML统一开发过程
  • [故障诊断方向]SNNs:针对小样本轴承故障诊断的孪生神经网络模型
  • 在Vscode中使用Kimi K2模型:实践指南,三分钟生成个小游戏
  • 练习三:熟知前端知识
  • 目标检测中的标签分配算法总结
  • MinIO深度解析:从核心特性到Spring Boot实战集成
  • Vue的路由模式的区别和原理
  • 《Qt5串口开发》搭建跨平台通信系统
  • VSCode用Python操作MySQL:环境配置与代码验证
  • 操作系统-分布式同步
  • 实验室危险品智能管控:行为识别算法降低爆炸风险
  • Mybatis学习之简介(一)