使用DMA实现AD两个通道采样,通过串口打印结果,分别开启一个通道能够正确打印结果。而开启两个通道串口调试串口不显示任何数据。求高手指点如何解决。谢谢。 下面为主要的程序给程序配置应该没有问题,测试了一段时间。就是无法同时开启2个通道。不明白问题出在哪。望做过AD多道采样的高手给出解决的办法。谢谢。 #define ADC1_DR_Address ((uint32_t)0x4001244C) //ADC1 DR寄存器基地址 #define N 128 //ADC采样点数 #define M 2 //ADC采样通道数 vu16 AD_Value[N][M]; //存放ADC采样值,即DMA目标地址 u16 table[]; void ad_init() { ADC_InitTypeDefADC_InitStructure; DMA_InitTypeDefDMA_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr= ADC1_DR_Address; //DMA对应的外设基地址 DMA_InitStructure.DMA_MemoryBaseAddr= (uint32_t)&AD_Value; //内存存储基地址 //DMA_InitStructure.DMA_MemoryBaseAddr= (uint32_t)&ADConvertedValue; DMA_InitStructure.DMA_DIR= DMA_DIR_PeripheralSRC; //DMA的转换模式为SRC模式,由外设搬移到内存 DMA_InitStructure.DMA_BufferSize=2*128; //DMA缓存大小,2个,单位为DMA_MemoryDataSize DMA_InitStructure.DMA_PeripheralInc= DMA_PeripheralInc_Disable; //接收一次数据后,设备地址禁止后移 DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable; //关闭接收一次数据后,目标内存地址后移 //DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Disable; DMA_InitStructure.DMA_PeripheralDataSize= DMA_PeripheralDataSize_HalfWord; //定义外设数据宽度为16位 DMA_InitStructure.DMA_MemoryDataSize= DMA_MemoryDataSize_HalfWord; //DMA搬数据尺寸,HalfWord就是为16位 DMA_InitStructure.DMA_Mode= DMA_Mode_Circular; //转换模式,循环缓存模式。 DMA_InitStructure.DMA_Priority= DMA_Priority_High; //DMA优先级高 DMA_InitStructure.DMA_M2M= DMA_M2M_Disable; //M2M模式禁用 DMA_Init(DMA1_Channel1,&DMA_InitStructure); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE); RCC_ADCCLKConfig(RCC_PCLK2_Div6); ADC_DeInit(ADC1); ADC_InitStructure.ADC_Mode= ADC_Mode_Independent; //独立的转换模式 ADC_InitStructure.ADC_ScanConvMode=ENABLE; //开启扫描模式 //ADC_InitStructure.ADC_ScanConvMode=DISABLE; ADC_InitStructure.ADC_Con tinuousConvMode=ENABLE; // 开启连续转换模式 //ADC_InitStructure.ADC_ContinuousConvMode=DISABLE; ADC_InitStructure.ADC_ExternalTrigConv= ADC_ExternalTrigConv_None; //ADC外部开关,关闭状态 ADC_InitStructure.ADC_DataAlign= ADC_DataAlign_Right; //对齐方式,ADC为12位中,右对齐方式 ADC_InitStructure.ADC_NbrOfChannel=2; //开启通道数,2个 ADC_Init(ADC1,&ADC_InitStructure); ADC_DMACmd(ADC1,ENABLE); //ADC命令,使能 ADC_Cmd(ADC1,ENABLE); //开启ADC1 ADC_ResetCalibration(ADC1); //重新校准 while(ADC_GetResetCalibrationStatus(ADC1)); //等待重新校准完成 ADC_StartCalibration(ADC1); //开始校准 while(ADC_GetCalibrationStatus(ADC1)); //等待校准完成 ADC_SoftwareStartConvCmd(ADC1,ENABLE); //连续转换开始,ADC通过DMA方式不断的更新RAM区。 DMA_Cmd(DMA1_Channel1,ENABLE); //设置ADC1规则通道组,设置转化顺序和采样时间 //ADC1,ADC通道,规则采样顺序值,采样时间(具体计算) ADC_RegularChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_239Cycles5); ADC_RegularChannelConfig(ADC1,ADC_Channel_12,2,ADC_SampleTime_239Cycles5); } u16 GetVolt(u16 advalue) //获得AD采样电压值调用函数 { return(u16)(advalue*330/4096); } u16 value[]; void filter_2() //2个通道均值 { intsum=0; u8count; u8j; for(j=0;j<2;j++) { for(count=0;count<128;count++) { sum+=AD_Value[count][j]; } while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET); table[j]=sum/128; value[j]=GetVolt(table[j]); sum=0; } } void filter_printf_2() //2个通`道打印 { //u16value[2]; u8k; for(k=0;k<2;k++) { //value[k]=GetVolt(table[k]); while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET); printf("value[%d]:t%d.%dvn",k,value[k]/100,value[k]%100); printf("n"); } }
|