OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4614|回复: 8

STM32F103调试12位ADC,采用DMA方式获取的转换结果远大于4096

[复制链接]

1

主题

6

帖子

0

精华

新手上路

积分
20
金钱
20
注册时间
2016-6-7
在线时间
4 小时
发表于 2016-6-7 17:14:16 | 显示全部楼层 |阅读模式
本帖最后由 xuande 于 2016-6-7 17:29 编辑

vu16 ADC_Val[12]={0,0,0,0,0,0,0,0,0,0,0,0};
u16 J;
void ADC_GPIO_Init(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC        , ENABLE );          //ê1ÄüADC1í¨μàê±Öó

        //PA1 ×÷ÎaÄ£Äaí¨μàêäèëòy½Å                        
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;                //Ä£Äaêäèëòy½Å
        GPIO_Init(GPIOA, &GPIO_InitStructure);        
        
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;                //Ä£Äaêäèëòy½Å
        GPIO_Init(GPIOB, &GPIO_InitStructure);        
        
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_2;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;                //Ä£Äaêäèëòy½Å
        GPIO_Init(GPIOC, &GPIO_InitStructure);        
}

void ADC_DMA_Config(void)
{
        DMA_InitTypeDef DMA_InitStructure;
        ADC_InitTypeDef ADC_InitStructure;
        
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1        , ENABLE );
        RCC_ADCCLKConfig(RCC_PCLK2_Div8);   //éèÖÃADC·ÖÆμòò×ó6 72M/6=12,ADC×î′óê±¼ä2»Äü3¬1y14M
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
        
        DMA_DeInit(DMA1_Channel1);
        
        DMA_InitStructure.DMA_PeripheralBaseAddr=(u32)&(ADC1->DR);
        DMA_InitStructure.DMA_MemoryBaseAddr=(u32)&ADC_Val;
        DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;
        DMA_InitStructure.DMA_BufferSize=12;
        DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;
        DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;
        DMA_InitStructure.DMA_MemoryDataSize=DMA_PeripheralDataSize_HalfWord;
        DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_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);
        DMA_ITConfig(DMA1_Channel1,DMA1_IT_TC1,ENABLE);
        
        DMA_Cmd(DMA1_Channel1, ENABLE);
//        DMA_ITConfig(DMA1_Channel1,DMA1_IT_TC1,ENABLE);
        
        ADC_DeInit(ADC1);  //¸′λADC1,½«íaéè ADC1 μÄè«2¿¼Ä′æÆ÷ÖØéèÎaè±ê¡Öμ

        ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;        //ADC1¤×÷Ä£ê½:ADC1oíADC21¤×÷Ôú¶àá¢Ä£ê½
        ADC_InitStructure.ADC_ScanConvMode = ENABLE;        //Ä£êy×a»»1¤×÷Ôúμ¥í¨μàÄ£ê½
        ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;        //Ä£êy×a»»1¤×÷Ôúμ¥′Î×a»»Ä£ê½
        ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;        //×a»»óéèí¼t¶ø2»êÇía2¿′¥·¢Æô¶ˉ
        ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;        //ADCêy¾Yóò¶ÔÆë
        ADC_InitStructure.ADC_NbrOfChannel = 12;        //Ë3Dò½øDD1æÔò×a»»μÄADCí¨μàμÄêyÄ¿
        ADC_Init(ADC1, &ADC_InitStructure);        //¸ù¾YADC_InitStructÖDÖ¸¶¨μÄ2Îêy3õê¼»ˉíaéèADCxμļÄ′æÆ÷  

        ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5 );
        ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_239Cycles5 );
        ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 3, ADC_SampleTime_239Cycles5 );
        ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 4, ADC_SampleTime_239Cycles5 );
        ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 5, ADC_SampleTime_239Cycles5 );
        ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 6, ADC_SampleTime_239Cycles5 );
        ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 7, ADC_SampleTime_239Cycles5 );         
        ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 8, ADC_SampleTime_239Cycles5 );
        ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 9, ADC_SampleTime_239Cycles5 );
        ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 10, ADC_SampleTime_239Cycles5 );
        ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 11, ADC_SampleTime_239Cycles5 );
        ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 12, ADC_SampleTime_239Cycles5 );

        
        // ¿aÆôADCμÄDMAÖ§3Ö£¨òaêμÏÖDMA1|Äü£¬»1Dè¶àá¢ÅäÖÃDMAí¨μàμè2Îêy£©
        ADC_DMACmd(ADC1, ENABLE);   
        ADC_Cmd(ADC1, ENABLE); //ê1ÄüÖ¸¶¨μÄADC1   
        ADC_ResetCalibration(ADC1); //¸′λָ¶¨μÄADC1μÄD£×¼¼Ä′æÆ÷

        while(ADC_GetResetCalibrationStatus(ADC1)); //»ñè¡ADC1¸′λD£×¼¼Ä′æÆ÷μÄ×′ì¬,éèÖÃ×′ì¬Ôòμè′y   
        ADC_StartCalibration(ADC1); //¿aê¼Ö¸¶¨ADC1μÄD£×¼×′쬠  
        while(ADC_GetCalibrationStatus(ADC1)); //»ñè¡Ö¸¶¨ADC1μÄD£×¼3ìDò,éèÖÃ×′ì¬Ôòμè′y   
        ADC_SoftwareStartConvCmd(ADC1, ENABLE);//¿aê¼×a»»        
}

