OpenEdv-开源电子网

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

ADC多通道采样,增加滤波算法后,得到的电压值比实际值要小

[复制链接]

10

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2021-4-12
在线时间
16 小时
发表于 2023-3-17 09:25:28 | 显示全部楼层 |阅读模式
1金钱
ADC多通道采样,增加滤波算法后,得到的电压值比实际值要小
u16 AD_HEX[10][3];
float AD_Value[3];

adc.c文件
/*******************************************************************************
* 函 数 名         : ADCx_Init
* 函数功能                   : ADC初始化       
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void ADCx_Init(void)
{
    //定义结构体变量
        GPIO_InitTypeDef GPIO_InitStructure;
        ADC_InitTypeDef ADC_InitStructure;
    DMA_InitTypeDef DMA_InitStructure;
       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_ADC1,ENABLE);
       
    //打开DMA时钟
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

    // 复位DMA控制器
    DMA_DeInit(DMA1_Channel1);

    // 配置 DMA 初始化结构体
        // 外设基址为:ADC 数据寄存器地址
    DMA_InitStructure.DMA_PeripheralBaseAddr = ( u32 ) ( & ( ADC1->DR ) );

    // 存储器地址,实际上就是一个内部SRAM的变量
        DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&AD_HEX;

        // 数据源来自外设
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
       
        //数据数
        DMA_InitStructure.DMA_BufferSize = 30;
       
        // 外设寄存器只有一个,地址不用递增
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

        // 存储器地址固定
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
       
        // 外设数据大小为半字,即两个字节
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
       
        // 内存数据大小也为半字,跟外设数据大小相同
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
       
        // 循环传输模式
        DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;       

        // DMA 传输通道优先级为高,当使用一个DMA通道时,优先级设置不影响
        DMA_InitStructure.DMA_Priority = DMA_Priority_High;
       
        // 禁止存储器到存储器模式,因为是从外设到存储器
        DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
       
        // 初始化DMA
        DMA_Init(DMA1_Channel1, &DMA_InitStructure);
       
        // 使能 DMA 通道
        DMA_Cmd(DMA1_Channel1 , ENABLE);

        RCC_ADCCLKConfig(RCC_PCLK2_Div6);//设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M
       
        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0 | GPIO_Pin_1;//ADC
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;        //模拟输入
        GPIO_Init(GPIOA,&GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;//ADC
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;        //模拟输入
        GPIO_Init(GPIOB,&GPIO_InitStructure);

    ADC_DeInit(ADC1);  //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值
       
        ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
        ADC_InitStructure.ADC_ScanConvMode = ENABLE;//非扫描模式***ENABLE//多通道扫描模式       
        ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//关闭连续转换***ENABLE//连续转换模式
        ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//禁止触发检测,使用软件触发
        ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐       
        ADC_InitStructure.ADC_NbrOfChannel = 3;//顺序进行规则转换的ADC通道的数目
        ADC_Init(ADC1, &ADC_InitStructure);//ADC初始化

    ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5);//PA0;ADC1,ADC通道,239.5个周期,提高采样时间可以提高精确度
    ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_239Cycles5);//PA1
    ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 3, ADC_SampleTime_239Cycles5);//PB0
       
        ADC_Cmd(ADC1, ENABLE);//开启AD转换器

    // 使能ADC DMA 请求
        ADC_DMACmd(ADC1, ENABLE);
       
        ADC_ResetCalibration(ADC1);//重置指定的ADC的校准寄存器
        while(ADC_GetResetCalibrationStatus(ADC1));//获取ADC重置校准寄存器的状态
       
        ADC_StartCalibration(ADC1);//开始指定ADC的校准状态
        while(ADC_GetCalibrationStatus(ADC1));//获取指定ADC的校准程序

        ADC_SoftwareStartConvCmd(ADC1, ENABLE);//使能或者失能指定的ADC的软件转换启动功能
}



void Get_AD_Value()
{
        u8 i;
        u8 num;
        u16 sum;
        float val;
        for(num=0;num<3;num++)
        {
                sum = 0;
                for(i=0;i<10;i++)
                {
                        sum +=  AD_HEX[i][num];               
                }
                val = sum/10;
        sum = 0;
                AD_Value[num] = val*3/4095;
        }
}



main.c函数
int main()
{

    SysTick_Init(72);//时钟初始化
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //中断优先级分组 分2组
    ledInit();
    USART1_Init(9600);//串口初始化
    ADCx_Init();



    while(1)
    {

        Get_AD_Value();

        printf("检测vol[0]电压值为:%.2fV\r\n",AD_Value[0]);

        printf("检测vol[1]电压值为:%.2fV\r\n",AD_Value[1]);

        printf("检测vol[2]电压值为:%.2fV\r\n",AD_Value[2]);

        delay_ms(1000);

    }
}

最佳答案

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

是的,参考电压是3.3,已经解决了,感谢大佬
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

10

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2021-4-12
在线时间
16 小时
 楼主| 发表于 2023-3-17 09:25:29 | 显示全部楼层
szczyb1314 发表于 2023-3-17 10:30
AD_Value[num] = val*3/4095;  
1.参考电压是3V还是3.3V?要是3.3V就公式已经错了
2.3.3V参考电压的话:AD ...

是的,参考电压是3.3,已经解决了,感谢大佬
回复

使用道具 举报

7

主题

480

帖子

0

精华

高级会员

Rank: 4

积分
771
金钱
771
注册时间
2021-4-15
在线时间
304 小时
发表于 2023-3-17 09:45:57 | 显示全部楼层
你几位的ADC 你变量会溢出吗
日常敲键--头秃一片
回复

使用道具 举报

10

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2021-4-12
在线时间
16 小时
 楼主| 发表于 2023-3-17 10:23:32 | 显示全部楼层
日渐秃兀 发表于 2023-3-17 09:45
你几位的ADC 你变量会溢出吗

3位,变量没溢出
回复

使用道具 举报

26

主题

1538

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6376
金钱
6376
注册时间
2015-8-25
在线时间
1004 小时
发表于 2023-3-17 10:30:39 | 显示全部楼层
AD_Value[num] = val*3/4095;  
1.参考电压是3V还是3.3V?要是3.3V就公式已经错了
2.3.3V参考电压的话:AD_Value[num] = val*3.3/4096;    《==3.3V被分成了0-4095共4096份  
He who fights with monsters should look to it that he himself does not become a monster, when you gaze long into the abyss, the abyss also gazes into you.
过于执着就会陷入其中,迷失自己,困住自己。
回复

使用道具 举报

15

主题

36

帖子

0

精华

初级会员

Rank: 2

积分
76
金钱
76
注册时间
2023-3-20
在线时间
26 小时
发表于 2023-3-20 20:31:22 | 显示全部楼层
DMA_InitStructure.DMA_BufferSize = 30;这个为啥是30呀
回复

使用道具 举报

4

主题

36

帖子

0

精华

初级会员

Rank: 2

积分
196
金钱
196
注册时间
2021-10-23
在线时间
21 小时
发表于 2023-5-22 16:48:30 | 显示全部楼层
哥,方便加个联系方式吗?有问题想向你请教一下   yshlwsyyj
回复

使用道具 举报

28

主题

360

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1027
金钱
1027
注册时间
2021-2-4
在线时间
146 小时
发表于 2023-5-24 09:41:33 | 显示全部楼层
三百七十睡不醒 发表于 2023-3-20 20:31
DMA_InitStructure.DMA_BufferSize = 30;这个为啥是30呀

这个没为什么
只是用户自己定义的一个大小而已
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-24 09:13

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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