基于51单片机的智能台灯设计

描述

一、设计目的

使用单片机设计智能台灯对于提高学生的单片机应用能力具有较强的意义。通过该设计,可以巩固所学的单片机理论知识,培养学生硬件和软件的设计能力,从而促进学生所掌握的理论知识向实践应用的改变。

二、设计要求

(1)熟悉51单片机集成开发环境,运用C语言编写工程文件;  (2)熟练应用所选用单片机的内部结构、资源,以及软硬件调试设备的基本方法;  (3)自行构建基于单片机的最小系统,完成相关硬件电路的设计实现;  (4)掌握智能台灯的原理和实现方法。

三、设计内容

(1) 可以通过按键切换控制模式,有自动模式和手动模式可选;

(2) 自动模式下,可根据空间环境的光线强度大小,调节台灯的亮度。并且

1分钟检测不到有人,直接熄灭台灯,达到节能的效果;

(3) 手动模式下,可通过按键增加或减少亮度;

开题报告

51单片机

方案设计

整个系统以STC89C52单片机为核心器件,配合电阻电容晶振等器件,构成单片机的最小系统。其它个模块围绕着单片机最小系统展开。其中包括,照明设备采用USB小灯进行模拟,使得设计在外形上更加美观,在USB小灯内部,是6颗白色的LED灯;光照强度采集模块,是使用光敏电阻+ADC0832方案;人体感应采用红外热释传感器,该传感器灵敏度高,操作控制简单;指示灯模块由一颗绿色的小灯构成,指示灯亮时是自动模式,熄灭时是手动模式;按键模块由3个按键组成,包括模式切换按键、亮度减少按键和亮度增加按键;

51单片机

 

设计功能

1、上电之后,绿色的 LED 灯点亮,代表当前是自动控制模式。

2、通过按键 1,可以在手动模式(绿灯灭)和自动模式(绿灯亮)之间来回切换。 

3、在手动模式下,可以通过按键 2 降低亮度,按键 3 增加亮度。 

4、在自动模式下,首先要检测到有人,才进行亮度的自动控制,否则台灯熄灭。可以挡住光敏电阻的光线,或用手电筒来照射光敏电阻,模拟光照的变化,从而就可以 看到台灯的亮度会随着环境中的光照强度的改变而改变,效果是光照越弱,台灯越亮。如果人体传感器 1 分钟检测不到有人,台灯就会自动熄灭。

5、无论是自动模式还是手动模式,都是把亮度分为 10 个等级的。 

6、注意,人体感应检测功能只在自动模式下有效。

原理图设计


51单片机
 

PCB设计


51单片机51单片机

源代码


 

#include 
#include 


#define uchar unsigned char    // 以后unsigned char就可以用uchar代替
#define uint  unsigned int    // 以后unsigned int 就可以用uint 代替




sbit LED     = P1^0;          // 模式指示灯,亮是自动模式,灭是手动模式
sbit Lamp    = P1^4;           // 台灯控制引脚
sbit Key1    = P1^1;          // 按键1,模式切换按键
sbit Key2    = P1^2;           // 按键2,亮度减少按键      
sbit Key3    = P1^3;          // 按键3,亮度增加按键
sbit ADC_CS  = P2^3;           // ADC0832的CS引脚
sbit ADC_CLK = P2^0;           // ADC0832的CLK引脚
sbit ADC_DAT = P2^1;           // ADC0832的DI/DO引脚
sbit Module  = P2^2;          // 人体红外检测模块




uchar gCount=0;                // 全局计数变量
uchar gIndex;                  // 亮度变量,0是最暗,9是最亮,一共10档
uint  gTime=0;                // 计时变量,用于计时多久没检测到有人






/*********************************************************/
// 毫秒级的延时函数,time是要延时的毫秒数
/*********************************************************/
void DelayMs(uint time)
{
  uint i,j;
  for(i=0;i>= 1;
    if(ADC_DAT)
      dat2=dat2|0x80;
    else
      dat2=dat2|0x00;
    WavePlus();
  }


  _nop_();            // 结束此次传输
  ADC_DAT = 1;
  ADC_CLK = 1;
  ADC_CS  = 1;   


  if(dat1==dat2)      // 返回采集结果
    return dat1;
  else
    return 0;
} 






