[STM32F1] 用AD采集连续两个零点

[复制链接]
2166|40
songqian17 发表于 2020-8-25 23:03 | 显示全部楼层
没有看懂楼主的代码要实现什么
chenho 发表于 2020-8-25 23:07 | 显示全部楼层
控制采样的flag呢?
juventus9554 发表于 2020-8-25 23:14 | 显示全部楼层
就是跟楼主的变量控制有关系。
houcs 发表于 2020-8-25 23:17 | 显示全部楼层
楼主不是应该通过计算两次实现的吗?
zwll 发表于 2020-8-25 23:20 | 显示全部楼层
两次采集求平均值,不如均值滤波算法。
chuxh 发表于 2020-8-25 23:24 | 显示全部楼层
tmp这个数据是怎么产生的?
llia 发表于 2020-8-25 23:29 | 显示全部楼层
楼主最好附上完成的代码
llljh 发表于 2020-8-25 23:33 | 显示全部楼层
采样复位设置一个变量。
juventus9554 发表于 2020-8-25 23:37 | 显示全部楼层

如果不想采集,将变量置位为0.
pangb 发表于 2020-8-25 23:41 | 显示全部楼层
采样完成就不讲tmp换成你要数据就行。
dingy 发表于 2020-8-25 23:44 | 显示全部楼层

把flag设置为0采样不会继续的。
pengf 发表于 2020-8-25 23:49 | 显示全部楼层

需要采样的时候将变量置位true否则为false。
 楼主| liuzaiy 发表于 2020-8-25 23:53 | 显示全部楼层
#include "led.h"
#include "sys.h"
#include "usart.h"         
#include "adc.h"
#include "find_peak.h"
#include "timer.h"
#include "math.h"

int sig[MAX_SIGNAL_LEN];  //采集数据
int peaks[MAX_SIGNAL_LEN];   //峰值点位置数据
int troughs[MAX_SIGNAL_LEN];   // 谷值点位置数据
int i,n1,n2,n3;
int tmp;
double fre;

int main()
{
         i=0;
         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
         LED_Init ();
         uart_init(115200);
         Adc_Init();
         TIM_OPMGATE_Init();
         while(1)
                 {
                         tmp=Get_Adc_Average(ADC_Channel_1,10);
                         if(tmp==3103)
                         {
                                 for(i=0;i<MAX_SIGNAL_LEN;i++)
                                 {
                                         sig=Get_Adc_Average(ADC_Channel_1,10);
                                 //sig=Get_Adc(ADC_Channel_1);
                                         printf("%d \r\n",sig);
                                 }
                         }
                        
        n1 = MAX_SIGNAL_LEN;  
        
        process(sig,n1);  //数据预处理
        
        n2=find_peaks(sig,n1,peaks);  //
        n3=find_troughs(sig,n1,troughs);   //

        printf("\n峰值点位置\n");
        for(i=0;i<n2;i++)
                         {
                                 printf("%u ",peaks+1);  //下标从1开始
                                 TIM_Open();
                         }
        printf("\谷值点位置\n");
        for(i=0;i<n3;i++)
                         {
                                 printf("%u ",troughs+1);
                                 TIM_Open();
                         }
                 }
}
 楼主| liuzaiy 发表于 2020-8-25 23:56 | 显示全部楼层

我的目的并不是找到峰谷值点。输入信号是类正弦信号(带噪声,周期会变化但不会突变),我想在检测到峰谷点的时候立即输出一个脉冲波。但是对峰值检测理解不深,虽然有阈值法检测程序。但是有很大的问题:首先必须检测一段数据才可以进行处理,假如数据包含了峰谷点(或许不值一个),那么这个特征点已经过去了,再加上要处理,实时性根本做不到。
方法一:所以想控制ADC采集的数据长度,以半个周期采集一次(连续两个过零点),其中必有一个峰值或者谷值点。用定时器控制ADC采样,然后findpeak()找到峰值点位置,计算出点数乘于定时器时间就是图中的t0,由于周期不会突变,就把t0的时间给谷值点,认为这两段时间近似相等,依次类推。
方法二:最简单误差有点大,过零点把类正弦转换为方波,然后输入捕获,计算半个周期时间除于2得时间t,开启定时器定时t,时间到发送脉冲波。也刚好在峰值点或者谷值点出现脉冲。只是误差大。
很想用第一种方法,但是感觉很复杂,各位老铁给分析下。
cdklh1968 发表于 2020-8-26 07:31 | 显示全部楼层
“我的目的并不是找到峰谷值点。输入信号是类正弦信号(带噪声,周期会变化但不会突变),我想在检测到峰谷点的时候立即输出一个脉冲波。”   楼主这句话好矛盾呀??
ayb_ice 发表于 2020-8-26 09:09 | 显示全部楼层
本帖最后由 ayb_ice 于 2020-8-26 09:16 编辑

不能等于某个值,要给一个范围
        bit bStart = 0;
        u16 aucBuf[xxx];
        u16 usPushIndex = 0;
        while (1)
        {
                u16 usTmp = AdcGetVal();
                if (usTmp >= xxx && usTmp <= xxx)
                {
                        if (!bStart)
                        {
                                bStart = 1;
                        }
                        else
                        {
                                break;
                        }
                }
                if (bStart)
                {
                        if (usPushIndex < xxx)
                        {
                                aucBuf[usPushIndex++] = usTmp;
                        }
                }
        }




yanzhengxin1 发表于 2020-8-26 09:24 | 显示全部楼层
用“==”,确定能这么准确,用的是什么ADC呀?
houcs 发表于 2020-8-26 21:01 | 显示全部楼层

int ad_buf,ad_buf2;//AD缓存
int err;//零点误差范围
int zero_flag1,zero_flag2;
int i=0,sig[]={0};
ad_buf=Get_Ad();//第一次过零检测
if(abs(ad_buf-3103)<err)
{
    zero_flag1=1;
}
if(zero_flag==1)
{
ad_buf2=Get_Ad();
if(abs(ad_buf-3103)<err)//第二次过零检测
{
   i=0;
}
else if(abs(ad_buf-3103)>=err)//中间数据
{
  seg【i】=ad_buf2;
   i++;
}


}
renyaq 发表于 2020-8-26 21:06 | 显示全部楼层
如果用对比的话 要 有一个范围 不能是一个值
chenjunt 发表于 2020-8-26 21:09 | 显示全部楼层
我没看明白楼主想要问啥捏
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部