新手入门
- 积分
- 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]);
- }
- }
复制代码
|
|