摘要
本次设计利用单片机、光学传感器、ADC、蜂鸣器等设计了一个声光报警装置。
采用PCF8591接收光照强度,并发送到数码管的后四位进行动态刷新显示,实现动态监测光强;
当光强超出安全范围(自行设定的光强上下阈值)时,实现报警功能,报警分为声光两部分,蜂鸣器发出声音(警笛鸣叫),流水灯实现警灯闪烁。
还有按键功能,按键S7选中光强上限,按键S6选中光强下限,S5\S4对光强上/下限进行修改:加10/减10功能;同时在数码管的前四位显示光强上限及光强下限的数值。
以及掉电保存,当关闭电源,重新打开后,可记忆光强上下限上次修改后的数值,采用AT24C02(EEPROM)进行掉电保存。
代码
AT2402.c
#include "AT24C02.h"
void delay_24(unsigned int i)
{
while(i--)
;
}
void write_24C02(unsigned char adrr,unsigned char dat)//单字节写入
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(adrr);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
unsigned char read_24C02(unsigned char adrr)//单字节读出
{
unsigned char dat;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(adrr);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
dat=IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
return dat;
}
main函数
#include "iic.h"
#include<STC15.h>
#include<intrins.h>
#include"AT24C02.h"
sbit HC138_A=P2^5;
sbit HC138_B=P2^6;
sbit HC138_C=P2^7;
//按键定义
sbit key_max=P3^0; //s7
sbit key_min=P3^1; //s6
sbit key_add=P3^2; //s5
sbit key_sub=P3^3; //s4
unsigned int light_max=200;
unsigned int light_min=50;
unsigned char key4_last=1;
unsigned char dis_buff[4];
unsigned char dis_buff0[4];
unsigned char dis_buff1[4];
unsigned char seg_code[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char table[] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};
unsigned char mode=0;
unsigned char flag=0;
void delay(unsigned char k)
{
unsigned char i,j;
for(;k>0;k--)
for(i=0;i<10;i++)
for(j=0;j<48;j++);
}
void led(void)
{
unsigned char i;
HC138_C=1;
HC138_B=0;
HC138_A=0;
if(mode==1)
{
for(i=0;i<3;i++)
{
P0=0x00;
delay(60000);
delay(60000);
P0=0xff;
delay(60000);
delay(60000);
}
for(i=0;i<=8;i++)
{
P0=0xff<<i;
delay(60000);
delay(60000);
}
for(i=0;i<=8;i++)
{
P0=~(0xff<<i);
delay(60000);
delay(60000);
}
}
}
unsigned char PCF8591_Read()
{
unsigned char temp;
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
temp=IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
return temp;
}
void PCF8591_Init()
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x01);
IIC_WaitAck();
IIC_Stop();
}
void display()
{
unsigned char i;
unsigned int dat=1;
for(i=0;i<4;i++)
{
P0=0x00;
P2=(P2&0x1f)|0xc0;
P2=(P2&0x1f)|0x00;
P0=seg_code[dis_buff[i]];
P2=(P2&0x1f)|0xe0;
P2=(P2&0x1f)|0x00;
P0=0x01<<(7-i);
P2=(P2&0x1f)|0xc0;
P2=(P2&0x1f)|0x00;
delay(1);
}
}
void display_max()
{
unsigned char i;
unsigned int dat=1;
for(i=0;i<4;i++)
{
P0=0x00;
P2=(P2&0x1f)|0xc0;
P2=(P2&0x1f)|0x00;
P0=seg_code[dis_buff0[i]];
P2=(P2&0x1f)|0xe0;
P2=(P2&0x1f)|0x00;
P0=0x01<<(3-i);
P2=(P2&0x1f)|0xc0;
P2=(P2&0x1f)|0x00;
delay(1);
}
}
void display_min()
{
unsigned char i;
unsigned int dat=1;
for(i=0;i<4;i++)
{
P0=0x00;
P2=(P2&0x1f)|0xc0;
P2=(P2&0x1f)|0x00;
P0=seg_code[dis_buff1[i]];
P2=(P2&0x1f)|0xe0;
P2=(P2&0x1f)|0x00;
P0=0x01<<(3-i);
P2=(P2&0x1f)|0xc0;
P2=(P2&0x1f)|0x00;
delay(1);
}
}
void sys_init(void)
{
P0=0xff;
P2=(P2&0x1f)|0x80;
P2=(P2&0x1f)|0x00;
P0=0x00;
P2=(P2&0x1f)|0xa0;
P2=(P2&0x1f)|0x00;
}
void baojing(void)
{
if(mode==1)
{
P0=0x40;
P2=0xa0;
P2=0x00;
}
else
{
P0=0x00;
P2=0xa0;
P2=0x00;
}
}
void keyscan(void) //按键函数
{
if(key_max==0) //
{
delay(10);
if(key_max==0)
{
flag=0;
while(!key_max)
{
display_max();
display();
}
}
}
if(key_min==0) //
{
delay(10);
if(key_min==0)
{
flag=1;
while(!key_min)
{
display_min();
display();
}
}
}
if(key_add==0)
{
delay(10);
if(key_add==0 && flag==0)
{
light_max=light_max+10;
write_24C02(0x00,light_max);//单字节写入
delay(10);
while(!key_add)
{
display_max();
display();
}
}
if(key_add==0 && flag==1)
{
light_min=light_min+10;
write_24C02(0xa0,light_min);//单字节写入
delay(10);
while(!key_add)
{
display_min();
display();
}
}
}
if(key_sub==0)
{
delay(10);
if(key_sub==0 && flag==0)
{
light_max=light_max-10;
write_24C02(0x00,light_max);//单字节写入
delay(10);
while(!key_sub)
{
display_max();
display();
}
}
if(key_sub==0 && flag==1)
{
light_min=light_min-10;
write_24C02(0xa0,light_min);//单字节写入
delay(10);
while(!key_sub)
{
display_min();
display();
}
}
}
}
void main()
{
unsigned char light_val;
sys_init();
PCF8591_Init();
light_max=read_24C02(0x00);//单字节读出
light_min=read_24C02(0xa0);
while(1)
{
keyscan();
light_val=PCF8591_Read();
if(light_val>=light_max||light_val<=light_min)
{
mode=1;
}
else
mode=0;
baojing();
led();
dis_buff[3]=light_val/1000;
dis_buff[2]=light_val%1000/100;
dis_buff[1]=light_val%100/10;
dis_buff[0]=light_val%10;
dis_buff0[3]=light_max/1000;
dis_buff0[2]=light_max%1000/100;
dis_buff0[1]=light_max%100/10;
dis_buff0[0]=light_max%10;
dis_buff1[3]=light_min/1000;
dis_buff1[2]=light_min%1000/100;
dis_buff1[1]=light_min%100/10;
dis_buff1[0]=light_min%10;
display();
}
}
iic.c
#include "reg52.h"
#include "intrins.h"
#include "iic.h"
#define DELAY_TIME 5
//#define SlaveAddrW 0xA0
//#define SlaveAddrR 0xA1
//总线引脚定义
sbit SDA = P2^1; /* 数据线 */
sbit SCL = P2^0; /* 时钟线 */
void IIC_Delay(unsigned char i)
{
do{_nop_();}
while(i--);
}
//总线启动条件
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 0;
}
//总线停止条件
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//发送应答
void IIC_SendAck(bit ackbit)
{
SCL = 0;
SDA = ackbit; // 0:应答,1:非应答
IIC_Delay(DELAY_TIME);
SCL = 1;
IIC_Delay(DELAY_TIME);
SCL = 0;
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//等待应答
bit IIC_WaitAck(void)
{
bit ackbit;
SCL = 1;
IIC_Delay(DELAY_TIME);
ackbit = SDA;
SCL = 0;
IIC_Delay(DELAY_TIME);
return ackbit;
}
//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++)
{
SCL = 0;
IIC_Delay(DELAY_TIME);
if(byt & 0x80) SDA = 1;
else SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 1;
byt <<= 1;
IIC_Delay(DELAY_TIME);
}
SCL = 0;
}
//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
unsigned char i, da;
for(i=0; i<8; i++)
{
SCL = 1;
IIC_Delay(DELAY_TIME);
da <<= 1;
if(SDA) da |= 1;
SCL = 0;
IIC_Delay(DELAY_TIME);
}
return da;
}
利用单片机、光学传感器、ADC、蜂鸣器等设计一个声光报警装置。系统功能可以分为基础功能和发挥部分,基础功能必须实现,扩展功能可自行选择。
基础功能:
- 该声光报警器能够测量光照强度,并通过数码管显示。
- 当光照强度超过安全范围,报警器发出声光报警,警灯闪烁(用流水灯模拟),警笛鸣叫(用蜂鸣器模拟)。
- 安全范围有上下限,均可通过按键修改。
扩展功能:
- 报警光强参数可以用EEPROM保存,系统开机后从EEPROM读取参数配置系统,参数通过按键修改后,应保存到EEPROM。
- 能够将最近100