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