第二次积分赛所用函数汇总
外部GPIO_EXIT中断回调函数
//实际并没有派上用场
/*
* 外部比较器引起的中断回调,打开adc采样
*
* cyclenum为指定的需要采集的周期个数,利用cont将每次adc采样的结果存放在一个adcstastic的二维数组中
*
* adc_finish是用来判断全部的adc周期采集完成的标志符号
*
* adc是用来判断单次adc采集是否完成的标志符号
* */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == cycle_find_Pin)
{
if (adc_finish == false)
{
HAL_TIM_Base_Stop(&htim1);
HAL_ADC_Stop_DMA(&hadc1);
adc_single = true;
// HAL_NVIC_DisableIRQ(6);
}
}
}
该函数最后注释部分,是NVIC的终止函数,只求进中断一次
模拟看门狗中断回调函数
void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc)
ADC的相关函数
滤波函数
平均值滤波
void adc_filting(uint16_t a[][200], uint16_t b[],uint32_t i);
/*
* 函数作用:将传入的数组进行滤波:改版滑动滤波器(平均值)
*
* 函数参数:传入的需要进行滤波的数组首地址,传出的滤波操作完毕的接收数组首地址,传入二维数组的维度
*
* 函数返回值:空
* */
void adc_filting(uint16_t adcstas[][200],uint16_t adcDone[200],uint32_t cyclenum)
{
for (int j = 0; j < stasticnum; j++)
{
uint16_t num=0;
for (int i = 0; i < cyclenum-1; i++)
{
if (adcstas[i][j]==0&&adcstas[i][j+1]==0&&adcstas[i][j+2]==0&&adcstas[i][j+3]==0&&adcstas[0][j]!=0)
{
adcstas[i][j] = adcstas[0][j];
}
num += adcstas[i][j];
}
adcDone[j] = 1.0*num/(cyclenum-1);
}
}
中位值滤波
void middleValueFilter(uint32_t n,uint16_t a[200],uint32_t b);
/**
* @brief 函数作用:中位值滤波 连续采样N次(N取奇数)把N次采样值按大小排列取中间值为本次有效值
*
* @note 函数参数:传入采样中位值数据,待处理数组,数组实际需要个数
*
* @param N 采样的中位值数据
* @param adcDone 待处理数组
* @param st 数组实际需要个数
* */
void middleValueFilter(uint32_t N,uint16_t adcDone[FFT_LENGTH],uint32_t st)
{
st=stasticnum;
N = 3;
uint16_t value_buffer[4] = {0};
int i, j, k, temp;
for (int m = 0; m < st-3; m++)
{
for (int l = 0; l < N; ++l)
{
value_buffer[l] = adcDone[m+l];
}
for (j = 0; j < N - 1; ++j)
{
for (k = 0; k < N - j - 1; ++k)
{
//从小到大排序,冒泡法排序
if (value_buffer[k] > value_buffer[k + 1])
{
temp = value_buffer[k];
value_buffer[k] = value_buffer[k + 1];
value_buffer[k + 1] = temp;
}
}
}
adcDone[m]=value_buffer[(N-1)/2];
}
adcDone[st-1] = adcDone[0];
}
数组赋值函数
void adc_get_value(uint16_t a[200],uint16_t b[200],uint32_t c);
/**
* @brief 将一个数组的数据传入到另一个数组
*
* @param adcne 传入数据的数组
*
* @param adcdon 传出数据的数组
*
* @param stas 需要传入的长度
*
* */
void adc_get_value(uint16_t adcne[1024],uint16_t adcdon[1024],uint32_t stas)
{
for (int i = 0; i < stas; i++) {
adcdon[i] = adcne[i];
}
adcdon[0] = (adcdon[stas-1]+adcdon[0])/2;
}
FFT相关函数
arm_cfft_radix4_instance_f32 scfft;//某结构体存放scfft这个结构体变量
void fft_over(float a[],float b[]);//运行fft
/*
* 函数作用:运行fft
*
* 函数参数:传入fft装载好的数组,传出fft运行后的数组
*
* 返回值:空
* */
void fft_over(float ff_in[],float ff_out[])
{
arm_cfft_radix4_init_f32(&scfft, FFT_LENGTH, 0, 1);//初始化fft
//arm_cfft_f32(&scfft, ff_in, 0, 1);
arm_cfft_radix4_f32(&scfft, ff_in);
arm_cmplx_mag_f32(ff_in, ff_out, FFT_LENGTH);
ff_out[0] /= (float )FFT_LENGTH;//根据傅里叶变换原理,直流分量幅频曲线中幅值与时域的幅值相等(好吧我也不太清楚)
for (int i = 1; i < FFT_LENGTH; i++)//输出各次谐波幅值
{
ff_out[i] /=(float ) FFT_LENGTH/2;
}
}