新手入门 
 
	- 积分
 - 11
 
        - 金钱
 - 11 
 
       - 注册时间
 - 2022-1-25
 
      - 在线时间
 - 4 小时
 
 
 
 | 
 
如题,想做一个数字滤波器,adc采样数据后再通过dac把滤波后的信号发送出去,然后卡在两个dma上面了。目前是在用adc+dma采样数据,通过滤波函数处理后串口发送出去,同时dac输出一个与” adc采样数据无关 “的正弦波,观察dac+dma能否正常工作。 
遇到的问题是,dac在关闭的时候,adc接受的一个三次谐波,经过滤波函数,滤波函数正常工作,将滤波后信号串口打印,是一个正弦波。 
dac在正常工作并输出正弦波的时候,adc同样接受的一个三次谐波,经过滤波函数,此时滤波函数滤波后的信号变为三次谐波,就是没起到作用,求大佬解惑。 
下面是adc+dma的代码配置 
- #include "adc.h"
 
 - #include "delay.h"        
 
 - #include <string.h>
 
 - #include "filter.h"
 
  
- #define TEST_LENGTH_SAMPLES  300 
 
  
- extern u16 ADC_Raw[TEST_LENGTH_SAMPLES];
 
 - u16 temp[TEST_LENGTH_SAMPLES];
 
 - extern float testInput_f32_50Hz_200Hz[TEST_LENGTH_SAMPLES];        
 
  
