- 2024-11-11
-
加入了学习《littlefulse 多元新技术赋能安全可靠和高效》,观看 LIT-3762-09 CSR Series_Captions-CN
-
加入了学习《littlefulse 多元新技术赋能安全可靠和高效》,观看 LIT-3762-08-eFuse_USB_Captions-CN
-
加入了学习《littlefulse 多元新技术赋能安全可靠和高效》,观看 LIT-3762-24_LoadSwitchesICs_2024UpdateFINAL_CN
-
加入了学习《littlefulse 多元新技术赋能安全可靠和高效》,观看 LIT-3762-20-SIDACtor-Captions_CN
-
加入了学习《littlefulse 多元新技术赋能安全可靠和高效》,观看 LIT-3762-11_SZSMF4L_Captions-CN
-
加入了学习《littlefulse 多元新技术赋能安全可靠和高效》,观看 LIT-3762-10-AEC-Q200-CN-Captions
-
加入了学习《littlefulse 多元新技术赋能安全可靠和高效》,观看 LIT-3762-22-25_MATE12B-MITI7L-ReedSwitches-Captions-CN
-
加入了学习《littlefulse 多元新技术赋能安全可靠和高效》,观看 LIT-3762-23_TTapeCaptions-CN
- 2024-06-13
-
回复了主题帖:
AD采样通过FFT算幅值和角度不对
Gen_X 发表于 2024-6-11 11:37
我数学不是太好,但也做过一些FFT分析,效果很好。
有个原则:一个周期的数据无论采集密度多好(64点) ...
对,64点,32点在电力中常用,而且算出来的没什么问题。
应该还是程序有问题。
-
回复了主题帖:
使用网上FFT的计算方式,进入硬件错误中断
吾妻思萌 发表于 2024-6-12 08:54
采用的数据读取格式时候是不是有问题
倒是参考着网上的来做的。我再检查检查。
-
回复了主题帖:
使用网上FFT的计算方式,进入硬件错误中断
大小家伙好 发表于 2024-6-11 14:34
楼主有确认过ADC内码与实际波形是否吻合吗,
可以是先试着自己按照理论正弦函数生成64个点,
再去验 ...
嗯,我先用excel表格弄2组64点数据,带到程序里试试。关于你说的ADC内码与实际波形,这个没有注意,ADC内码就是采样值,这个实际波形怎么抓到,这个采样就是一个周波一个周波这么采,不是从过0点开始采的,不知道是哪个起始位置。
- 2024-06-11
-
发表了主题帖:
使用网上FFT的计算方式,进入硬件错误中断
在AD采样通过FFT算幅值和角度不对 - 测试/测量 - 电子工程世界-论坛 (eeworld.com.cn)帖子中,算的相位与幅值不对。又从网上找了找例程,用网上的方法重新做了一遍,相位依然不对,而且出现个新问题。
每周波20ms采64个点,定义的输入数组、输出数组、各次谐波数组如下:
int32_t lBUFIN[64]; //NPT=64
int32_t lBUFOUT[32]; //输出数组是采样输入的一半
int16_t lx,ly; //过度变量
float X,Y,Mag; //虚部 实部 谐波临时存储变量
uint32_t lBufMagArray[32]; //最后算出来的谐波值数组 也是32个
for (i = 0; i < 64; i++)
{
lBUFIN[i] = (sample[channel].AI0[b0]<<16); //channel是AD通道序号
}
cr4_fft_64_stm32(lBUFOUT,lBUFIN,64); //总是在这一步进入硬件错误中断,屏蔽此处正常
for (i = 0;i <= (64 >> 1);i ++)
{
lx = (lBUFOUT[i] << 16) >> 16;
ly = (lBUFOUT[i] >> 16);
X = 64 * ((float)lx) / 32768;
Y = 64 * ((float)ly) / 32768;
Mag = sqrt(X * X + Y * Y) / 64;
if(i == 0)
lBufMagArray[i] = (unsigned long)(Mag * 32768); //0次,即直流分量
else
lBufMagArray[i] = (unsigned long)(Mag * 65536); //1,2,3,4等谐波幅值 其中1次谐波是50hz,是正弦波的基波,认为近似等于输入正弦波幅值
if(i==1)
{
MYData.Forier[f_type].phase=(atan2(X,Y) * 180.00 / PI); //在1次谐波50hz下,算相位
}
}
现在问题是:
(1)相位依然在乱变,大致看上去互相差120度,但一直(-118,127),(-109,-248),(113,246)(111,-249),基本就是这种没有规律的乱变
(2)输出数组数量如果定义为int32_t lBUFOUT[32]; 一旦运行到cr4_fft_64_stm32(lBUFOUT,lBUFIN,64); 就进入硬件错误中断。将lBUFOUT[32]改为lBUFOUT[64]就没事。但网上我看都是输出数组大小是输入数组的一半。这是哪有问题。
- 2024-06-10
-
发表了主题帖:
AD采样通过FFT算幅值和角度不对
使用STM32F103采样3个交流电压、3个交流电流,但因为电流采样范围较宽,所以使用多级运放进行不同倍数的放大,共开通12个AD通道,3个电压通道,9个电流通道。
使用TIM3定时器,设置每周波(20ms)采64个点,DMA一直在传送;
htim3.Instance = TIM3;
htim3.Init.Prescaler = 2-1;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 11250-1;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
{
Error_Handler();
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
/* USER CODE BEGIN Callback 0 */
if (htim == (&htim3))
{
HAL_ADC_Start_DMA(&hadc1,(uint32_t *)ADC_Cache,12);
}
/* USER CODE END Callback 0 */
/* USER CODE BEGIN Callback 1 */
/* USER CODE END Callback 1 */
}
通过ADC回调函数将转换的采样取出来:
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc==&hadc1)
{
adc_data[0].sample[pcnt]=ADC_Cache[0];
adc_data[1].sample[pcnt]=ADC_Cache[1];
adc_data[2].sample[pcnt]=ADC_Cache[2];
。。。。。。。
/*省略这一段就是12个通道的采样取值*/
pcnt++;
pcnt&= 255;
if(pcnt%64==0)
{
calc_flag=1;
fft_ptn=pcnt;
}
}
}
采到64个点,就置一个标志位,使用FFT算幅值和角度。使用的是ST自带的FFT计算库中的:
cr4_fft_64_stm32(lBUFOUT,lBUFIN,64);
再计算实部和虚部,通过实部虚部再算幅值和角度。
其中,幅值是算了1~9次谐波累加再开方作为幅值;
角度是phase=(atan2(lBUF_v[1].imag,lBUF_v[1].real)/PI*180.00),因为我认为1次正弦波就是50hz,角度就是该频率点下的角度。
问题是:
(1)算出来的幅值乘以系数后,只能在某个区间是对的,比如在200~240V电压之间是对的。将电压调低,算出来的数据就差的比较多,需要改系数,但对其他区间的电压采样又不对。
(2)算出来的角度,以A相为基准,认为是0度,用B相减去A相,C相减去A相,B,C角度总在变,一会是-121,118,一会是245,114,一会是-240,128,一会是-125,-248。
想问问这种可能是什么原因。