OpenEdv-开源电子网

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

求助原子哥和各位大侠STM32H732 HAL库+adc多通道采集+DMA方式,读出来的数据都是0

[复制链接]

10

主题

97

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
486
金钱
486
注册时间
2019-12-6
在线时间
151 小时
发表于 2020-10-8 13:44:01 | 显示全部楼层 |阅读模式
10金钱
我想用HAL库配置ADC三个通道采集 +DMA方式  转换后的结果保存到自己定义的一个数组里 可是读出去的数据全是0 我把ADC的三个通道引脚分别连到3.3 V    0V   2.5V电源管脚上  是不是哪里配置错 百度也没有HAL库配置ADC多通道采集的教程 弄了几天了还是没数据收到 求指教一下 以下是代码 main很简单就是 输出三个数组单元的值

#include "adc.h"
#include "sys.h"
#include "dma.h"

extern u32 ADC1ConvertedVoltage[3];  //dma传输的数据保存到该数组里

ADC_HandleTypeDef ADC_Handler;
DMA_HandleTypeDef DMA_Handler;  //DMA句柄  //DMA2时钟使能
void MY_ADC_Init(void)
{       
        ADC_Handler.Instance=ADC1;
        ADC_Handler.Init.BoostMode=ENABLE;
        ADC_Handler.Init.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV4;                                 //AHB时钟四分频 200m/4=50m(已超频 h743不影响实验)
        ADC_Handler.Init.ContinuousConvMode=ENABLE;                                                          //开启连续模式
        ADC_Handler.Init.ConversionDataManagement=ADC_CONVERSIONDATA_DR;                //数据存放到DR寄存器里
        ADC_Handler.Init.EOCSelection=ADC_EOC_SINGLE_CONV;                                               
        ADC_Handler.Init.ExternalTrigConv=ADC_EXTERNALTRIG_T1_CC1;                                //外部触发方式 ADC_EXTERNALTRIG_T1_CC1
        ADC_Handler.Init.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_NONE;        //外部触发边沿
        ADC_Handler.Init.LeftBitShift=DISABLE;                                                                        //偏移量关闭
        ADC_Handler.Init.LowPowerAutoWait=DISABLE;                                                                //低功耗模式关闭
        ADC_Handler.Init.NbrOfConversion=3;                                                                  //规则序列中有多少个转换 3
        ADC_Handler.Init.DiscontinuousConvMode=DISABLE;                                                 ////不连续采样模式 DISABLE
        ADC_Handler.Init.NbrOfDiscConversion=0;                                                                        //不连续采样通道数 0
        ADC_Handler.Init.Overrun=ADC_OVR_DATA_OVERWRITTEN;
        ADC_Handler.Init.OversamplingMode=DISABLE;
        ADC_Handler.Init.Resolution=ADC_RESOLUTION_16B;                                                        //分辨率 12/10/8/6 位
        ADC_Handler.Init.ScanConvMode=ENABLE;                                                                     //开启扫描模式
        HAL_ADC_Init(&ADC_Handler);
       
       
        ADC_RegularChannelConfig(&ADC_Handler, ADC_CHANNEL_3, ADC_REGULAR_RANK_1, ADC_SAMPLETIME_64CYCLES_5);        //pa6 ADC12通道3
    ADC_RegularChannelConfig(&ADC_Handler, ADC_CHANNEL_7, ADC_REGULAR_RANK_2, ADC_SAMPLETIME_64CYCLES_5);                 //pa7 ADC12通道7
    ADC_RegularChannelConfig(&ADC_Handler, ADC_CHANNEL_14, ADC_REGULAR_RANK_3, ADC_SAMPLETIME_64CYCLES_5);                 //pa2 ADC12通道14
       
        my_dma_Init();                                                                        //调用dma初始化
       
        HAL_ADC_Start_DMA(&ADC_Handler, (u32*)&ADC1ConvertedVoltage, 3);     //开始传输 传输的数据保存到ADC1ConvertedVoltage数组中

}

void  HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
         GPIO_InitTypeDef GPIO_Initure;
        __HAL_RCC_ADC12_CLK_ENABLE();                        //开启ADC12时钟       
        __HAL_RCC_GPIOA_CLK_ENABLE();           //开启GPIOA时钟
        __HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_CLKP); //ADC外设时钟选择

    GPIO_Initure.Pin=GPIO_PIN_7|GPIO_PIN_6|GPIO_PIN_2;    //PA2,PA6,PA7 ()
    GPIO_Initure.Mode=GPIO_MODE_ANALOG;      //模拟输入
    GPIO_Initure.Pull=GPIO_NOPULL;        //无上下拉
    GPIO_Initure.Speed=GPIO_SPEED_FREQ_VERY_HIGH;     //高速
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);
       
        HAL_ADCEx_Calibration_Start(&ADC_Handler,ADC_CALIB_OFFSET,ADC_SINGLE_ENDED); //ADC 校准
}