void DMA1_Channel1_IRQHandler(void)
{
        u8 i;
        if(DMA_GetITStatus(DMA1_IT_TC1)!=RESET){
                ADC_Cmd(ADC1,DISABLE);
                ADC_SoftwareStartConvCmd(ADC1,DISABLE);
                DMA_Cmd(DMA1_Channel1,DISABLE);
                for(i=0;i<12;i++){
                        printf("(%d):%d ",i,ADC_Val);
                        delay_ms(100);
                }               
                printf("\n");
                DMA_Cmd(DMA1_Channel1,ENABLE);
                ADC_Cmd(ADC1,ENABLE);
                ADC_SoftwareStartConvCmd(ADC1,ENABLE);
    DMA_ClearFlag(DMA1_FLAG_TC1);      
        }
        J++;
}

void NVIC_Configuration(void)
{

    NVIC_InitTypeDef  NVIC_InitStructure;
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);   
  DMA_ClearFlag(DMA1_FLAG_TC1);
  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

采集到的数据很异常,前6个值远远大于1024,后面6个位0,如果将DMA_InitStructure.DMA_BufferSize=12,改为DMA_InitStructure.DMA_BufferSize=24;则12个数全部远远大于4096.
171022zoszpn96811ss6cb.png


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11544
金钱
11544
注册时间
2014-4-1
在线时间
1315 小时
发表于 2016-6-7 17:28:02 | 显示全部楼层

这中间有n个物理过程,
ADC,DMA,串口,
随便哪个有问题都不对。

分开来,一步步调试。


回复 支持 反对

使用道具 举报

1

主题

6

帖子

0

精华

新手上路

积分
20
金钱
20
注册时间
2016-6-7
在线时间
4 小时
 楼主| 发表于 2016-6-7 17:30:54 | 显示全部楼层
xuande 发表于 2016-6-7 17:28
这中间有n个物理过程,
ADC,DMA,串口,
随便哪个有问题都不对。

我如果不用DMA方式,传回的数据是正确的。
回复 支持 反对

使用道具 举报

1

主题

6

帖子

0

精华

新手上路

积分
20
金钱
20
注册时间
2016-6-7
在线时间
4 小时
 楼主| 发表于 2016-6-7 17:47:00 | 显示全部楼层
如果用DMA只管理一路ADC通道,也是同样的问题,而且发现会把ADC1_DR寄存器中的高位丢失掉,如图一。

图一

图一

回复 支持 反对

使用道具 举报

6

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
79
金钱
79
注册时间
2016-4-16
在线时间
12 小时
发表于 2016-6-7 19:18:46 | 显示全部楼层
不使用中断接受呢?
回复 支持 反对

使用道具 举报

1

主题

6

帖子

0

精华

新手上路

积分
20
金钱
20
注册时间
2016-6-7
在线时间
4 小时
 楼主| 发表于 2016-6-7 19:46:15 | 显示全部楼层
giant_huang 发表于 2016-6-7 19:18
不使用中断接受呢?

和这个是一样的
回复 支持 反对

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11544
金钱
11544
注册时间
2014-4-1
在线时间
1315 小时
发表于 2016-6-7 19:49:24 | 显示全部楼层

可能你DMA设为8位宽度了,
所以把高位丢了。


回复 支持 反对

使用道具 举报

1

主题

6

帖子

0

精华

新手上路

积分
20
金钱
20
注册时间
2016-6-7
在线时间
4 小时
 楼主| 发表于 2016-6-7 20:02:45 | 显示全部楼层
xuande 发表于 2016-6-7 19:49
可能你DMA设为8位宽度了,
所以把高位丢了。

谢谢,你提示了我,我发现问题了
DMA_InitStructure.DMA_MemoryDataSize=DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;

上面那个应该是
DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;
现在正常了!我太粗心了。
麻烦您了!多谢!
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
12
金钱
12
注册时间
2016-8-17
在线时间
2 小时
发表于 2016-8-17 20:47:42 | 显示全部楼层
ironn 发表于 2016-6-7 20:02
谢谢,你提示了我,我发现问题了
DMA_InitStructure.DMA_MemoryDataSize=DMA_PeripheralDataSize_HalfW ...

你好,我的ADC+DMA程序也出现丢高字节的现象,我检查过,halfword传输,内存地址增长使能的,能帮我想想还有别的影响因素吗?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-7 15:59

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表