***************************************************************/
#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(); //顯示設置界面
}
}
|