- //初始化ADC                                                                                                                           
 
 - void DMA_Config(DMA_Stream_TypeDef *DMA_Streamx,uint32_t chx,uint32_t par,uint32_t mar,uint16_t ndtr,uint32_t pri)
 
 - { 
 
 -  
 
 -         DMA_InitTypeDef  DMA_InitStructure;
 
 -         
 
 -         if((u32)DMA_Streamx>(u32)DMA2)                                                                                                                                                                        //得到当前stream是属于DMA2还是DMA1
 
 -         {
 
 -           RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);                                                                                //DMA2时钟使能 
 
 -                 
 
 -         }else 
 
 -         {
 
 -           RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);                                                                                //DMA1时钟使能 
 
 -         }
 
 -   DMA_DeInit(DMA_Streamx);
 
 -         
 
 -         while (DMA_GetCmdStatus(DMA_Streamx) != DISABLE){}                                                                                        //等待DMA可配置 
 
 -         
 
 -   /* 配置 DMA Stream */
 
 -   DMA_InitStructure.DMA_Channel            = chx;                                                                                                 //通道选择
 
 -   DMA_InitStructure.DMA_PeripheralBaseAddr = par;                                                                                                  //DMA外设地址
 
 -   DMA_InitStructure.DMA_Memory0BaseAddr    = mar;                                                                                                        //DMA 存储器0地址
 
 -   DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralToMemory;        //外设到内存
 
 -   DMA_InitStructure.DMA_BufferSize         = ndtr;                                                                                                //数据传输量 
 
 -   DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;                //外设非增量模式
 
 -   DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable;                                //存储器增量模式
 
 -   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设数据长度:16位
 
 -   DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_HalfWord;                        //存储器数据长度:16位
 
 -   DMA_InitStructure.DMA_Mode               = DMA_Mode_Circular;                                                        //使用循环模式 
 
 -   DMA_InitStructure.DMA_Priority           = pri;                                                        //优先级
 
 -   DMA_InitStructure.DMA_FIFOMode           = DMA_FIFOMode_Disable;         
 
 -   DMA_InitStructure.DMA_FIFOThreshold      = DMA_FIFOThreshold_Full;
 
 -   DMA_InitStructure.DMA_MemoryBurst        = DMA_MemoryBurst_Single;                        //存储器突发单次传输
 
 -   DMA_InitStructure.DMA_PeripheralBurst    = DMA_PeripheralBurst_Single;        //外设突发单次传输
 
 -   DMA_Init(DMA_Streamx, &DMA_InitStructure);                                                                                                                        //初始化DMA Stream
 
 -                                                                                                
 
 -                 
 
 -         /* DMA2_Stream0 enable */
 
 -   DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TC);
 
 -         DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);
 
 -         DMA_Cmd(DMA_Streamx, ENABLE);     
 
 - } 
 
 -  
 
 - //初始化ADC3IN7引脚
 
 - void ADCInit_GPIO(void)
 
 - {
 
 -         GPIO_InitTypeDef  GPIO_InitStructure;
 
 -  
 
 -   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
 
 -  
 
 -   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
 
 -   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;  
 
 -   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 
 
 -   GPIO_Init(GPIOA, &GPIO_InitStructure);  
 
 - } 
 
 -  
 
 - void ADC_Config(void)
 
 - {
 
 -         ADC_CommonInitTypeDef ADC_CommonInitStructure;
 
 -   ADC_InitTypeDef       ADC_InitStructure;
 
 -     
 
 -   RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);
 
 -     
 
 -   RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC3,ENABLE);      
 
 -   RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC3,DISABLE);    
 
 -  
 
 -   ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
 
 -   ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; 
 
 -   ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; 
 
 -   ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;
 
 -   ADC_CommonInit(&ADC_CommonInitStructure);
 
 -     
 
 -   ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
 
 -   ADC_InitStructure.ADC_ScanConvMode = ENABLE; 
 
 -   ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
 
 -   ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising; 
 
 -   ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO;//定时器2外部触发  
 
 -   ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
 
 -   ADC_InitStructure.ADC_NbrOfConversion = 1; //M   
 
 -   ADC_Init(ADC3, &ADC_InitStructure);
 
 -     delay_ms(5);
 
 -   ADC_RegularChannelConfig(ADC3, ADC_Channel_0, 1, ADC_SampleTime_480Cycles);   
 
 -   ADC_DMARequestAfterLastTransferCmd(ADC3, ENABLE);//源数据变化时开启DMA传输
 
 -   ADC_DMACmd(ADC3, ENABLE);  //使能ADC的DMA传输
 
 -   ADC_Cmd(ADC3, ENABLE);
 
 -         
 
 - }
 
 -  
 
 -  
 
 -  
 
 -  
 
 - void NVIC_Config(void)
 
 - {
 
 -         NVIC_InitTypeDef NVIC_InitStructure;
 
 -   
 
 -         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//最高一位用于配置抢占优先级,低三位用于配置响应优先级
 
 -         
 
 -   NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  
 
 -   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;  
 
 -   NVIC_InitStructure.NVIC_IRQChannelSubPriority =1;        
 
 -   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;            
 
 -   NVIC_Init(&NVIC_InitStructure);    
 
 -    
 
 -   NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;  
 
 -   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;  
 
 -   NVIC_InitStructure.NVIC_IRQChannelSubPriority =1;        
 
 -   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           
 
 -   NVIC_Init(&NVIC_InitStructure);   
 
 - }
 
 -  
 
 - void Timer_Init(void)
 
 - {
 
 -         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
 
 -  
 
 -  
 
 -   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);          
 
 -  
 
 -  
 
 -   TIM_Cmd(TIM2, DISABLE);
 
 -   TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); 
 
 -     
 
 -   //T=(84 * 625) / 84M = 625us = 20ms/32,1600HZ 
 
 -   TIM_TimeBaseStructure.TIM_Prescaler = 4199        ;//84-1; 
 
 -   TIM_TimeBaseStructure.TIM_Period = 1;//312500/CurrentFreq - 1; 
 
 -   TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; 
 
 -   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up ; 
 
 -   TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); 
 
 -     
 
 -     
 
 -   TIM_ARRPreloadConfig(TIM2, ENABLE); 
 
 -   TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);  
 
 -  
 
 -   TIM_Cmd(TIM2, ENABLE); 
 
 - }
 
 -  
 
 - void TIM2_IRQHandler(void)  
 
 - {
 
 -   if(TIM_GetITStatus(TIM2, TIM_IT_Update))  
 
 -   {  
 
 -                 //LED0=~LED0;
 
 -     TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
 
 -   }
 
 -     
 
 - }
 
 - u16 adc_cov;
 
 - u16 ADC3_IN7_RES;
 
 -  
 
 -  
 
 - void DMA2_Stream0_IRQHandler(void)  
 
 - {
 
 -         u16 i=0;
 
 -  if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0)) 
 
 -  {
 
 -          memcpy(temp, ADC_Raw, sizeof(u16)*TEST_LENGTH_SAMPLES);
 
 -                 for(i=0;i<TEST_LENGTH_SAMPLES;i++){
 
 -                         testInput_f32_50Hz_200Hz[i]=(float)temp[i];
 
 -                 }
 
 -                 printf("\r\n-------arm_fir_f32_lp();-------\r\n");
 
 -                 arm_fir_f32_lp();
 
 -                 printf("\r\n------arm_fir_f32_lp();--------\r\n");
 
 -    DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
 
 -          
 
 -  }
 
 - }
 
 -          
 
  
 
 
 
 
 
 
 
 
  复制代码 以下是dac+dma和定时器的配置 