//规则通道组设置
void ADC_RegularChannelConfig(ADC_HandleTypeDef *AdcHandle, uint32_t Channel, uint32_t Rank, uint32_t SamplingTime)
{
        ADC_ChannelConfTypeDef ADC_ChannelConfig;
               
        ADC_ChannelConfig.Channel=Channel;                                                         //通道选择
        ADC_ChannelConfig.Offset=0;                                                                        //注入通道
        ADC_ChannelConfig.SamplingTime=SamplingTime;                                //采样时间
        ADC_ChannelConfig.Rank=Rank;                                                                //序列号选择
        ADC_ChannelConfig.SingleDiff=ADC_SINGLE_ENDED;
        ADC_ChannelConfig.OffsetSignedSaturation=DISABLE;
        ADC_ChannelConfig.OffsetNumber=0;
        ADC_ChannelConfig.OffsetRightShift= DISABLE;
        HAL_ADC_ConfigChannel(&ADC_Handler, &ADC_ChannelConfig);        //adc通道配置
       
        HAL_ADC_Start(&ADC_Handler);                                                                 //开始转换                       
       
        HAL_ADC_PollForConversion(&ADC_Handler, 10);    //等待转换结束
}

//下面是DMA的设置

//DMAx的各通道配置
//这里的传输形式是固定的,这点要根据不同的情况来修改
//从存储器->外设模式/8位数据宽度/存储器增量模式
void my_dma_Init(void)
{
       
        __HAL_RCC_DMA2_CLK_ENABLE();  //DMA2时钟使能
       
        __HAL_LINKDMA(&ADC_Handler,DMA_Handle,DMA_Handler);  //将DMA与ADC联系起来(发送DMA)
       
        DMA_Handler.Instance=DMA2_Stream1;                                                        //DMA2_Stream1对应ADC1
        DMA_Handler.Init.Direction=DMA_PERIPH_TO_MEMORY;                        //外设到存储器
        DMA_Handler.Init.FIFOMode=DMA_FIFOMODE_DISABLE;                               
        DMA_Handler.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL;               
        DMA_Handler.Init.MemBurst=DMA_MBURST_SINGLE;                                //存储器突发单次传输               
        DMA_Handler.Init.MemDataAlignment=DMA_MDATAALIGN_BYTE;                //存储器数据长度:8位
        DMA_Handler.Init.MemInc=DMA_MINC_ENABLE;                                        //存储器增量模式
        DMA_Handler.Init.Mode=DMA_NORMAL;                                                        //普通模式
        DMA_Handler.Init.PeriphBurst=DMA_PBURST_SINGLE;                                //外设突发单次传输
        DMA_Handler.Init.PeriphDataAlignment=DMA_PDATAALIGN_BYTE;        //外设数据长度:8位
        DMA_Handler.Init.PeriphInc=DMA_PINC_DISABLE;                                //外设非增量模式
        DMA_Handler.Init.Priority=DMA_PRIORITY_MEDIUM;                                //中等优先级
        DMA_Handler.Init.Request=DMA_REQUEST_ADC1;                                //ADC1发送DMA
       
        HAL_DMA_DeInit(&DMA_Handler);
       
        HAL_DMA_Init(&DMA_Handler);
       
       
        HAL_NVIC_EnableIRQ(DMA2_Stream7_IRQn);                                //使能DMA2_Stream7_IRQn中断通道
        HAL_NVIC_SetPriority(DMA2_Stream7_IRQn,0,0);                        //抢占优先级0,子优先级0

}

//中断通用处理函数
void DMA2_Stream7_IRQHandler(void)
{
                HAL_DMA_GetState(&DMA_Handler);
        HAL_DMA_IRQHandler(&DMA_Handler);
}








最佳答案

