单片机系统设计声光报警器

摘要

本次设计利用单片机、光学传感器、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;    
}
  1. 设计任务

利用单片机、光学传感器、ADC、蜂鸣器等设计一个声光报警装置。系统功能可以分为基础功能和发挥部分,基础功能必须实现,扩展功能可自行选择。

  1. 功能要求

    基础功能:

  1. 该声光报警器能够测量光照强度,并通过数码管显示。
  2. 当光照强度超过安全范围,报警器发出声光报警,警灯闪烁(用流水灯模拟),警笛鸣叫(用蜂鸣器模拟)。
  3. 安全范围有上下限,均可通过按键修改。

扩展功能:

  1. 报警光强参数可以用EEPROM保存,系统开机后从EEPROM读取参数配置系统,参数通过按键修改后,应保存到EEPROM
  2. 能够将最近100
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值