【C51单片机】声控LED智能灯

一、项目要求

设计一款声控LED智能灯,该灯含有8个灯珠,采用一个按键统一控制灯的开与关,也可以通过声音控制开灯,开灯后根据环境光亮度,点亮多个灯珠(最暗时点亮8个灯珠,最亮时点亮1个灯珠)。

二、使用的硬件

       1. 51单片机实验板,以及电源线、下载线、杜邦线

       2. 声音传感器、PCF8591数模转换模块、光敏电阻、独立按键、LED灯

三、设计方案

通过外部中断的开关和声音传感器统一控制灯的开与关,然后用PCF8591数模转换上的光敏电阻把当前环境光的亮度传给单片机,单片机通过光照强度来控制亮几个灯

系统连接图:

四、源代码

1、PCF8591数模转换函数

#include <pcf8591.h>
sbit scl=P2^0;       //I2C  时钟 
sbit sda=P2^1;       //I2C  数据 
bit ack;             //应答标志位
/******************************************************************* 
功能:     启动I2C总线,即发送I2C起始条件.  
********************************************************************/
void Start_I2c()
{
  sda=1;         /*发送起始条件的数据信号*/
  _nop_();
  scl=1;
  _nop_();        /*起始条件建立时间大于4.7us,延时*/
  _nop_();
  _nop_();
  _nop_();
  _nop_();    
  sda=0;         /*发送起始信号*/
  _nop_();        /* 起始条件锁定时间大于4μs*/
  _nop_();
  _nop_();
  _nop_();
  _nop_();       
  scl=0;       /*钳住I2C总线,准备发送或接收数据 */
  _nop_();
  _nop_();
}

/******************************************************************* 
功能:     结束I2C总线,即发送I2C结束条件.  
********************************************************************/
void Stop_I2c()
{
  sda=0;      /*发送结束条件的数据信号*/
  _nop_();       /*发送结束条件的时钟信号*/
  scl=1;      /*结束条件建立时间大于4μs*/
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  sda=1;      /*发送I2C总线结束信号*/
  _nop_();
  _nop_();
  _nop_();
  _nop_();
}

/*******************************************************************
功能:     将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
          此状态位进行操作.(不应答或非应答都使ack=0)     
           发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
********************************************************************/
void  I2C_SendByte(u8  c)
{
 u8  i;
 
 for(i=0;i<8;i++)  /*要传送的数据长度为8位*/
    {
     if((c<<i)&0x80)sda=1;   /*判断发送位*/
       else  sda=0;                
     _nop_();
     scl=1;               /*置时钟线为高,通知被控器开始接收数据位*/
      _nop_(); 
      _nop_();             /*保证时钟高电平周期大于4μs*/
      _nop_();
      _nop_();
      _nop_();         
     scl=0; 
    }
    
    _nop_();
    _nop_();
    sda=1;                /*8位发送完后释放数据线,准备接收应答位*/
    _nop_();
    _nop_();   
    scl=1;
    _nop_();
    _nop_();
    _nop_();
    if(sda==1)ack=0;     
       else ack=1;        /*判断是否接收到应答信号*/
    scl=0;
    _nop_();
    _nop_();
}