查看完整内容[请看2#楼]

问题已经解决 配置有些问题 现在已经弄好了 我自己测试了 采集的数据非常准确 代码如下 有需要的可以看下 #include "adc.h" #include "sys.h" #include "dma.h" ADC_HandleTypeDef ADC1_Handle; DMA_HandleTypeDef hdma_adc1; u16 ADC_ConvertedValue[5]; static void ADC_Mode_Config(void) { ADC_ChannelConfTypeDef ADC_Config; my_dma_Init(); ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

10

主题

97

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
486
金钱
486
注册时间
2019-12-6
在线时间
151 小时
 楼主| 发表于 2020-10-8 13:44:02 | 显示全部楼层
本帖最后由 陶佳不哭 于 2023-9-6 00:10 编辑

问题已经解决  配置有些问题 现在已经弄好了 我自己测试了 采集的数据非常准确 代码如下  有需要的可以看下

#include "adc.h"
#include "sys.h"
#include "dma.h"


ADC_HandleTypeDef ADC1_Handle;
DMA_HandleTypeDef hdma_adc1;
u16 ADC_ConvertedValue[5];



static void ADC_Mode_Config(void)
{
    ADC_ChannelConfTypeDef ADC_Config;
      
    my_dma_Init();                                                //DMA初始化 (注意DMA初始化要放在ADC初始化前)
   
    ADC1_Handle.Instance = RHEOSTAT_ADC1;
    ADC1_Handle.Init.BoostMode = ENABLE;                                                        //使能Boost模式
    ADC1_Handle.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;                //ADC时钟4分频
    ADC1_Handle.Init.ContinuousConvMode = ENABLE;                                        //使能连续转换模式
    ADC1_Handle.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR;    //数据存放在数据寄存器中
    ADC1_Handle.Init.DiscontinuousConvMode = DISABLE;                                //关闭不连续转换模式
    ADC1_Handle.Init.EOCSelection = ADC_EOC_SINGLE_CONV;                        //单次转换
    ADC1_Handle.Init.ExternalTrigConv = ADC_SOFTWARE_START;                        //软件触发
    ADC1_Handle.Init.LowPowerAutoWait = DISABLE;                                        //关闭低功耗自动等待
    ADC1_Handle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;                        //数据溢出时,覆盖写入
    ADC1_Handle.Init.OversamplingMode = DISABLE;                                        //不使能过采样模式
    ADC1_Handle.Init.Resolution = ADC_RESOLUTION_16B;                                //分辨率为:16bit
    ADC1_Handle.Init.ScanConvMode = ENABLE;                                                        //使能多通道扫描        
    ADC1_Handle.Init.NbrOfConversion =5;                                                        //扫描三个通道
    HAL_ADC_Init(&ADC1_Handle);                                                                                //初始化 ADC1
         
    //使用通道3
    ADC_Config.Channel = ADC_CHANNEL_3;                        //PA6
    //转换顺序为1
    ADC_Config.Rank = ADC_REGULAR_RANK_1;
    //采样周期为64.5个周期
    ADC_Config.SamplingTime = ADC_SAMPLETIME_64CYCLES_5;
    //不使用差分输入的功能
    ADC_Config.SingleDiff = ADC_SINGLE_ENDED ;        
        //注入通道关闭
        ADC_Config.Offset=0;
    //配置ADC通道
    HAL_ADC_ConfigChannel(&ADC1_Handle, &ADC_Config);   

    //使用通道18
    ADC_Config.Channel = ADC_CHANNEL_18;                        //PA4
    //转换顺序为2
    ADC_Config.Rank = ADC_REGULAR_RANK_2;
    //配置ADC通道
    HAL_ADC_ConfigChannel(&ADC1_Handle, &ADC_Config);
        
        
        //使用通道4
    ADC_Config.Channel = ADC_CHANNEL_4;                        //Pc4
    //转换顺序为3
    ADC_Config.Rank = ADC_REGULAR_RANK_3;        
    //配置ADC通道
    HAL_ADC_ConfigChannel(&ADC1_Handle, &ADC_Config);
        

        //使用通道7
    ADC_Config.Channel = ADC_CHANNEL_7;                        //PA7
    //转换顺序为3
    ADC_Config.Rank = ADC_REGULAR_RANK_4;
    //配置ADC通道
    HAL_ADC_ConfigChannel(&ADC1_Handle, &ADC_Config);
        
        
        //使用通道8
    ADC_Config.Channel = ADC_CHANNEL_8;                        //PC5
    //转换顺序为3
    ADC_Config.Rank = ADC_REGULAR_RANK_5;        
    //配置ADC通道
    HAL_ADC_ConfigChannel(&ADC1_Handle, &ADC_Config);
        

    //使能ADC1
    ADC_Enable(&ADC1_Handle);
   
    HAL_ADC_Start_DMA(&ADC1_Handle, (uint32_t *)ADC_ConvertedValue, 5);
           
}

void  HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
         GPIO_InitTypeDef GPIO_Initure;
        __HAL_RCC_ADC12_CLK_ENABLE();                        //开启ADC12时钟        
        __HAL_RCC_GPIOA_CLK_ENABLE();           //开启GPIOA时钟
        __HAL_RCC_GPIOC_CLK_ENABLE();           //开启GPIOC时钟
        
        __HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_CLKP); //ADC外设时钟选择

    GPIO_Initure.Pin=GPIO_PIN_6|GPIO_PIN_4|GPIO_PIN_7|GPIO_PIN_5;    //PA6,PA4,PA7
    GPIO_Initure.Mode=GPIO_MODE_ANALOG;      //模拟输入
    GPIO_Initure.Pull=GPIO_NOPULL;        //无上下拉
    GPIO_Initure.Speed=GPIO_SPEED_FREQ_VERY_HIGH;     //高速
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);
        
        
         GPIO_Initure.Pin=GPIO_PIN_4|GPIO_PIN_5;
        HAL_GPIO_Init(GPIOC,&GPIO_Initure);
        
        HAL_ADCEx_Calibration_Start(&ADC1_Handle,ADC_CALIB_OFFSET,ADC_SINGLE_ENDED); //ADC 校准
        
        
        HAL_NVIC_EnableIRQ( ADC_IRQn );                                //使能ADC_IRQn中断通道
        HAL_NVIC_SetPriority( ADC_IRQn ,0,0);                        //抢占优先级0,子优先级0
}


