找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

帖子
查看: 3534|回復(fù): 3
收起左側(cè)

單片機(jī)程序中的計算分貝值的算法看不太懂,大神幫幫忙講解一下

[復(fù)制鏈接]
ID:418006 發(fā)表于 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; //設(shè)置鍵
sbit key_jia  =P1^1; //加值鍵
sbit key_jian =P1^2; //減值鍵

/************************變量定義************************/
uchar db_up;                 //分貝限值
bit set_f=0;                 //設(shè)置變量,=0正常測量,=1處于設(shè)置分貝限值

uint ad=0;                          //存儲AD轉(zhuǎn)換值
double VCC=500;             //存儲系統(tǒng)電源電壓,放大100倍
double V;                 //存儲當(dāng)前所測電壓
double low_V;                 //存儲上一次所測電壓

uchar db;                 //存儲當(dāng)前所測分貝
/********************************************************
函數(shù)名稱:void delayms(uint ms)
函數(shù)作用:毫秒延時函數(shù)
參數(shù)說明:ms為延時的毫秒數(shù)
********************************************************/
void delayms(uint ms)
{
        uchar i=100,j;
        for(;ms;ms--)
        {
                while(--i)
                {
                        j=10;
                        while(--j);
                }
        }
}

/*********************************************************
函數(shù)名稱:void display()
函數(shù)作用:正常顯示函數(shù)
參數(shù)說明:
*********************************************************/
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)  //實(shí)測值大于設(shè)置值
        {
                ledr=0;          //紅色指示燈亮
                ledg=1;
        }
        else                  //否則處于正常
        {
                ledr=1;
                ledg=0;          //綠色指示燈亮
        }                                    
}
/*********************************************************
函數(shù)名稱:void display2()
函數(shù)作用:顯示設(shè)置分貝提示限值函數(shù)
參數(shù)說明:
*********************************************************/
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");                                    
}
/*********************************************************
函數(shù)名稱:void scan()
函數(shù)作用:按鍵檢測處理
參數(shù)說明:
*********************************************************/
void scan()
{
        //設(shè)置鍵
        if(key_she==0)                                        //按鍵按下
        {
                delayms(7);                                        //延時消抖
                if(key_she==0)                                //再次判斷按鍵是否按下
                {
                        set_f=~set_f;                        //切換設(shè)置和正常測量
                        if(set_f==0)                        //如果設(shè)置完成
                                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--;
                }
        }
}
/*********************************************************
函數(shù)名稱:db_count()
函數(shù)作用:計算分貝值
參數(shù)說明:
*********************************************************/

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;                 //根據(jù)電壓對應(yīng)計算分貝值
}
/*********************************************************
函數(shù)名稱:void main()
函數(shù)作用:主函數(shù)
參數(shù)說明:
*********************************************************/
void main()
{
        uint i=0;       //存儲采集次數(shù)
        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)                //死循環(huán)
        {        
                scan();                                //按鍵檢測與處理
                if(set_f==0)                //正常顯示
                {
                        i++;            //循環(huán)次數(shù)+1
                        ad+=ADC0832_read(0);//讀取AD值,并累加記錄到ad上
                        
                        if(i>=100)                //每采集100次計算一次分貝值
                        {
                                i=0;                //重置計數(shù)變量

                                db_count(); //計算分貝
                                display();  //顯示分貝        

                                ad=0;            //重置ad值
                        }
                        delay_n40us(80);
                }
                else                                //否則,處于設(shè)置模式
                        display2();                //顯示設(shè)置界面
        }
}

回復(fù)

使用道具 舉報

ID:388197 發(fā)表于 2019-6-4 00:33 | 顯示全部樓層

DB的定義是個以10為底的對數(shù),比如1000換成DB就是 20*lg1000=60.
所以說正常計算的話,怎么樣都要包含MATH.H
而程序里 db=35+V/4.0
這個應(yīng)該是輸入模擬量的器件(比如傳感器)為了使用方便,已經(jīng)做了線性處理的,電壓值跟DB值是線性關(guān)系.一般這種公式在該器件的說明書里能找到.
回復(fù)

使用道具 舉報

ID:511890 發(fā)表于 2019-6-4 02:44 | 顯示全部樓層

     if(set_f==0)                //正常顯示
    {
          i++;            //循環(huán)次數(shù)+1
          ad+=ADC0832_read(0);//讀取AD值,并累加記錄到ad上                        
          if(i>=100)                //每采集100次計算一次分貝值
          {
               i=0;                //重置計數(shù)變量
              db_count(); //計算分貝
              display();  //顯示分貝        
              ad=0;            //重置ad值
         }
set_f=0,即正常測量的時候 adwhile每次循環(huán)采集一次實(shí)時分貝值(通過ADC0832轉(zhuǎn)換獲得)。等采集累積到100個值的時候調(diào)用db_count()計算分貝值(主要是濾波,取100個值的平均值),計算好平均分貝值后,調(diào)用display()進(jìn)行顯示。然后ad清零,i清零重新采集實(shí)時分貝值。ADC0832_read(0)是在另一個.c文件中的函數(shù),應(yīng)該是進(jìn)行模擬量的分貝值采集然后進(jìn)行模數(shù)轉(zhuǎn)換,將分貝值轉(zhuǎn)換成數(shù)字量。
回復(fù)

使用道具 舉報

ID:305511 發(fā)表于 2019-6-4 13:06 | 顯示全部樓層
注釋的挺詳細(xì)的��!
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表