/*********************************************************/
// 定时器初始化
/*********************************************************/
void TimerInit()
{
  TMOD = 0x01;        // 使用定时器0,工作方式1   
  TH0  = 252;          // 给定时器0的TH0装初值
  TL0  = 24;          // 给定时器0的TL0装初值  
  ET0  = 1;            // 定时器0中断使能
  EA   = 1;            // 打开总中断
  TR0   = 1;            // 启动定时器0
}






/*********************************************************/
// 手动控制
/*********************************************************/
void ManualControl()
{
  // 亮度减少
  if(Key2==0)          // 如果按键2被按下去
  {
    if(gIndex>0)      // 只要当前亮度不为最低才能减少亮度
    {
      gIndex--;        // 亮度降低一档
      DelayMs(300);    // 延时0.3秒
    }
  }


  // 亮度增加
  if(Key3==0)          // 如果按键3被按下去
  {
    if(gIndex<9)      // 只要当前亮度不为最高才能增加亮度
    {
      gIndex++;        // 亮度增加一档
      DelayMs(300);    // 延时0.3秒
    }
  }
}






/*********************************************************/
// 自动控制
/*********************************************************/
void AutoControl(uchar num)
{
  if(num<59)                            // 最亮
    gIndex=9;
  else if((num>65)&&(num<81))            // 第二亮
    gIndex=8;
  else if((num>87)&&(num<103))          // 第三亮
    gIndex=7;
  else if((num>109)&&(num<125))
    gIndex=6;
  else if((num>131)&&(num<147))
    gIndex=5;
  else if((num>153)&&(num<169))
    gIndex=4;
  else if((num>175)&&(num<191))
    gIndex=3;
  else if((num>197)&&(num<213))
    gIndex=2;
  else if((num>219)&&(num<235))
    gIndex=1;
  else if(num>241)                     // 最暗
    gIndex=0;
}






/*********************************************************/
// 主函数
/*********************************************************/
void main()
{
  uchar ret;


  TimerInit();           // 定时器初始化


  LED=0;                // 指示灯点亮(自动模式指示灯)
  ret=Get_ADC0832();    // 获取AD采集结果(环境光照强度)
  AutoControl(ret);      // 上电先进行一次自动亮度控制  
  AutoControl(ret+7);


  while(1)
  {
    /* 模式切换控制 */
    if(Key1==0)          // 如果按键1被按下去
    {
      LED=~LED;          // 切换LED灯状态
      DelayMs(10);      // 延时消除按键按下的抖动
      while(!Key1);      // 等待按键释放
      DelayMs(10);      // 延时消除按键松开的抖动
    }


    /* 亮度控制 */
    if(LED==1)              // 如果LED是灭的
    {
      ManualControl();      // 则进行手动控制
    }
    else                    // 如果LED是亮的
    {
      if(gTime<60000)
      {
        ret=Get_ADC0832();    // 获取AD采集结果(环境光照强度)
        AutoControl(ret);      // 进行自动控制  
        DelayMs(200);
      }
    }


    /*检测是否有人*/
    if(Module==1)
    {
      gTime=0;                    // 检测到有人,则把60秒计时清零
    }
    if(gTime>60000)                // 如果gTime的值超过了60000
    {
      gTime=60000;                // 则把gTime的值重新赋值为60000,避免过大溢出
      gIndex=0;                    // 如果1分钟检测不到有人,则把台灯熄灭
    }
  }
}




/*********************************************************/
// 定时器0服务程序,1毫秒
/*********************************************************/
void Timer0(void) interrupt 1
{
  TH0  = 252;            // 给定时器0的TH0装初值
  TL0  = 24;            // 给定时器0的TL0装初值  


  gTime++;              // 每1毫秒,gTime变量加1
  gCount++;              // 每1毫秒,gCount变量加1


  if(gCount==10)        // 如果gCount加到10了
  {
    gCount=0;            // 则将gCount清零,进入新一轮的计数
    if(gIndex!=0)        // 如果说台灯不是最暗的(熄灭)
    {
      Lamp=0;            // 则把台灯点亮
    }
  }
  if(gCount==gIndex)    // 如果gCount计数到和gIndex一样了
  {
    if(gIndex!=9)        // 如果说台灯不是最亮的
    {
      Lamp=1;            // 则把台灯熄灭
    }
  }
}

 

 

 

  审核编辑:汤梓红
 
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
评论(0)
发评论
jf_15835282 05-28
0 回复 举报
作者您好代码不完整吧 收起回复
jf_58294130 01-05
0 回复 举报
作者你好,你这代码是不是不完整,第46行后面少些东西 收起回复
全部评论

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分