用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[ccc]=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[j] = (float)Num[j]*3300/4096-1640; ad+=zzz[j]*zzz[j]; } ad = sqrt(ad/200); TIM_Cmd(TIM3, ENABLE); } |
完整电路图
根据公式,zzz[]数组赋值不对,应该是直接的AD转换值u(1)、u(2)........。开方运算后才是电压值。而且变量ad累加200次还需要考虑溢出的问题。
zzz[]数组里的值是平方和,
ad = sqrt(ad/200);是开根号
每个u(n)得到一个绝对值了,那个*3300/4096-1640的运算不应该做的
3300/4096-1640
是直接取消掉不要了,1640,是直流偏执电压,所有要减去
电压偏置电路
偏置电压为3.3/2
你的图只是一个参考电压的电路, 没看到你是怎样把交流加上参考电压的啊
就是1640这个数有稍微的误差,应该是1590, 但这都不应该对你的精度有大的影响
那具体要怎么做,要用什么公式?
请您指点一下。。!