1.在项目中使用复旦微LE系列MCU,ADC使用DMA搬运数据,为了调试方便使用UART1发送数据,但发现ADC和串口不能同时使用,开启UART1发送数据功能,就会使DMA搬运ADC值失败。

2.代码如下:

void DMA_Init(void)
{
  /* ADC DMA */
  FL_DMA_InitTypeDef DMA_InitStruct = {0};
  FL_DMA_ConfigTypeDef DMA_ConfigStruct = {0};
  DMA_InitStruct.periphAddress = FL_DMA_PERIPHERAL_FUNCTION1;
  DMA_InitStruct.direction = FL_DMA_DIR_PERIPHERAL_TO_RAM;
  DMA_InitStruct.memoryAddressIncMode = FL_DMA_MEMORY_INC_MODE_INCREASE;
  DMA_InitStruct.dataSize = FL_DMA_BANDWIDTH_16B;
  DMA_InitStruct.priority = FL_DMA_PRIORITY_HIGH;
  DMA_InitStruct.circMode = FL_ENABLE;
  FL_DMA_Init(DMA, &DMA_InitStruct, FL_DMA_CHANNEL_4);

  FL_DMA_Enable(DMA);

  DMA_ConfigStruct.memoryAddress = (uint32_t)&ADC_Drv.Buf;
  DMA_ConfigStruct.transmissionCount = sizeof(ADC_Drv.Buf) /  sizeof(adc_result_type) - 1;
  FL_DMA_StartTransmission(DMA, &DMA_ConfigStruct, FL_DMA_CHANNEL_4);

  NVIC_DisableIRQ(DMA_IRQn);
//  NVIC_SetPriority(DMA_IRQn, 0);
//  NVIC_EnableIRQ(DMA_IRQn);
}

void ADC_Init(void)
{
    FL_ADC_CommonInitTypeDef    ADC_CommonInitStruct;
    FL_ADC_InitTypeDef          ADC_InitStruct ;
    
    /* ADC 时钟配置 */
    ADC_CommonInitStruct.clockSource         = FL_RCC_ADC_CLK_SOURCE_RCHF;  /* ADC_CLK 时钟源 */
    ADC_CommonInitStruct.clockPrescaler      = FL_RCC_ADC_PSC_DIV8;         /* ADC_CLK 分频系数 */
    
    FL_ADC_CommonInit(&ADC_CommonInitStruct);
    
    /* ADC寄存器设置 */
    ADC_InitStruct.conversionMode           = FL_ADC_CONV_MODE_SINGLE;     /* 单次模式 */
    ADC_InitStruct.autoMode                 = FL_ADC_SINGLE_CONV_MODE_AUTO;/* 自动 */
    ADC_InitStruct.waitMode                 = FL_DISABLE;                  /* 等待 */
    ADC_InitStruct.overrunMode              = FL_ENABLE;                   /* 覆盖上次数据 */
    ADC_InitStruct.scanDirection            = FL_ADC_SEQ_SCAN_DIR_FORWARD; /* 通道正序扫描 */
    ADC_InitStruct.externalTrigConv         = FL_ADC_TRIGGER_EDGE_NONE;    /* 禁止触发信号 */
    ADC_InitStruct.triggerSource            = FL_ADC_TRGI_PA8;             /* 触发信号选择 */
    ADC_InitStruct.fastChannelTime          = FL_ADC_FAST_CH_SAMPLING_TIME_2_ADCCLK;  /* 快速通道采样时间 */
    ADC_InitStruct.lowChannelTime           = FL_ADC_SLOW_CH_SAMPLING_TIME_192_ADCCLK;/* 慢速通道采样时间 */
    ADC_InitStruct.oversamplingMode         = FL_ENABLE;                   /* 过采样打开 关闭可缩短采样时间 */
    ADC_InitStruct.overSampingMultiplier    = FL_ADC_OVERSAMPLING_MUL_8X;  /* 8倍过采样 */
    ADC_InitStruct.oversamplingShift        = FL_ADC_OVERSAMPLING_SHIFT_3B;/* 数据右移*/
   
    FL_ADC_Init(ADC, &ADC_InitStruct);
    FL_ADC_EnableDMAReq(ADC);
}

3.使用DMA通道4进行搬运ADC数据

4.手册说明

5.从手册中看出UART1的TX脚也是DMA的通道4,所以怀疑是通道冲突导致的,将DMA搬运ADC数据的通道改为0,发现ADC和UART1功能都正常了。

6.如下所示

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