数码之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 196|回复: 4

[C51] 分享STC32G8K64的一份ADC转换数字滤波代码

[复制链接]
发表于 前天 12:01 | 显示全部楼层 |阅读模式

爱科技、爱创意、爱折腾、爱极致,我们都是技术控

您需要 登录 才可以下载或查看,没有账号?立即注册

x


因为成本,渠道,代码风格,ADC特性等原因从RISV-V回归到STC芯片,喜欢其极简风格的寄存器赋值代码,以下是ADC转换的数字滤波代码,分享给有兴趣的坛友.
我是半路出家的代码搬运者很多算法类都是参照前辈的代码自己修改,也不敢说代码没有瑕疵或bug,只是目前调试还算正常,献丑了高手请轻拍,谢谢!
说起来对于小电路开发我更有信心说原创...


1: 代码中ADC的初始化只用了3行专用指令,其它共同类配置(如: IO状态 )都包含在其他函数中.
2: ADC正式转换前先模拟转换3次不取值,这是前辈们的经验,毕竟刚切换到当前通道,稳定点为好.
3: 取值10次并使用冒泡排序法整形数组一字排列.
4: 只取样数组排序后第4到第7个值计算均值,项目对直流信号转换的时效性要求不高所以掐头去尾,就算有误读值也不影响结果.


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include "main.h"      //简化程序架构,函数声明在同一个头文件方便任意调用.

u32 temp_adc[10] , temp = 0;

//========================================================================
// 函数: void Adc_Init(void)
// 描述: STC32G8K64的ADC模块初始化.
// 参数: void.
// 返回: void.
//========================================================================
void Adc_Init(void)         //  ADC初始化
{

    ADCTIM = 0x3f;      //设置 ADC 内部时序,ADC采样时间建议设最大值
    ADCCFG = 0x2f;      //设置 ADC 转换结果右对齐,时钟为系统时钟/2/16
    ADC_CONTR = 0x84;   //使能 ADC 模块

}

//========================================================================
// 函数: u16 Get_ADC12bitResult(u8 channel)
// 描述: 查询法读十次ADC结果并排序选择中间4位计算均值.
// 参数: channel: 选择要转换的ADC, 0~15.
// 返回: 12位ADC计算后的结果.
//========================================================================
u32        Get_ADC12bitResult(u8 channel)        //channel = 0~15
{
    u8 i , x = 0 , y = 0 , swapflag = 0;

    for(i = 0 ; i < 3 ; i ++)         //ADC读3次空值
    {
        ADC_CONTR = (ADC_CONTR & 0xF0) | 0x40 | channel;    //启动 AD 转换

        while((ADC_CONTR & 0x20) == 0);   //等待ADC结束

        ADC_CONTR &= ~0x20;     //清除ADC结束标志

    }

    for(i = 0 ; i < 10 ; i ++)      //转换10次存数组
    {
        ADC_RES = 0;
        ADC_RESL = 0;
        ADC_CONTR = (ADC_CONTR & 0xF0) | 0x40 | channel;    //启动 AD 转换

        while((ADC_CONTR & 0x20) == 0);   //等待ADC结束

        ADC_CONTR &= ~0x20;     //清除ADC结束标志
        temp_adc = (((u16)ADC_RES << 8) | ADC_RESL) ; //读取ADC数据

    }

    for ( x = 0; x < 9; x++)
    {

        swapflag = 0 ;         //轮询OK标志位

        for ( y = 0; y < 10 - x - 1; y++)      //轮询
        {
            if (temp_adc[y] > temp_adc[y + 1])    //判断交换
            {
                temp = temp_adc[y];
                temp_adc[y] = temp_adc[y + 1];
                temp_adc[y + 1] = temp;
                swapflag = 1;
            }
        }

        if (!swapflag) break;  // 已有序退出轮询

    }

    temp = 0 ;

    for(i = 4 ; i < 8 ; i ++)     //取样4-7 的值累加,抛弃头尾各3个值     
    {

        temp += temp_adc ;

    }

    return (( temp * 1250U ) / 4096U );    //计算十进制值(1250为5V基准/4次值)

}








打赏

参与人数 2家元 +39 收起 理由
慕名而来 + 24 原創內容
不长叶子的树 + 15

查看全部打赏

发表于 前天 14:05 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

发表于 前天 16:52 | 显示全部楼层
游客请登录后查看回复内容

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复 支持 反对

使用道具 举报

发表于 前天 17:04 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

发表于 前天 21:21 来自手机浏览器 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

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

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|数码之家-技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2026-7-16 17:03 , Processed in 0.296400 second(s), 11 queries , Gzip On, Redis On.

Powered by Discuz!

© MyDigit.Net Since 2006

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