标题:
单片机程序中的计算分贝值的算法看不太懂,大神帮帮忙讲解一下
[打印本页]
作者:
天狼星666
时间:
2019-6-3 17:19
标题:
单片机程序中的计算分贝值的算法看不太懂,大神帮帮忙讲解一下
***************************************************************/
#include<reg52.h> //头文件
#include<LCD1602.h>
#include<ADC0832.h>
#include<AT24C02.h>
/************************引脚定义************************/
sbit ledr =P1^3; //红色LED灯
sbit ledg =P1^5; //绿色LED灯
sbit key_she =P1^0; //设置键
sbit key_jia =P1^1; //加值键
sbit key_jian =P1^2; //减值键
/************************变量定义************************/
uchar db_up; //分贝限值
bit set_f=0; //设置变量,=0正常测量,=1处于设置分贝限值
uint ad=0; //存储AD转换值
double VCC=500; //存储系统电源电压,放大100倍
double V; //存储当前所测电压
double low_V; //存储上一次所测电压
uchar db; //存储当前所测分贝
/********************************************************
函数名称:void delayms(uint ms)
函数作用:毫秒延时函数
参数说明:ms为延时的毫秒数
********************************************************/
void delayms(uint ms)
{
uchar i=100,j;
for(;ms;ms--)
{
while(--i)
{
j=10;
while(--j);
}
}
}
/*********************************************************
函数名称:void display()
函数作用:正常显示函数
参数说明:
*********************************************************/
void display()
{
lcd1602_write_character(0,1," Decibel: ");
LCD_disp_char(10,1,ASCII[db/100]); //显示分贝值
LCD_disp_char(11,1,ASCII[db%100/10]);
LCD_disp_char(12,1,ASCII[db%10]);
lcd1602_write_character(13,1,"db"); //显示【db】
lcd1602_write_character(2,2,"TC:"); // ()SSN UN IN
//lcd1602_write_character(8,2," FC:LFN"); // IFN HFN
if(db>db_up) //实测值大于设置值
{
ledr=0; //红色指示灯亮
ledg=1;
}
else //否则处于正常
{
ledr=1;
ledg=0; //绿色指示灯亮
}
}
/*********************************************************
函数名称:void display2()
函数作用:显示设置分贝提示限值函数
参数说明:
*********************************************************/
void display2()
{
lcd1602_write_character(0,1,"Set decibe limit");
LCD_disp_char(5,2,ASCII[db_up/100]);
LCD_disp_char(6,2,ASCII[db_up%100/10]);
LCD_disp_char(7,2,ASCII[db_up%10]);
lcd1602_write_character(8,2,"db");
}
/*********************************************************
函数名称:void scan()
函数作用:按键检测处理
参数说明:
*********************************************************/
void scan()
{
//设置键
if(key_she==0) //按键按下
{
delayms(7); //延时消抖
if(key_she==0) //再次判断按键是否按下
{
set_f=~set_f; //切换设置和正常测量
if(set_f==0) //如果设置完成
AT24C02_write_date(0,db_up);//存储【分贝】限值
LCD_write_command(0x01);//清除屏幕显示
delay_n40us(100); //等待清除完成
}
while(!key_she); //等待按键松开
}
//加键
if(key_jia==0&&set_f!=0)
{
delayms(7);
if(key_jia==0)
{
if(db_up<100)
db_up++;
}
}
//减键
if(key_jian==0&&set_f!=0)
{
delayms(7);
if(key_jian==0)
{
if(db_up>1)
db_up--;
}
}
}
/*********************************************************
函数名称:db_count()
函数作用:计算分贝值
参数说明:
*********************************************************/
void db_count()
{
ad=ad/100; //采集100次ad值后计算平均值,均值滤波
V=VCC*ad/255.0; //计算所测电压, V/ad=VCC/255
low_V=(low_V+V)/2; //与上一次测量电压值求平均值
low_V=V; //记录分贝电压值
db=35+V/4.0; //根据电压对应计算分贝值
}
/*********************************************************
函数名称:void main()
函数作用:主函数
参数说明:
*********************************************************/
void main()
{
uint i=0; //存储采集次数
if(key_jian==0)
{
delayms(100);
if(key_jian==0)
AT24C02_write_date(0,60);//存储【分贝】限值
}
db_up=AT24C02_read_date(0);//先读取存储的【分贝限值】
LCD_init(); //初始化液晶
while(1) //死循环
{
scan(); //按键检测与处理
if(set_f==0) //正常显示
{
i++; //循环次数+1
ad+=ADC0832_read(0);//读取AD值,并累加记录到ad上
if(i>=100) //每采集100次计算一次分贝值
{
i=0; //重置计数变量
db_count(); //计算分贝
display(); //显示分贝
ad=0; //重置ad值
}
delay_n40us(80);
}
else //否则,处于设置模式
display2(); //显示设置界面
}
}
作者:
cjm82
时间:
2019-6-4 00:33
DB的定义是个以10为底的对数,比如1000换成DB就是 20*lg1000=60.
所以说正常计算的话,怎么样都要包含MATH.H
而程序里 db=35+V/4.0
这个应该是输入模拟量的器件(比如传感器)为了使用方便,已经做了线性处理的,电压值跟DB值是线性关系.一般这种公式在该器件的说明书里能找到.
作者:
幻剑心
时间:
2019-6-4 02:44
if(set_f==0) //正常显示
{
i++; //循环次数+1
ad+=ADC0832_read(0);//读取AD值,并累加记录到ad上
if(i>=100) //每采集100次计算一次分贝值
{
i=0; //重置计数变量
db_count(); //计算分贝
display(); //显示分贝
ad=0; //重置ad值
}
set_f=0,即正常测量的时候 adwhile每次循环采集一次实时分贝值(通过ADC0832转换获得)。等采集累积到100个值的时候调用db_count()计算分贝值(主要是滤波,取100个值的平均值),计算好平均分贝值后,调用display()进行显示。然后ad清零,i清零重新采集实时分贝值。ADC0832_read(0)是在另一个.c文件中的函数,应该是进行模拟量的分贝值采集然后进行模数转换,将分贝值转换成数字量。
作者:
太阳黑子1
时间:
2019-6-4 13:06
注释的挺详细的啊!
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1