用AD检测交流电压信号,用FFT算法?
用AD检测交流电压(50HZ)信号,电路已经加直流偏执太高电压,没有负电压。用FFT算法用定时器中断,100us中断一次,每中断一次读取一次AD值,共中断200次,就是20ms一个周期,读取200次放入数组,然后关闭定时器,然后通过均方根得到最后AD数值,然后在打开定时器。
现在的问题是得到的数值的个位一直在变化(数值为3位数),并且精度也不是很高,是方法有问题还是程序有问题??
uint16_t Get_Adc(void)
{
ADC_SoftwareStartConvCmd(ADC1,ENABLE); //启动ADC转换
while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)); //等待转换完成
return ADC_GetConversionValue(ADC1);
}
void TIM3_IRQHandler(void)
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //100us中断一次
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update );
Num=Get_Adc();
ccc++;
if(ccc>200)
{
ccc=0;
TIM_Cmd(TIM3, DISABLE);
flag=1;
}
}
}
void yyy(void)
{
uint16_t j=0;
uint16_t i=0;
if(flag==1)
{
flag=0;
for(j=0;j<200;j++)
{
zzz = (float)Num*3300/4096-1640;
ad+=zzz*zzz;
}
ad = sqrt(ad/200);
TIM_Cmd(TIM3, ENABLE);
}
edmundlee 发表于 2019-11-23 10:40
你的图只是一个参考电压的电路, 没看到你是怎样把交流加上参考电压的啊 ...
完整电路图
问题是你的目的是什么,单一频率的信号。
根据公式,zzz[]数组赋值不对,应该是直接的AD转换值u(1)、u(2)........。开方运算后才是电压值。而且变量ad累加200次还需要考虑溢出的问题。
wenyangzeng 发表于 2019-10-31 12:47
根据公式,zzz[]数组赋值不对,应该是直接的AD转换值u(1)、u(2)........。开方运算后才是电压值。而且变 ...
zzz[]数组里的值是平方和,
ad = sqrt(ad/200);是开根号 qazplm3218 发表于 2019-10-31 13:56
zzz[]数组里的值是平方和,
ad = sqrt(ad/200);是开根号
每个u(n)得到一个绝对值了,那个*3300/4096-1640的运算不应该做的 wenyangzeng 发表于 2019-10-31 14:37
每个u(n)得到一个绝对值了,那个*3300/4096-1640的运算不应该做的
3300/4096-1640
是直接取消掉不要了,1640,是直流偏执电压,所有要减去 要不就用慢办法,分步来,先看ADC的值对不对,再计算一两组和理论公式对应一下 你的直流偏压是怎样加上去的?如果是直接的AC+DC, 那你的公式就错了, 那能把DC也算进去的 edmundlee 发表于 2019-11-21 12:26
你的直流偏压是怎样加上去的?如果是直接的AC+DC, 那你的公式就错了, 那能把DC也算进去的 ...
电压偏置电路
qazplm3218 发表于 2019-11-22 15:38
电压偏置电路
偏置电压为3.3/2
页:
[1]
2