- //dac.c
 
  
- #include "dac.h"
 
  
 
- //DAC通道1输出初始化
 
 - void DAC_Mode_Init(u16 mar)
 
 - {
 
 -     DAC_InitTypeDef DAC_InitType;
 
 -     DMA_InitTypeDef DMA_InitStre;
 
 -     GPIO_InitTypeDef  GPIO_InitStructure;
 
 -     
 
 -                 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟
 
 -                 RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);//使能DAC时钟
 
 -     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);//DMA时钟
 
 -         
 
 -         
 
 -                 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
 
 -                 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
 
 -                 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//下拉
 
 -                 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;  
 
 -                 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
 
 -                 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化
 
 -     /************************* 通道1 ***************************/
 
 -     //使用DMA模式-寄存器到外设
 
 -     DAC_InitType.DAC_Trigger=DAC_Trigger_T2_TRGO;    //必须使用触发功能 TEN1=0
 
 -     DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_None;//不使用波形发生
 
 -     DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;//屏蔽、幅值设置
 
 -     DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Disable;    //DAC1输出缓存关闭 BOFF1=1
 
 -                 DAC_Init(DAC_Channel_1,&DAC_InitType);     //初始化DAC通道1
 
 -     DAC_Cmd(DAC_Channel_1, ENABLE);  //使能DAC通道1
 
 -     
 
 -     
 
 -     //DMA初始化
 
 -     DMA_DeInit(DMA1_Stream5);//复位
 
 -     DMA_InitStre.DMA_PeripheralBaseAddr=(uint32_t)&(DAC->DHR12R1);//外设 DAC1_DR
 
 -     DMA_InitStre.DMA_PeripheralBurst=DMA_PeripheralBurst_Single;
 
 -     DMA_InitStre.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;//半字
 
 -     DMA_InitStre.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//外设地址增加失能
 
 -     
 
 -     DMA_InitStre.DMA_Memory0BaseAddr=mar;    //内存地址
 
 -     DMA_InitStre.DMA_MemoryInc=DMA_MemoryInc_Enable;//寄存器(变量)地址增加
 
 -     DMA_InitStre.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;//半字
 
 -     DMA_InitStre.DMA_MemoryBurst=DMA_MemoryBurst_Single;
 
 -     
 
 -     DMA_InitStre.DMA_Channel=DMA_Channel_7;
 
 -     DMA_InitStre.DMA_DIR=DMA_DIR_MemoryToPeripheral;//寄存器到外设输出
 
 -     DMA_InitStre.DMA_BufferSize=300;//一个输出循环中数据长度
 
 -     DMA_InitStre.DMA_Mode=DMA_Mode_Circular;//循环发送
 
 -     
 
 -     DMA_InitStre.DMA_Priority=DMA_Priority_High;
 
 -     DMA_InitStre.DMA_FIFOMode=DMA_FIFOMode_Disable;
 
 -     DMA_InitStre.DMA_FIFOThreshold=DMA_FIFOThreshold_1QuarterFull;
 
 -     DMA_Init(DMA1_Stream5,&DMA_InitStre);//初始化
 
 -     
 
 -     DMA_Cmd(DMA1_Stream5,ENABLE);//DMA使能
 
 -     DAC_DMACmd(DAC_Channel_1, ENABLE);//DAC-DMA使能 
 
 -         }
 
  
- //time.c
 
 - #include "timer.h"
 
 - #include "led.h"
 
  
 