/*******************************************************************
功能:        用来接收从器件传来的数据,并判断总线错误(不发应答信号),
          发完后请用应答函数应答从机。  
********************************************************************/    
u8   I2C_RcvByte()
{
  u8  retc=0,i; 
  sda=1;                     /*置数据线为输入方式*/
  for(i=0;i<8;i++)
      {
        _nop_();           
        scl=0;                  /*置时钟线为低,准备接收数据位*/
        _nop_();
        _nop_();                 /*时钟低电平周期大于4.7μs*/
        _nop_();
        _nop_();
        _nop_();
        scl=1;                  /*置时钟线为高使数据线上数据有效*/
        _nop_();
        _nop_();
        retc=retc<<1;
        if(sda==1)retc=retc+1;  /*读数据位,接收的数据位放入retc中 */
        _nop_();
        _nop_(); 
      }
  scl=0;    
  _nop_();
  _nop_();
  return(retc);
}
/********************************************************************
功能:      主控器进行应答信号(可以是应答或非应答信号,由位参数a决定)
********************************************************************/
void Ack_I2c(bit a)
{  
  if(a==0)sda=0;              /*在此发出应答或非应答信号 */
  else sda=1;				  /*0为发出应答,1为非应答信号 */
  _nop_();
  _nop_();
  _nop_();      
  scl=1;
  _nop_();
  _nop_();                    /*时钟低电平周期大于4μs*/
  _nop_();
  _nop_();
  _nop_();  
  scl=0;                     /*清时钟线,住I2C总线以便继续接收*/
  _nop_();
  _nop_();    
}
/************************************************************
* 函数功能      : PCF8591的输出端输出模拟量
******************* *****************************************/
bit Pcf8591_DaConversion(u8 addr,u8 channel,u8 Val)
{
   Start_I2c();              //启动总线
   I2C_SendByte(addr);            //发送器件地址
   if(ack==0)return(0);
   I2C_SendByte(0x40|channel);              //发送控制字节
   if(ack==0)return(0);
   I2C_SendByte(Val);            //发送DAC的数值  
   if(ack==0)return(0);
   Stop_I2c();               //结束总线
   return(1);
}
/************************************************************
* 函数功能		: 写入一个控制命令
************************************************************/
bit PCF8591_SendByte(u8 addr,u8 channel)
{
   Start_I2c();              //启动总线
   I2C_SendByte(addr);            //发送器件地址
   if(ack==0)return(0);
   I2C_SendByte(0x40|channel);              //发送控制字节
   if(ack==0)return(0);
   Stop_I2c();               //结束总线
   return(1);
}
/************************************************************
* 函数功能   	: 读取一个转换值*/

u8 PCF8591_RcvByte(u8 addr)
{  
   u8 dat;

   Start_I2c();          //启动总线
   I2C_SendByte(addr+1);      //发送器件地址
   if(ack==0)return(0);
   dat=I2C_RcvByte();          //读取数据0

   Ack_I2c(1);           //发送非应答信号
   Stop_I2c();           //结束总线
   return(dat);
}

2、Main函数

#include<config.h>
#include<uart.h>
#include <pcf8591.h>
sbit RL=P2^2;	//声控
sbit gnd=P3^4;
//sbit Switch=P3^2;
sbit beep=P2^3;	//蜂鸣器引脚
int flag=1,flag1=1;
u8 print[20];
void delay_ms(u16 x)//毫秒延时函数
{u16 i;
 u8 j;
 for(i=0;i<x;i++)
    for(j=0;j<115;j++);
}

void delay_us(u8 t) //10倍微秒延时函数,延时10*t微秒
{u8 i;
 for(i=0;i<=t;i++);
}

void Alarm(u8 t) //蜂鸣器报警,持续t秒
{
 u8 i,j,k; 	
 for(j=0;j<t;j++)
 { for(i=0;i<200;i++)
      {beep=0;delay_us(50);beep=1;delay_us(50);}
   for(k=0;k<100;k++)
      {beep=0;delay_us(110);beep=1;delay_us(110);}
 }
}
void main()
{
	u8 light;
	P1=0xff;
	EA=1;
	IT0=1;
	EX0=1;
	gnd=0;
    Init_COM();   //初始化
	flag=1;
   while(1)
    {
		PCF8591_SendByte(AddWr,1);//启动AIN0通道模数转换,光敏
        light=PCF8591_RcvByte(AddWr);//读出转换数字值
		light=255-light;
		delay_ms(200);
	 
	    sprintf(print,"L:%3bu",light);
	    Print_str_COM(print);	  //将采集的值送串口
	 	if(RL==1){flag=!flag;delay_ms(150);}		
		if(flag==0)
		{
				//if(light=0){	P1=0XFF;}
				if(light>0&&light<30){P1=0X00;}
				if(light>=30&&light<60){P1=0X01;}
				if(light>=60&&light<90){P1=0X03;}
				if(light>=90&&light<120){P1=0X07;}
				if(light>=120&&light<150){P1=0X0F;}
				if(light>=150&&light<180){P1=0X1F;}
				if(light>=180&&light<210){P1=0X3F;}
				if(light>=210&&light<=255){P1=0X7F;}
				//delay_ms(3000);
				//P1=0XFF;
			}
			else	
		{
			P1=0XFF;delay_ms(10);//break;
		}	
		}	 
}
void int0() interrupt 0
{
	flag=!flag;	
}
	

五、实验效果

由于不能上传视频,所以我将效果视频上传至优酷,请点击观看------->声控LED智能灯

 

问题咨询及项目源码请加群:

QQ群

名称:IT项目交流群

群号:245022761

 

 

  • 10
    点赞
  • 110
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值