各位大神,帮忙看下下面的6路ADC+_DMA的代码,能出来数值,但是最后的值不对,GND能识别成0V,但是3.3V就被识别成47V.
int main(void)
{
u32 mar[6] = {0};
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
delay_init(168); //
uart_init(115200); //
LED_Init();
Adc_Init((u32)mar);
while(1)
{
if(DMA_GetFlagStatus(DMA2_Stream0,DMA_FLAG_TCIF0)!=RESET)
{
printf("adc0=%f ",(float)mar[0]*(3.0/4096.0));
printf("adc1=%f ",(float)mar[1]*(3.0/4096.0));
printf("adc2=%f ",(float)mar[2]*(3.0/4096.0));
printf("adc3=%f ",(float)mar[3]*(3.0/4096.0));
printf("adc4=%f ",(float)mar[4]*(3.0/4096.0));
printf("adc5=%f ",(float)mar[5]*(3.0/4096.0));
// printf("adc = %f",temp);
printf("
");
DMA_ClearFlag(DMA2_Stream0,DMA_FLAG_TCIF0);
}
LED0=!LED0;
delay_ms(250);
}
}
void Adc_Init(u32 mar)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//ê1ÄüGPIOAê±Öó
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //ê1ÄüADC1ê±Öó
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);
//Ïè3õê¼»ˉADC1í¨μà5 IO¿ú
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_4|GPIO_Pin_3|GPIO_Pin_2|GPIO_Pin_1|GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//Ä£Äaêäèë
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//2»′øéÏÏÂà-
GPIO_Init(GPIOA, &GPIO_InitStructure);//3õê¼»ˉ
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE); //ADC1¸′λ
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE); //¸′λ½áêø
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;//Ô¤·ÖÆμ4·ÖÆμ
ADC_CommonInit(&ADC_CommonInitStructure);//3õê¼»ˉ
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12λÄ£ê½
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//½ûÖ1′¥·¢¼ì2a£¬ê1óÃèí¼t′¥·¢
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//óò¶ÔÆë
ADC_InitStructure.ADC_NbrOfConversion = 6;
ADC_Init(ADC1, &ADC_InitStructure);//ADC3õê¼»ˉ
DMA_DeInit(DMA2_Stream0);
while (DMA_GetCmdStatus(DMA2_Stream0) != DISABLE){}//μè′yDMA¿éÅäÖÃ
/* ÅäÖÃ DMA Stream */
DMA_InitStructure.DMA_Channel = DMA_Channel_0; //í¨μàÑ¡Ôñ
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->DR;//DMAíaéèμØÖ·
DMA_InitStructure.DMA_Memory0BaseAddr = (u32)mar;//DMA ′æ′¢Æ÷0μØÖ·
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;//′æ′¢Æ÷μ½íaéèÄ£ê½
DMA_InitStructure.DMA_BufferSize = 6;//êy¾Y′«êäá¿
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//íaéè·ÇÔöá¿Ä£ê½
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//′æ′¢Æ÷Ôöá¿Ä£ê½
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;//íaéèêy¾Y3¤¶è:32λ
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;//′æ′¢Æ÷êy¾Y3¤¶è:32λ
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//ÖDμèóÅÏ輶
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;//íaéèí»·¢μ¥′Î′«êä
DMA_Init(DMA2_Stream0, &DMA_InitStructure);//3õê¼»ˉDMA Stream
DMA_Cmd(DMA2_Stream0,ENABLE);
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_144Cycles );
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_144Cycles );
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_144Cycles );
ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_144Cycles );
ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 5, ADC_SampleTime_144Cycles );
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 6, ADC_SampleTime_144Cycles );
ADC_SoftwareStartConv(ADC1);
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
ADC_DMACmd(ADC1,ENABLE);
ADC_Cmd(ADC1, ENABLE);//¿aÆôAD×a»»Æ÷
}
原子哥,问题找到了,有三个问题。
1.应该使用void Adc_Init()初始化,不能使用void Adc_Init(u32 mar)。 这是为什么?
2.ADC_SoftwareStartConv(ADC1);应该放在ADC_Cmd(ADC1, ENABLE);的后面,放在前面就会出现问题。
3.接受数组的定义u32 mar[6];应该放在main函数的外面,并且在adc.c中要加外部变量什么extern u32 mar[6];
[mw_shl_code=c,true]extern u32 mar[6];
void Adc_Init()
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_4|GPIO_Pin_3|GPIO_Pin_2|GPIO_Pin_1|GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE);
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles;
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 = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 6;
ADC_Init(ADC1, &ADC_InitStructure);
DMA_DeInit(DMA2_Stream0);
while (DMA_GetCmdStatus(DMA2_Stream0) != DISABLE) {}
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->DR;
DMA_InitStructure.DMA_Memory0BaseAddr = (u32)mar;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = 6;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
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(DMA2_Stream0, &DMA_InitStructure);
DMA_Cmd(DMA2_Stream0,ENABLE);
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_144Cycles );
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_144Cycles );
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_144Cycles );
ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_144Cycles );
ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 5, ADC_SampleTime_144Cycles );
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 6, ADC_SampleTime_144Cycles );
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
ADC_DMACmd(ADC1,ENABLE);
ADC_Cmd(ADC1, ENABLE);
ADC_SoftwareStartConv(ADC1);
}
u32 mar[6];
int main(void)
{
u8 i;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//éèÖÃÏμí3ÖD¶ÏóÅÏ輶·Ö×é2
delay_init(168); //3õê¼»ˉÑóê±oˉêy
uart_init(115200); //3õê¼»ˉ′®¿ú2¨ìØÂêÎa115200
LED_Init();
Adc_Init(); //3õê¼»ˉADC
while(1)
{
if(DMA_GetFlagStatus(DMA2_Stream0,DMA_FLAG_TCIF0)!=RESET)
{
for(i = 0; i < 6; i++)
{
printf("adc%d =%4.2f ",i,mar*3.3/4096);
}
printf(" ");
DMA_ClearFlag(DMA2_Stream0,DMA_FLAG_TCIF0);
}
LED0=!LED0;
delay_ms(250);
}
}
[/mw_shl_code]
如果我想要想串口DMA那样,可以在初始化的时候才输入数组的地址?我对输入数组地址有点疑惑,不是输入数组名就是数组的起始地址吗?那为什么我上面的那种跑不通?正确方法应该是怎么样的呢?
感谢@rgzdb大神,他在一篇帖子里面回复了他的各种ADC实验,我是根据他里面的代码一行一行弄出来的。大神回复的那篇帖子
一周热门 更多>