|
|
爱科技、爱创意、爱折腾、爱极致,我们都是技术控
您需要 登录 才可以下载或查看,没有账号?立即注册
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次值)
}
|
打赏
-
查看全部打赏
|