菜鸟求助STM32ADC多通道连续转换模式问题

2019-03-23 18:22发布

我用PA0,PA1,PB0三路作为ADC的三个通道,每个通道用单通道模式测试转换都是正确的,但是ADC和DMA参数改成多通道模式时结果不正确,为乱码。

/*-------------------------------ADC private variables-----------------------------*/
#define ADC1_DR_Address    ((u32)0x4001244C)
#define Vref=3.0;
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
vu16 ADCConvertedValue;
static unsigned long ticks;
unsigned char Clock1s;
/*------------------------------ADC private variables------------------------------*/


/*----------------ADC中传输数据的DMA的初始化--------------------------------------------------------------*/
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);    //ENABLE DMA clock  
DMA_DeInit(DMA1_Channel1);
   DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;     //DMA两个源的地址
   DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADCConvertedValue;
   DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                   //数据的传输方向,把外设作为源,即第一个地址为源
   DMA_InitStructure.DMA_BufferSize = 1;             //传输数据的大小
   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;   //每次传出数据的地址是否递增。因为ADC每次传出数据的地址同一个,不用递增
   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;      //AD为多通道连续转换模式,两个通道的结果存放在一个数组里
   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //传输数据的位数。半字,16位
   DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
   DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;        //传输模式,一种为普通模式,传输完了就好了;循环模式,传输完了在传输
   DMA_InitStructure.DMA_Priority = DMA_Priority_High;
   DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
   DMA_Init(DMA1_Channel1, &DMA_InitStructure);   
   /* Enable DMA1 channel1 */
  DMA_Cmd(DMA1_Channel1, ENABLE);
/*-----------------初始化结束--------------------------------------------------------------------------------*/   
                           
   /* ADC1 configuration ---------------------------------------------------------------------------------------*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1  | RCC_APB2Periph_AFIO |RCC_APB2Periph_GPIOA |RCC_APB2Periph_GPIOB,ENABLE);
   ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
   ADC_InitStructure.ADC_ScanConvMode = ENABLE;
   ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
   ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
   ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
   ADC_InitStructure.ADC_NbrOfChannel = 3;
   ADC_Init(ADC1, &ADC_InitStructure);   
   /* ADC1 regular channel8,channel9 configuration  -4 */
  ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 2, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 3, ADC_SampleTime_239Cycles5);     
   /* Enable ADC1 DMA */
   ADC_DMACmd(ADC1, ENABLE);
  
   /* Enable ADC1 */
   ADC_Cmd(ADC1, ENABLE);
   /* Enable ADC1 reset calibaration register */   
   ADC_ResetCalibration(ADC1);
   /* Check the end of ADC1 reset calibration register */
   while(ADC_GetResetCalibrationStatus(ADC1));
   /* Start ADC1 calibaration */
   ADC_StartCalibration(ADC1);
   /* Check the end of ADC1 calibration */
   while(ADC_GetCalibrationStatus(ADC1));
     
   /* Start ADC1 Software Conversion */
   ADC_SoftwareStartConvCmd(ADC1, ENABLE);
/*-----------------------------ADC初始化结束-------------------------------------------------------------------*/

for(adci=0;adci<=2;adci++)
    {
        AD_value[adci]=ADC_GetConversionValue(ADC1);               //读取两个通道的转换结果
    }
    if(ticks++>=500000)   //软件产生延时
    {
        ticks=0;
     Clock1s=1;
    }  
    if(Clock1s)
    {
        Clock1s=0;
   //  printf("The current AD value1 = 0x%4x ",AD_value[0]);
   //  printf("The current AD value2 = 0x%4x ",AD_value[1]);
    }            
    /*ADC数据测试模块------------------------------------------------------------------------------*/
这是我ADC部分的程序,各位大神,能告诉我哪里错了吗?

[ 本帖最后由 向日葵不哭100 于 2012-11-17 22:40 编辑 ] 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
7条回答
wudayongnb
1楼-- · 2019-03-24 01:09
/ 你虽然使能了DMA,但是根本就没有用上
for(adci=0;adci<=2;adci++)
    {
        AD_value[adci]=ADC_GetConversionValue(ADC1);               //读取两个通道的转换结果
    }
你还是直接调用AD的函数来读取转换值,如果用DMA,你试试这么改
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)AD_value;
向日葵不哭100
2楼-- · 2019-03-24 07:09
请问DMA_InitStructure.DMA_MemoryBaseAddr = (u32)AD_value; 中的AD_value是库函数里面的函数吗?我设置的变量是AD_value[3]数组类型
向日葵不哭100
3楼-- · 2019-03-24 09:00
 精彩回答 2  元偷偷看……
wudayongnb
4楼-- · 2019-03-24 09:59
是按照我说的那样调出来的吗
wudayongnb
5楼-- · 2019-03-24 14:36
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)AD_value ,这个AD_value就是你定义的存放转换结果的数组的首地址,你要读3个转换结果,所以 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 内存设置成增加模式,另外你原来的程序为什么不行,我是这么理解的,你是这么写的
for(adci=0;adci<=2;adci++)
    {
        AD_value[adci]=ADC_GetConversionValue(ADC1);               //读取两个通道的转换结果
    }
你连着读3次想把3次的结果读出来,后两次还没转换完呢,你就去读,肯定是乱码的,你在这个循环里加上判别是不是转换结束的语句,再读,你这么做试试
沉睡中的king
6楼-- · 2019-03-24 19:34
 精彩回答 2  元偷偷看……

一周热门 更多>