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

一、设计要求

  本设计是一种基于PWM调光的智能台灯设计。把单片机技术和PWM调光技术结合起来实现台灯光强的调节。即在不改变PWM方波周期的前提下,利用单片机控制PWM的占空比,从而来改变电压的大小实现灯光亮度的调节。

  当人体在台灯的范围内且环境光线较弱时,自动感应开灯,且灯的亮度随着环境光线的改变而自动调节,一旦人离开台灯范围,即红外热释传感器检测不到有人时,1分钟后自动熄灯。本设计通过亮度的自动调节和人体检测控制台灯开关来达到绿色节能的效果。同时为了提高本设计的适用范围,还加入了手动模式的控制,在该模式下,台灯亮度由按键调节,这样使得该台灯在一些特殊情况下也能适用。

  系统的组成结构如下:

二、设计资料

三、部分程序代码

#include <reg52.h>
#include <intrins.h>

#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<time;i++)
    for(j=0;j<112;j++);
}



/*********************************************************/
// ADC0832的时钟脉冲
/*********************************************************/
void WavePlus()
{
  _nop_();
  ADC_CLK = 1;
  _nop_();
  ADC_CLK = 0;
}



/*********************************************************/
// 获取指定通道的A/D转换结果
/*********************************************************/
uchar Get_ADC0832()

  uchar i;
  uchar dat1=0;
  uchar dat2=0;
  
  ADC_CLK = 0;        // 电平初始化
  ADC_DAT = 1;
  _nop_();
  ADC_CS = 0;
  WavePlus();          // 起始信号 
  ADC_DAT = 1;
  WavePlus();          // 通道选择的第一位
  ADC_DAT = 0;      
  WavePlus();          // 通道选择的第二位
  ADC_DAT = 1;
  
  for(i=0;i<8;i++)    // 第一次读取
  {
    dat1<<=1;
    WavePlus();
    if(ADC_DAT)
      dat1=dat1|0x01;
    else
      dat1=dat1|0x00;
  }
  
  for(i=0;i<8;i++)    // 第二次读取
  {
    dat2>>= 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;
}
四、protues仿真

五、AD原理图

六、PCB

六、全套设计资料扫一扫关注公众号立即获取

  • 22
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

下饭的王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值