OpenEdv-开源电子网

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

用例程采集出来的是对的,但是换了一个通道后就不行了,求大佬们解答解答

[复制链接]

9

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
97
金钱
97
注册时间
2021-2-8
在线时间
43 小时
发表于 2022-3-13 20:10:46 | 显示全部楼层 |阅读模式
10金钱
#include "adc.h"
#include "delay.h"
//////////////////////////////////////////////////////////////////////////////////         
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32H7开发板
//ADC驱动代码          
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2017/8/13
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024
//All rights reserved                                                                          
//////////////////////////////////////////////////////////////////////////////////        

ADC_HandleTypeDef ADC1_Handler;//ADC句柄

//初始化ADC
//ch: ADC_channels
//通道值 0~16取值范围为:ADC_CHANNEL_0~ADC_CHANNEL_16
void MY_ADC_Init(void)
{
    ADC1_Handler.Instance=ADC1;
    ADC1_Handler.Init.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV2;         //4分频,ADCCLK=PER_CK/4=64/4=16MHZ
    ADC1_Handler.Init.Resolution=ADC_RESOLUTION_16B;                   //16位模式
    ADC1_Handler.Init.ScanConvMode=DISABLE;                            //非扫描模式
    ADC1_Handler.Init.EOCSelection=ADC_EOC_SINGLE_CONV;               //关闭EOC中断
                ADC1_Handler.Init.LowPowerAutoWait=DISABLE;                                        //自动低功耗关闭                               
    ADC1_Handler.Init.ContinuousConvMode=DISABLE;               //关闭连续转换
    ADC1_Handler.Init.NbrOfConversion=1;                        //1个转换在规则序列中 也就是只转换规则序列1
    ADC1_Handler.Init.DiscontinuousConvMode=DISABLE;            //禁止不连续采样模式
    ADC1_Handler.Init.NbrOfDiscConversion=0;                    //不连续采样通道数为0
    ADC1_Handler.Init.ExternalTrigConv=ADC_SOFTWARE_START;      //软件触发
    ADC1_Handler.Init.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_NONE;//使用软件触发
                ADC1_Handler.Init.BoostMode=ENABLE;                                                        //BOOT模式关闭
                ADC1_Handler.Init.Overrun=ADC_OVR_DATA_OVERWRITTEN;                        //有新的数据的死后直接覆盖掉旧数据
                ADC1_Handler.Init.OversamplingMode=DISABLE;                                        //过采样关闭
                ADC1_Handler.Init.ConversionDataManagement=ADC_CONVERSIONDATA_DR;  //规则通道的数据仅仅保存在DR寄存器里面
    HAL_ADC_Init(&ADC1_Handler);                                 //初始化
       
                HAL_ADCEx_Calibration_Start(&ADC1_Handler,ADC_CALIB_OFFSET,ADC_SINGLE_ENDED); //ADC校准
}

//ADC底层驱动,引脚配置,时钟使能
//此函数会被HAL_ADC_Init()调用
//hadc:ADC句柄
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
    GPIO_InitTypeDef GPIO_Initure;
    __HAL_RCC_ADC12_CLK_ENABLE();           //使能ADC1/2时钟
    __HAL_RCC_GPIOC_CLK_ENABLE();                        //开启GPIOA时钟
        __HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_CLKP); //ADC外设时钟选择
       
    GPIO_Initure.Pin=GPIO_PIN_1;            //PC1
    GPIO_Initure.Mode=GPIO_MODE_ANALOG;     //模拟
    GPIO_Initure.Pull=GPIO_NOPULL;          //不带上下拉
    HAL_GPIO_Init(GPIOC,&GPIO_Initure);
}

//获得ADC值
//ch: 通道值 0~16,取值范围为:ADC_CHANNEL_0~ADC_CHANNEL_16
//返回值:转换结果
u16 Get_Adc(u32 ch)   
{
    ADC_ChannelConfTypeDef ADC1_ChanConf;

    ADC1_ChanConf.Channel=ch;                                   //通道
    ADC1_ChanConf.Rank=ADC_REGULAR_RANK_1;                          //1个序列
    ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_64CYCLES_5;              //采样时间      
                ADC1_ChanConf.SingleDiff=ADC_SINGLE_ENDED;                                  //单边采集                         
                ADC1_ChanConf.OffsetNumber=ADC_OFFSET_NONE;                    
                ADC1_ChanConf.Offset=0;   
    HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf);        //通道配置

    HAL_ADC_Start(&ADC1_Handler);                               //开启ADC
       
    //HAL_ADC_PollForConversion(&ADC1_Handler,10);                //轮询转换
        return (u16)HAL_ADC_GetValue(&ADC1_Handler);                    //返回最近一次ADC1规则组的转换结果
}
//获取指定通道的转换值,取times次,然后平均
//times:获取次数
//返回值:通道ch的times次转换结果平均值
u16 Get_Adc_Average(u32 ch,u8 times)
{
        u32 temp_val=0;
        u8 t;
        for(t=0;t<times;t++)
        {
                temp_val+=Get_Adc(ch);
                delay_ms(5);
        }
        return temp_val/times;
}
/****************************************************/
/****************************************************/
                        adcx=Get_Adc_Average(ADC_CHANNEL_10,20);//获取通道19的转换值,20次取平均
                        temp=(float)adcx*(3.3/65536);         //获取计算后的带小数的实际电压值,比如3.1111
                        u3_printf("%6.3f\r\n",temp);



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

使用道具 举报

9

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
97
金钱
97
注册时间
2021-2-8
在线时间
43 小时
 楼主| 发表于 2022-3-13 20:23:24 | 显示全部楼层
本帖最后由 刘文意 于 2022-3-13 20:26 编辑

例程里面甚至都不用引脚配置,只需要ADC的时钟配置,我注释掉引脚配置以后也可以测出来,我直接凌乱了,求大佬解解惑//ADC底层驱动,引脚配置,时钟使能
//此函数会被HAL_ADC_Init()调用
//hadc:ADC句柄
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
    GPIO_InitTypeDef GPIO_Initure;
    __HAL_RCC_ADC12_CLK_ENABLE();           //使能ADC1/2时钟
    //__HAL_RCC_GPIOC_CLK_ENABLE();                        //开启GPIOA时钟
          __HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_CLKP); //ADC外设时钟选择
        
//    GPIO_Initure.Pin=GPIO_PIN_1;            //PC1
//    GPIO_Initure.Mode=GPIO_MODE_ANALOG;     //模拟
//    GPIO_Initure.Pull=GPIO_NOPULL;          //不带上下拉
    HAL_GPIO_Init(GPIOC,&GPIO_Initure);
}



回复

使用道具 举报

0

主题

668

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1926
金钱
1926
注册时间
2021-8-13
在线时间
262 小时
发表于 2022-3-14 09:40:42 | 显示全部楼层
帮顶   
回复

使用道具 举报

3

主题

74

帖子

0

精华

初级会员

Rank: 2

积分
188
金钱
188
注册时间
2021-12-22
在线时间
34 小时
发表于 2022-3-14 11:04:32 | 显示全部楼层
因为不同的ADC通道有不同的引脚,你可以看一下你想设置的通道对应的引脚,然后在HAL_ADC_Init()改一下。
回复

使用道具 举报

11

主题

2131

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4728
金钱
4728
注册时间
2015-1-10
在线时间
590 小时
发表于 2022-3-14 13:39:01 | 显示全部楼层
GPIO上电后默认是模拟输入,因此只需要设置GPIO时钟即可,换通道需要GPIO与ADC_channel对应
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-26 00:26

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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