久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3516|回復: 3
打印 上一主題 下一主題
收起左側

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

[復制鏈接]
跳轉到指定樓層
樓主
ID:418006 發表于 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();                //顯示設置界面
        }
}

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:388197 發表于 2019-6-4 00:33 | 只看該作者

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

使用道具 舉報

板凳
ID:511890 發表于 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文件中的函數,應該是進行模擬量的分貝值采集然后進行模數轉換,將分貝值轉換成數字量。
回復

使用道具 舉報

地板
ID:305511 發表于 2019-6-4 13:06 | 只看該作者
注釋的挺詳細的啊!
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 高清欧美性猛交xxxx黑人猛交 | 国产精品中文在线 | 日韩在线观看一区 | 日韩精品一区在线 | 欧美高清视频一区 | 亚洲免费在线 | 国产一区二区三区色淫影院 | 特级特黄特色的免费大片 | 成人福利在线视频 | 欧美成人免费在线 | 国产精品伦一区二区三级视频 | 天天澡天天狠天天天做 | 日本黄色高清视频 | 香蕉久久久久久 | 国产一区二区三区色淫影院 | 91网站在线播放 | 亚洲一区二区免费 | 欧美一级二级视频 | 在线观看亚洲专区 | 天堂一区二区三区四区 | 免费在线观看一区二区三区 | 国产偷录叫床高潮录音 | 日韩伦理一区二区三区 | 在线一区视频 | 四虎海外| 欧美视频一区二区三区 | 亚州一区二区三区 | 激情五月婷婷综合 | 欧美一级做性受免费大片免费 | 亚洲精品久久久一区二区三区 | 亚洲精品视频导航 | 免费二区| 在线观看中文字幕一区二区 | 天堂一区二区三区 | 日韩av在线中文字幕 | h视频在线免费 | 久久久久久久久久久久久久久久久久久久 | 天堂亚洲 | 精品福利视频一区二区三区 | 欧美a v在线 | 亚洲精品在线免费观看视频 |