//dma配置

void my_dma_Init(void)
{
        __HAL_RCC_DMA1_CLK_ENABLE();
   
    hdma_adc1.Instance = DMA1_Stream1;
    hdma_adc1.Init.Request = DMA_REQUEST_ADC1;
    hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
    hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
    hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
    hdma_adc1.Init.Mode = DMA_CIRCULAR;
    hdma_adc1.Init.Priority = DMA_PRIORITY_LOW;
    hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
        
    if(HAL_DMA_Init(&hdma_adc1) != HAL_OK)
    {}
    __HAL_LINKDMA(&ADC1_Handle,DMA_Handle,hdma_adc1);
}


void ADC_Init(void)
{   
    ADC_Mode_Config();
  
}


C:\Users\Administrator\Pictures

实验十九 ADC多通道选择+DMA+OLED显示.zip

1.6 MB, 下载次数: 0

回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2020-10-9 00:59:26 | 显示全部楼层
帮顶
回复

使用道具 举报

22

主题

2251

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4471
金钱
4471
注册时间
2013-4-22
在线时间
335 小时
发表于 2020-10-10 14:39:03 | 显示全部楼层
自己调试一下看看
回复

使用道具 举报

13

主题

163

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1849
金钱
1849
注册时间
2012-5-19
在线时间
283 小时
发表于 2020-11-11 13:11:35 | 显示全部楼层
陶佳不哭 发表于 2020-10-8 13:44
问题已经解决  配置有些问题 现在已经弄好了 我自己测试了 采集的数据非常准确 代码如下  有需要的可以看下 ...

stm32L1得有没有,我的一直搞不定
回复

使用道具 举报

3

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
59
金钱
59
注册时间
2016-7-20
在线时间
11 小时
发表于 2020-12-7 17:55:18 | 显示全部楼层
我的配置跟你一样,但是我这边的数据根本就不变海盗是ctach的问题吗
回复

使用道具 举报

3

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
59
金钱
59
注册时间
2016-7-20
在线时间
11 小时
发表于 2020-12-7 18:31:23 | 显示全部楼层

原子个我测试的怎么没有数据变化呢
回复

使用道具 举报

3

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
62
金钱
62
注册时间
2021-7-15
在线时间
34 小时
发表于 2021-11-5 07:17:25 | 显示全部楼层
陶佳不哭 发表于 2020-10-8 13:44
问题已经解决  配置有些问题 现在已经弄好了 我自己测试了 采集的数据非常准确 代码如下  有需要的可以看下 ...

楼主有主函数代码吗
回复

使用道具 举报

0

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
50
金钱
50
注册时间
2021-5-3
在线时间
13 小时
发表于 2021-11-8 14:21:24 | 显示全部楼层
6666666666666
回复

使用道具 举报

10

主题

97

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
486
金钱
486
注册时间
2019-12-6
在线时间
151 小时
 楼主| 发表于 2023-9-26 21:27:22 | 显示全部楼层
这是实验代码

实验十九 ADC多通道选择+DMA+OLED显示.zip

1.6 MB, 下载次数: 10

回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-24 05:45

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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