HAL STM32G4 +ADC手动触发采集+各种滤波算法实现
✨本篇内容也是继
欧拉电子
相关无刷电机驱动控制学习的相关基础内容。仅作为个人笔记记录使用。
- 📍感谢网友提供的相关内容《基于STM32的ADC采样及各式滤波实现》文中的源码个人分享:
链接:https://pan.baidu.com/s/1CnhBREQ2-iRqjImH-ZAaGQ?pwd=9d37
提取码:9d37
- 🔖VOFA+波形显示ADC数据可以参考上面的文章介绍。
📙ADC采用各种滤波算法实现
- 🔖来源于上面参考内容源码。
- 🌿算术均值滤波算法
int averageFilter(int N)
{
int sum = 0;
short i;
for(i = 0; i < N; ++i)
{
sum += HAL_ADC_GetValue(&hadc1);
}
return sum/N;
}
- 🌿均值滤波
uint32_t Mean_Value_Filter(uint16_t *value, uint32_t size) // 均值滤波
{
uint32_t sum = 0;
uint16_t max = 0;
uint16_t min = 0xffff;
int i;
for (i = 0; i < size; i++) {
sum += value[i];
if (value[i] > max) {
max = value[i];
}
if (value[i] < min) {
min = value[i];
}
}
sum -= max + min;
sum = sum / (size - 2);
// if(sum>1)sum+=4; 后期校准
return sum;
}
- 🌿中值滤波算法
int middleValueFilter(int N)
{
int value_buf[N];
int i,j,k,temp;
for( i = 0; i < N; ++i)
{
value_buf[i] = HAL_ADC_GetValue(&hadc1);
}
for(j = 0 ; j < N-1; ++j)
{
for(k = 0; k < N-j-1; ++k)
{
//从小到大排序,冒泡算法
if(value_buf[k] > value_buf[k+1])
{
temp = value_buf[k];
value_buf[k] = value_buf[k+1];
value_buf[k+1] = temp;
}
}
}
return value_buf[(N-1)/2];
}
- 🌿一阶互补滤波
int firstOrderFilter(int newValue, int oldValue, float a)
{
return a * newValue + (1-a) * oldValue;
}
- 🌿平滑均值滤波
#define N 10
int value_buf[N];
int sum=0;
int curNum=0;
int moveAverageFilter()
{
if(curNum < N)
{
value_buf[curNum] = HAL_ADC_GetValue(&hadc1);
sum += value_buf[curNum];
curNum++;
return sum/curNum;
}
else
{
sum -= sum/N;
sum += HAL_ADC_GetValue(&hadc1);
return sum/N;
}
}
- 🌿限幅平均滤波
//限幅平均滤波
#define A 50
#define M 12
int data[M];
int First_flag=0;
int LAverageFilter()
{
int i;
int temp,sum,flag=0;
data[0]=HAL_ADC_GetValue(&hadc1);
for(i=1;i<M;i++)
{
temp=HAL_ADC_GetValue(&hadc1);
if((temp-data[i-1])>A||((data[i-1]-temp)>A))
{
i--;flag++;
}
else
{
data[i]=temp;
}
}
for(i=0;i<M;i++)
{
sum+=data[i];
}
return sum/M;
}
- 🌿卡尔曼滤波
int KalmanFilter(int inData)
{
static float prevData = 0; //先前数值
static float p = 10, q = 0.001, r = 0.001, kGain = 0; // q控制误差 r控制响应速度
p = p + q;
kGain = p / ( p + r ); //计算卡尔曼增益
inData = prevData + ( kGain * ( inData - prevData ) ); //计算本次滤波估计值
p = ( 1 - kGain ) * p; //更新测量方差
prevData = inData;
return inData; //返回滤波值
}
📗测试例程
-
🔖分别使能ADC1的通道11(PB11),和ADC2通道0(PA0)进行adc采样。
-
🌿转换周期和精度配置,触发方式
-
📝main函数
int main(void)
{
/* USER CODE BEGIN 1 */
float temp[2];
uint8_t TempData[12]={0,0,0,0,0,0,0,0,0,0,0x80,0x7F} ;//vofa float数据流显示格式
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_USART1_UART_Init();
MX_ADC1_Init();
MX_ADC2_Init();
/* USER CODE BEGIN 2 */
//HAL_UART_Receive_IT(&huart3,(uint8_t *)&aRxBuffer,1);
HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED);//ADC自校验
HAL_ADCEx_Calibration_Start(&hadc2, ADC_SINGLE_ENDED);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while(1) {
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_ADC_Start(&hadc1);
HAL_ADC_Start(&hadc2);
//Vstep = Vref(3.3) / 4095=8.056mV
temp[0]=HAL_ADC_GetValue(&hadc1)*8.056f;//AIN11->PB12
temp[1]=HAL_ADC_GetValue(&hadc2)*8.056f;//*0.02094726f; //ADC2.AIN1->PA0
memcpy(TempData,(uint8_t*)temp,sizeof(temp));
HAL_UART_Transmit_DMA(&huart1,(uint8_t *)TempData,12);
HAL_Delay(100);
}
/* USER CODE END 3 */
}
- 📚程序源码:
- 🔖采用的STM32G431
链接:https://pan.baidu.com/s/1iIzQpNHDAG-XTEMcmXUIlA?pwd=7gs0
提取码:7gs0