ADC采集出来的信号一直有问题,我是利用DMA将信号存到一个内存数组,结果内存数组在一半多的时候数据就出现问题了,然后在双缓冲切换时,也会丢失几个点,这个我想的通,但是前面内存数组在一半多数据就全乱了,实在没找到问题,望各位大神解答。以下是代码:
main函数:
#define NUM 1600
int main(void)
{
float adc_Y=Rel_Value*4096.0/3.3;
u16 i,t;
u16 n=0;
u16 adc_value1[NUM+500];
u16 adc_value2[NUM+500];
u16 b0=0,b1=0;
u16 max=0;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
delay_init(168);
uart_init(230400);
EXTIX_Init(); //初始化外部中断输入
MYADC1_configure();
MYDMA_DMA_DIR_PeripheralToMemoryConfig(DMA2_Stream4,DMA_Channel_0,(u32)&ADC1->DR,(u32)&adc_value1,(u32)&adc_value2,NUM);
ADC_SoftwareStartConv(ADC1);
TIM3_Int_Init(10000-1,8400-1);//定时器结束将内存数组的数发出
while(1)
{
if(DMA_Freebuf_OK==1)
{
if(DMA_GetCurrentMemoryTarget(DMA2_Stream4)==0)
{
if(n<8000)
{
for(i=0;i<NUM;i++)
{
TestData[n]=adc_value2[i];//TestDate为内存数组存储ADC数据。全局变量,大小为10000
n=n+1;
}
}
}
else
{
if(n<8000)
{
for(i=0;i<NUM;i++)
{
TestData[n]=adc_value1[i];
n=n+1;
}
}
}
DMA_Freebuf_OK=0;
}
}
}
DMA.C:
u8 DMA_Freebuf_OK=0;
u16 TestData[TestData_Len];
void MYDMA_DMA_DIR_PeripheralToMemoryConfig(DMA_Stream_TypeDef *DMA_Streamx,u32 chanlx,u32 par,u32 memory0,u32 memory1,u16 ndtr)//(数据流,通道,外设基地址,存储器基地址,传输量,不管是多少位的,传输量只是数据的个数,这里设置为数组的长度)
{
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_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 = chanlx; //通道选择
DMA_InitStructure.DMA_PeripheralBaseAddr = par;//DMA外设地址,S0PAR
DMA_InitStructure.DMA_Memory0BaseAddr = memory0;//DMA 存储器地址 S0M0AR
DMA_InitStructure.DMA_DIR =DMA_DIR_PeripheralToMemory ;//外设到存储器
DMA_InitStructure.DMA_BufferSize = ndtr;//数据传输量 ,NDTR
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设非增量模式,S0CR
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//存储器增量模式,S0CR
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;// 循环模式,S0CR
DMA_InitStructure.DMA_Priority = DMA_Priority_High;//最高优先级,S0CR
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
DMA_DoubleBufferModeConfig(DMA_Streamx,(u32)&memory1,DMA_Memory_0);
DMA_DoubleBufferModeCmd(DMA_Streamx,ENABLE);
DMA_ClearITPendingBit(DMA2_Stream4,DMA_IT_TCIF4);
DMA_ITConfig(DMA2_Stream4,DMA_IT_TC,ENABLE);
DMA_Cmd(DMA_Streamx, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel=DMA2_Stream4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&NVIC_InitStructure);
}
void DMA2_Stream4_IRQHandler()
{
if(DMA_GetITStatus(DMA2_Stream4,DMA_IT_TCIF4))
{
DMA_ClearITPendingBit(DMA2_Stream4,DMA_IT_TCIF4);
DMA_ClearFlag(DMA2_Stream2,DMA_FLAG_TCIF2);//清满标志
while(DMA_GetFlagStatus(DMA2_Stream2,DMA_FLAG_TCIF2)==SET);
DMA_Freebuf_OK=1;
}
}
adc.c:
u16 Chanel[Ch_Num];
void MYADC1_configure()//从adc中
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL ;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
GPIO_Init(GPIOC,&GPIO_InitStructure);
//复位ADC
ADC_DeInit();
//配置通用寄存器ADC_CCR
ADC_CommonInitStructure.ADC_Mode=ADC_Mode_Independent;//单通道
ADC_CommonInitStructure.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInitStructure.ADC_DMAAccessMode=ADC_DMAAccessMode_Disabled;//未使用多重ADC模式
ADC_CommonInitStructure.ADC_Prescaler=ADC_Prescaler_Div4;//84/4=21M
ADC_CommonInit(&ADC_CommonInitStructure);
//配置ADC1
ADC_InitStructure.ADC_Resolution=ADC_Resolution_12b;//分辨率12位
ADC_InitStructure.ADC_ScanConvMode=DISABLE;//关闭扫描模式
ADC_InitStructure.ADC_ContinuousConvMode=ENABLE;//开启连续转换 CR2
ADC_InitStructure.ADC_ExternalTrigConvEdge=ADC_ExternalTrigConvEdge_None;//不采用边沿触发
ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//右对齐
ADC_InitStructure.ADC_NbrOfConversion=1;//采样通道1个
ADC_Init(ADC1,&ADC_InitStructure);
//始能ADC
ADC_RegularChannelConfig(ADC1, ADC_Channel_10,1, ADC_SampleTime_3Cycles ); //配置通道优先级 SMPR2,SQR3
ADC_DMARequestAfterLastTransferCmd(ADC1,ENABLE); //源数据变化时开启DMA传输,CR2
ADC_DMACmd(ADC1,ENABLE);//使能ADC的DMA传输
ADC_Cmd(ADC1, ENABLE);
}
timer:
void TIM3_Int_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); ///使能TIM3时钟
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(TIM3,&TIM_TimeBaseInitStructure);//初始化TIM3
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //允许定时器3更新中断
TIM_Cmd(TIM3,ENABLE); //使能定时器3
NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //定时器3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01; //抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
//定时器3中断服务函数
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
{
time_c++;
if(time_c==3)
{
TIM_Cmd(TIM3,DISABLE);
{
USART_SendData(USART1,0);
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
}
for(t=0;t<TestData_Len;t++)
{
USART_SendData(USART1,(TestData[t]&0xff00)>>8);
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
USART_SendData(USART1,TestData[t]&0xff);
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
}
time_c=0;
}
}
TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除中断标志位
}
对的,我把数组放在串口的.h里面声明全局就可以啦
一周热门 更多>