- //通用定时器4中断初始化
 
 - //arr:自动重装值。
 
 - //psc:时钟预分频数
 
 - //定时器溢出时间计算方法:Tout=((arr+1)*(psc+1))/Ft us.
 
 - //Ft=定时器工作频率,单位:Mhz
 
 - //这里使用的是定时器2
 
 - void TIM2_Int_Init(u16 arr,u16 psc)
 
 - {
 
 -         TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
 
 -         NVIC_InitTypeDef NVIC_InitStructure;
 
 -         
 
 -         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);   ///使能TIM2时钟
 
 -         
 
 -         
 
 -         TIM_DeInit(TIM2); // 初始化
 
 -         TIM_TimeBaseStructInit(&TIM_TimeBaseInitStructure); // 初始化
 
 -         
 
 -   TIM_TimeBaseInitStructure.TIM_Period = arr;         //自动重装载值
 
 -         TIM_TimeBaseInitStructure.TIM_Prescaler=psc;  //定时器分频
 
 -         TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
 
 -         TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; 
 
 -         
 
 -         TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);//初始化TIM2
 
 -         
 
 -         TIM_SelectOutputTrigger(TIM2,TIM_TRGOSource_Update); // **与上一方案不同**
 
 -         TIM_Cmd(TIM2,ENABLE); //使能定时器2
 
 -         
 
 -         
 
 - }
 
  复制代码 以下是滤波函数 
- #include "filter.h"
 
 - #include "arm_math.h"
 
  
- #define TEST_LENGTH_SAMPLES  300    /* 采样点数 */
 
 - #define BLOCK_SIZE           1             /* 调用一次arm_fir_f32处理的采样点个数 */
 
 - #define NUM_TAPS             29      /* 滤波器系数个数 */
 
  
- float32_t testInput_f32_50Hz_200Hz[TEST_LENGTH_SAMPLES]; /* 采样点 */
 
 - static float32_t testOutput[TEST_LENGTH_SAMPLES];               /* 滤波后的输出 */
 
 - static float32_t firStateF32[BLOCK_SIZE + NUM_TAPS - 1];        /* 状态缓存,大小numTaps + blockSize - 1*/
 
  
- uint32_t blockSize = BLOCK_SIZE;
 
 - uint32_t numBlocks = TEST_LENGTH_SAMPLES/BLOCK_SIZE;            /* 需要调用arm_fir_f32的次数 */
 
  
 
- const float32_t firCoeffs32LP[NUM_TAPS] = {
 
 -    0.001066399611256, 0.002126085729052, 0.003159337947181, 0.003059846159226,
 
 -   -1.968950437715e-18, -0.00705866005337, -0.01651859315877, -0.02329385602413,
 
 -    -0.01997951839664,5.751341766627e-18,  0.03857458762271,  0.09055123279738,
 
 -      0.1441009644858,   0.1844676143613,    0.199489117838,   0.1844676143613,
 
 -      0.1441009644858,  0.09055123279738,  0.03857458762271,5.751341766627e-18,
 
 -    -0.01997951839664, -0.02329385602413, -0.01651859315877, -0.00705866005337,
 
 -   -1.968950437715e-18, 0.003059846159226, 0.003159337947181, 0.002126085729052,
 
 -    0.001066399611256
 
 - };
 
  
 
- void arm_fir_f32_lp(void)
 
 - {
 
 -         uint32_t i;
 
 -         arm_fir_instance_f32 S;
 
 -         float32_t  *inputF32, *outputF32;
 
  
-         /* 初始化输入输出缓存指针 */
 
 -         inputF32 = &testInput_f32_50Hz_200Hz[0];
 
 -         outputF32 = &testOutput[0];
 
  
-         /* 初始化结构体S */
 
 -         arm_fir_init_f32(&S,                            
 
 -                                          NUM_TAPS, 
 
 -                         (float32_t *)&firCoeffs32LP[0], 
 
 -                          &firStateF32[0], 
 
 -                          blockSize);
 
  
-         /* 实现FIR滤波,这里每次处理1个点 */
 
 -         for(i=0; i < numBlocks; i++)
 
 -         {
 
 -                 arm_fir_f32(&S, inputF32 + (i * blockSize),  outputF32 + (i * blockSize),  blockSize);
 
 -         }
 
 -         
 
  
-         /* 打印滤波后结果 */
 
 -         for(i=0; i<TEST_LENGTH_SAMPLES; i++)
 
 -         {
 
 -                 printf("%f\r\n",  outputF32[i]);
 
 -         }
 
  
- }
 
  复制代码 
 
 |   
 
 
 
 |