打印
[STM32F1]

用AD采集连续两个零点

[复制链接]
楼主: liuzaiy
手机看帖
扫描二维码
随时随地手机跟帖
21
songqian17| | 2020-8-25 23:03 | 只看该作者 回帖奖励 |倒序浏览
没有看懂楼主的代码要实现什么

使用特权

评论回复
22
chenho| | 2020-8-25 23:07 | 只看该作者
控制采样的flag呢?

使用特权

评论回复
23
juventus9554| | 2020-8-25 23:14 | 只看该作者
就是跟楼主的变量控制有关系。

使用特权

评论回复
24
houcs| | 2020-8-25 23:17 | 只看该作者
楼主不是应该通过计算两次实现的吗?

使用特权

评论回复
25
zwll| | 2020-8-25 23:20 | 只看该作者
两次采集求平均值,不如均值滤波算法。

使用特权

评论回复
26
chuxh| | 2020-8-25 23:24 | 只看该作者
tmp这个数据是怎么产生的?

使用特权

评论回复
27
llia| | 2020-8-25 23:29 | 只看该作者
楼主最好附上完成的代码

使用特权

评论回复
28
llljh| | 2020-8-25 23:33 | 只看该作者
采样复位设置一个变量。

使用特权

评论回复
29
juventus9554| | 2020-8-25 23:37 | 只看该作者

如果不想采集,将变量置位为0.

使用特权

评论回复
30
pangb| | 2020-8-25 23:41 | 只看该作者
采样完成就不讲tmp换成你要数据就行。

使用特权

评论回复
31
dingy| | 2020-8-25 23:44 | 只看该作者

把flag设置为0采样不会继续的。

使用特权

评论回复
32
pengf| | 2020-8-25 23:49 | 只看该作者

需要采样的时候将变量置位true否则为false。

使用特权

评论回复
33
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();
                         }
                 }
}

使用特权

评论回复
34
liuzaiy|  楼主 | 2020-8-25 23:56 | 只看该作者

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

使用特权

评论回复
35
cdklh1968| | 2020-8-26 07:31 | 只看该作者
“我的目的并不是找到峰谷值点。输入信号是类正弦信号(带噪声,周期会变化但不会突变),我想在检测到峰谷点的时候立即输出一个脉冲波。”   楼主这句话好矛盾呀??

使用特权

评论回复
36
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;
                        }
                }
        }




使用特权

评论回复
37
yanzhengxin1| | 2020-8-26 09:24 | 只看该作者
用“==”,确定能这么准确,用的是什么ADC呀?

使用特权

评论回复
38
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++;
}


}

使用特权

评论回复
39
renyaq| | 2020-8-26 21:06 | 只看该作者
如果用对比的话 要 有一个范围 不能是一个值

使用特权

评论回复
40
chenjunt| | 2020-8-26 21:09 | 只看该作者
我没看明白楼主想要问啥捏

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则