OpenEdv-开源电子网

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

关于ADC1 DMA 多通道模数转换,得到数据错乱的问题

[复制链接]

9

主题

34

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
231
金钱
231
注册时间
2016-6-6
在线时间
48 小时
发表于 2021-1-4 10:50:57 | 显示全部楼层 |阅读模式
我用模数转换ADC1配置6通道模数转换,通过DMA进行数据传输。最后发现得到数据是乱的(通道1:63 1A ,A2 CA ,98 1A ,CE 98, 77 7C ,44 2C),其他通道在未接任何电位器情况下,数据也是乱的(如通道一)。STM32单片机经验有限,找了好久,找不到愿因。希望大家帮我看看问题在哪。
在系统中,我开启了串口123和定时器234,其中TIM4作为PWM输出时钟。
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "key.h"
#include "timer.h"
#include "iwdg.h"
#include "adc.h"


int main(void)
{       
    HAL_Init();                             
    Stm32_Clock_Init(RCC_PLL_MUL9);          
        delay_init(72);  
        MY_DMA_Init();                    
        uart_init();                                        //串口1.2.3
        LED_Init();                       
        KEY_GPIO_Init();               
        TIMx_Init();                                //定时器2.3.4
        MY_ADC1_Init();                //ADC13õê¼»ˉ

        HAL_ADC_Start_DMA(&ADC1_Handler,(uint32_t*)&ADC_Value,600);//ADC,DMA规则转换
    while(1)
    {
                NUMB1 = power_val.word;
                __HAL_TIM_SET_COMPARE(&TIM4_Handler, TIM_CHANNEL_1, NUMB1);        //PWM       

                speed_vol_read();  //按键读取程序

               
                read_ADC_average();   //读取ADC转换值
                temp1_value.word = (uint16_t)temp1_value_AD;   //ζè1
                data[0] = temp1_value.dc.hi;
                data[1] = temp1_value.dc.lo;                               

                if(speed_vol_on == 1)    //发送采样值到串口
                {
                        speed_vol_on = 0;
                        HAL_UART_Transmit(&UART1_Handler,(uint8_t*)data,2,1000);        //·¢Ëí½óêÕμ½μÄêy¾Y
                        while(__HAL_UART_GET_FLAG(&UART1_Handler,UART_FLAG_TC)!=SET);                //μè′y·¢Ëí½áêø
                }
    }
}


/*************ADC、DMA 配置****************/
#include "adc.h"
#include "delay.h"


ADC_HandleTypeDef         ADC1_Handler;                //ADC
DMA_HandleTypeDef         DMA1_Handler;      //DMA

uint32_t ADC_Value[600];        //ADC数据缓存区
uint32_t temp1_value_AD,temp2_value_AD,temp3_value_AD,temp4_value_AD,pow_value_AD,swr_value_AD;        //转换值寄存器

//初始化ADC
//ch: ADC_channels


void MY_ADC1_Init(void)
{
        RCC_PeriphCLKInitTypeDef ADC_CLKInit;
        ADC_ChannelConfTypeDef ADC1_Channel;
       
    ADC1_Handler.Instance=ADC1;
    ADC1_Handler.Init.ScanConvMode=ADC_SCAN_ENABLE;              //é¨ÃèÄ£ê½
    ADC1_Handler.Init.ContinuousConvMode=ENABLE;                //á¬Dø×a»»
        ADC1_Handler.Init.DiscontinuousConvMode=DISABLE;             //½ûÖ12»á¬Dø2éÑùÄ£ê½
    ADC1_Handler.Init.DataAlign=ADC_DATAALIGN_RIGHT;             //óò¶ÔÆë
    ADC1_Handler.Init.NbrOfConversion=6;                         //6¸ö×a»»Ôú1æÔòDòáDÖD ò2¾íêÇÖ»×a»»1æÔòDòáD1
//   ADC1_Handler.Init.NbrOfDiscConversion=0;                     //2»á¬Dø2éÑùí¨μàêyÎa0
    ADC1_Handler.Init.ExternalTrigConv=ADC_SOFTWARE_START;       //èí¼t′¥·¢?????
    while(HAL_ADC_Init(&ADC1_Handler) != HAL_OK){;}                                 //3õê¼»ˉ                

/****í¨μàÅäÖÃ****/
        ADC1_Channel.Channel = ADC_CHANNEL_0;
        ADC1_Channel.Rank = ADC_REGULAR_RANK_1;
        ADC1_Channel.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
        while(HAL_ADC_ConfigChannel(&ADC1_Handler, &ADC1_Channel) != HAL_OK)
        {;}
        ADC1_Channel.Channel = ADC_CHANNEL_1;
        ADC1_Channel.Rank = ADC_REGULAR_RANK_2;
        ADC1_Channel.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
        while(HAL_ADC_ConfigChannel(&ADC1_Handler, &ADC1_Channel) != HAL_OK)
        {;}
        ADC1_Channel.Channel = ADC_CHANNEL_2;
        ADC1_Channel.Rank = ADC_REGULAR_RANK_3;
        ADC1_Channel.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
        while(HAL_ADC_ConfigChannel(&ADC1_Handler, &ADC1_Channel) != HAL_OK)
        {;}
        ADC1_Channel.Channel = ADC_CHANNEL_3;
        ADC1_Channel.Rank = ADC_REGULAR_RANK_4;
        ADC1_Channel.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
        while(HAL_ADC_ConfigChannel(&ADC1_Handler, &ADC1_Channel) != HAL_OK)
        {;}
        ADC1_Channel.Channel = ADC_CHANNEL_4;
        ADC1_Channel.Rank = ADC_REGULAR_RANK_5;
        ADC1_Channel.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
        while(HAL_ADC_ConfigChannel(&ADC1_Handler, &ADC1_Channel) != HAL_OK)
        {;}
        ADC1_Channel.Channel = ADC_CHANNEL_5;
        ADC1_Channel.Rank = ADC_REGULAR_RANK_6;
        ADC1_Channel.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
        while(HAL_ADC_ConfigChannel(&ADC1_Handler, &ADC1_Channel) != HAL_OK)
        {;}

               
//        HAL_ADCEx_Calibration_Start(&ADC1_Handler);                                         //D£×¼ADC
}

