STM32|灵动微 MM32 多路ADC-DMA配置

一、问题 【STM32|灵动微 MM32 多路ADC-DMA配置】最近在使用灵动微的MM32,当用多路ADC-DMA时,出现了一些问题,所以在此记录一下
总结下来,处理了下面几个问题(这里的问题是拿到最新的SDK包,参考example没办法解决的)

  1. 多路通道对应的DMA内存不明确,例如CH0对应DMA的第二个字节,CH1却对应第一字节
  2. 多个通道数值接近
二、解决方法
  1. 使用任意通道
    ADC_ANY_NUM_Config(ADC1,3); //一共4通道 ADC1->ANYCR |=ADC_ANY_CR_CHANY_MDEN; //开启任意通道 ///设置通道的顺序 ADC_ANY_CH_Config(ADC1,0,ADC_Channel_0); ADC_ANY_CH_Config(ADC1,1,ADC_Channel_1); ADC_ANY_CH_Config(ADC1,2,ADC_Channel_2); ADC_ANY_CH_Config(ADC1,3,ADC_Channel_Vrefint);

  2. 这个问题,是因为引脚悬空导致了,举个例子,若PA1有确切电平, PA2 PA3
    悬空,则PA2 PA3得到的数据会跟随PA1变化,只有一点点区别(细微差别)
三、整体代码
void adc_dma_init() { DMA_InitTypeDef DMA_InitStruct; RCC_AHBPeriphClockCmd(RCC_AHBENR_DMA1, ENABLE); DMA_DeInit(DMA1_Channel1); DMA_StructInit(&DMA_InitStruct); //DMA transfer peripheral address DMA_InitStruct.DMA_PeripheralBaseAddr = (u32) & (ADC1->DR); //DMA transfer memory address DMA_InitStruct.DMA_MemoryBaseAddr = (u32)&adcBuf; //DMA transfer direction from peripheral to memory DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC; //DMA cache size DMA_InitStruct.DMA_BufferSize = ADC_DMA_BUF_SIZE; //After receiving the data, the peripheral address is forbidden to move //backward DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //After receiving the data, the memory address is shifted backward DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; //Define the peripheral data width to 16 bits DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //Define the memory data width to 16 bits DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //Cycle conversion mode DMA_InitStruct.DMA_Mode = DMA_Mode_Circular; //DMA priority is high DMA_InitStruct.DMA_Priority = DMA_Priority_High; //M2M mode is disabled DMA_InitStruct.DMA_M2M = DMA_M2M_Disable; DMA_InitStruct.DMA_Auto_reload = DMA_Auto_Reload_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStruct); DMA_Cmd(DMA1_Channel1, ENABLE); ADC_InitTypeDefADC_InitStruct; ADC_StructInit(&ADC_InitStruct); //Initialize PA1 to analog input mode //Enable ADC clock RCC_APB2PeriphClockCmd(RCC_APB2ENR_ADC1, ENABLE); ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b; //ADC prescale factor ADC_InitStruct.ADC_PRESCARE = ADC_PCLK2_PRESCARE_17; //Set ADC mode to continuous conversion mode ADC_InitStruct.ADC_Mode = ADC_Mode_Continue; //AD data right-justified ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1; ADC_Init(ADC1, &ADC_InitStruct); GPIO_InitTypeDef GPIO_InitStruct; RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOC, ENABLE); GPIO_StructInit(&GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOA, &GPIO_InitStruct); //PC3ADC_IN13 GPIO_InitStruct.GPIO_Pin=GPIO_Pin_3; GPIO_Init(GPIOC, &GPIO_InitStruct); //Enable the channel ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 0, ADC_Samctl_240_5); ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 0, ADC_Samctl_240_5); ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 0, ADC_Samctl_240_5); // ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 0, ADC_Samctl_240_5); // ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 0, ADC_Samctl_240_5); //ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 0, ADC_Samctl_240_5); //ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 0, ADC_Samctl_240_5); // ADC_RegularChannelConfig(ADC1, 13, 0, ADC_Samctl_240_5); //通道13 ADC_RegularChannelConfig(ADC1, ADC_Channel_Vrefint, 0, ADC_Samctl_240_5); ADC_ANY_CH_Config(ADC1,0,ADC_Channel_0); ADC_ANY_CH_Config(ADC1,1,ADC_Channel_1); ADC_ANY_CH_Config(ADC1,2,ADC_Channel_2); ADC_ANY_CH_Config(ADC1,3,ADC_Channel_Vrefint); ADC_ANY_NUM_Config(ADC1,3); // ADC1->ANYCR |=ADC_ANY_CR_CHANY_MDEN; //开启任意通道ADC_TempSensorVrefintCmd(ENABLE); //Enable ADCDMA ADC_DMACmd(ADC1, ENABLE); //Enable AD conversion ADC_Cmd(ADC1, ENABLE); ADC_SoftwareStartConvCmd(ADC1, ENABLE); }

    推荐阅读