//ADC驱动,引脚配置,时钟使能
//此函数会被HAL_ADC_Init()调用
//配置DMA
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
    GPIO_InitTypeDef GPIO_Initure;
  if(hadc->Instance==ADC1)
  {       
    __HAL_RCC_ADC1_CLK_ENABLE();            //使能ADC1时钟
    __HAL_RCC_GPIOA_CLK_ENABLE();                        //开启GPIOA时钟

       
    GPIO_Initure.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5;            //PA0~5
    GPIO_Initure.Mode = GPIO_MODE_ANALOG;     //模拟
    GPIO_Initure.Pull = GPIO_NOPULL;          //不上下拉
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);
       
/* ADC1 DMA Init */

    //DMA1配置
    DMA1_Handler.Instance = DMA1_Channel1;              //通道
    DMA1_Handler.Init.Direction=DMA_PERIPH_TO_MEMORY;             //外设到内存
    DMA1_Handler.Init.PeriphInc=DMA_PINC_DISABLE;        //外设非增量模式
    DMA1_Handler.Init.MemInc=DMA_MINC_ENABLE;             //内存增量模式
    DMA1_Handler.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD;           //外设数据长度
    DMA1_Handler.Init.MemDataAlignment=DMA_PDATAALIGN_WORD;           //存储器数据长度
    DMA1_Handler.Init.Mode=DMA_CIRCULAR;               //外设循环模式
    DMA1_Handler.Init.Priority=DMA_PRIORITY_LOW;             //优先级低

        while(HAL_DMA_Init(&DMA1_Handler) != HAL_OK){;}       
               
        __HAL_LINKDMA(hadc,DMA_Handle,DMA1_Handler);
  }
}
void MY_DMA_Init(void)
{
        __HAL_RCC_DMA1_CLK_ENABLE();                        //DMA1时钟使能
        HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
        HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}


//获取6通道的转换值,取100次转换的平均值
void read_ADC_average(void)
{
        int time;
        temp1_value_AD = 0;
        temp2_value_AD = 0;
        temp3_value_AD = 0;
        temp4_value_AD = 0;
        pow_value_AD = 0;
        swr_value_AD = 0;
        for(time=0;time<600;time=time+6)
        {
                temp1_value_AD = temp1_value_AD + ADC_Value[time];
                temp2_value_AD = temp2_value_AD + ADC_Value[time+1];
                temp3_value_AD = temp3_value_AD + ADC_Value[time+2];
                temp4_value_AD = temp4_value_AD + ADC_Value[time+3];
                pow_value_AD = pow_value_AD + ADC_Value[time+4];
                swr_value_AD = swr_value_AD + ADC_Value[time+5];
        }
        temp1_value_AD = (uint32_t)temp1_value_AD/100;
        temp2_value_AD = (uint32_t)temp2_value_AD/100;
        temp3_value_AD = (uint32_t)temp3_value_AD/100;
        temp4_value_AD = (uint32_t)temp4_value_AD/100;
        pow_value_AD = (uint32_t)pow_value_AD/100;
        swr_value_AD = (uint32_t)swr_value_AD/100;

}





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

使用道具 举报

9

主题

34

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
231
金钱
231
注册时间
2016-6-6
在线时间
48 小时
 楼主| 发表于 2021-1-4 11:01:53 | 显示全部楼层
   DMA1_Handler.Init.MemDataAlignment=DMA_PDATAALIGN_WORD;           //存储器数据长度
应该是   DMA1_Handler.Init.MemDataAlignment=DMA_MDATAALIGN_WORD;还是自己太菜了:@
回复 支持 反对

使用道具 举报

3

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
82
金钱
82
注册时间
2020-6-22
在线时间
17 小时
发表于 2021-1-25 11:10:01 | 显示全部楼层
试试    hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
           hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
我之前用一个字节也是数据不对。
回复 支持 反对

使用道具 举报

0

主题

48

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1161
金钱
1161
注册时间
2013-8-23
在线时间
165 小时
发表于 2021-1-28 08:37:28 | 显示全部楼层
同样发现此问题, 6是极限,超过数组次序就会乱, 只好拆分为5+4
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-12 18:00

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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