标题:
单片机智能台灯源程序
[打印本页]
作者:
llx888888888
时间:
2020-4-8 09:04
标题:
单片机智能台灯源程序
066c16b3e1e4537156ac44cc78cb470.png
(145.12 KB, 下载次数: 39)
下载附件
2020-4-8 09:02 上传
单片机源程序如下:
/**********************************************************************
* 名称 : 智能调光台灯
* 功能 : (1)亮度不够且有人靠近时台灯自动亮;
(2)靠的太近会提醒坐姿不正(蜂鸣器)
(3)附近无人时台灯自动熄灭(30秒) 时间可调
(4)根据环境亮度调节等亮度
(5)可手动调节台灯亮度
(6)设定学习时间
* 备注 :
***********************************************************************/
//头函数
#include <reg52.h>
#include <ADC0809.H>
//宏定义
#define uint unsigned int
#define uchar unsigned char
#define DUAN P0 //数码管段位
unsigned char code tab[]={0xa0,0xbb,0x62,0x2a,0x39,0x2c,0x24,0xba,0x20,0x28,0xff}; //0-9的显示码表 gc.debfa
unsigned char code tab_dian[]={0x80,0x9b,0x42,0x0a,0x19,0x0c,0x04,0x9a,0x00,0x08,0xdf}; //带点0-9的显示码表
uchar pdata tt[51]; //定义空数组用于AD0809取平均值
uchar scale=20,rsd_sec; //定义占空比比例,热释电计时秒变量
char min,sec; //定义计时分秒
//位定义
bit bdata flag_auto, //自动切换标志位
ss, //闪烁标志位
flag_bs, //报警位标志位
flag_rsd, //热释电动作标志位
flag_jiejin=1; //接近传感器标志位
uchar flag_set=0; //设置变量:0 正常 1 调分 2 调秒
uchar lum; //ad0809读出值
//函数声明
void delay(uchar i);
//管脚声明
sbit LED = P3^4; //PWM输出
sbit change= P2^3; //自动模式切换按键
sbit set = P2^2; //设置按键
sbit add = P2^1; //加按键
sbit sub = P2^0; //减按键
sbit rsd = P3^6; //热释电
sbit jiejin=P3^5; //接近开关
sbit buzz=P3^7;
sbit W0=P2^7; //数码管位端
sbit W1=P2^6;
sbit W2=P2^5;
sbit W3=P2^4;
/**********************************************************************
* 名称 : display();
* 功能 : 数码管显示
* 输入 : 无
* 输出 : 无
***********************************************************************/
void display()
{
if(flag_set==0) //正常模式下
{
DUAN=tab[min/10]; //送入段码,秒数高位
W0=0; //打开位地址
delay(1); //小延时
W0=1; //关闭位地址
DUAN=tab_dian[min%10]; //送入段码,秒数低位
W1=0;
delay(1);
W1=1;
DUAN=tab[sec/10]; //送入段码,分钟数高位
W2=0;
delay(1);
W2=1;
DUAN=tab[sec%10]; //送入段码,分钟数高位
W3=0;
delay(1);
W3=1;
}
else if(flag_set==1) //设置模式下闪烁相应位
{
if(ss==1) //闪烁标志 ss=1 正常显示
{
DUAN=~tab[min/10];
W0=0;
delay(1);
W0=1;
DUAN=~tab_dian[min%10];
W1=0;
delay(1);
W1=1;
}
else //闪烁标志 ss=0 熄灭相应位 达到闪烁效果 ss在定时器里500ms取反一次
{
DUAN=~tab[10]; //
W0=0;
delay(1);
W0=1;
DUAN=~tab_dian[10];
W1=0;
delay(1);
W1=1;
}
DUAN=~tab[sec/10];
W2=0;
delay(1);
W2=1;
DUAN=~tab[sec%10];
W3=0;
delay(1);
W3=1;
}
else
{
DUAN=~tab[min/10];
W0=0;
delay(1);
W0=1;
DUAN=~tab_dian[min%10];
W1=0;
delay(1);
W1=1;
if(ss==1)
{
DUAN=~tab[sec/10];
W2=0;
delay(1);
W2=1;
DUAN=~tab[sec%10];
W3=0;
delay(1);
W3=1;
}
else
{
DUAN=~tab[10];
W2=0;
delay(1);
W2=1;
DUAN=~tab[10];
W3=0;
delay(1);
W3=1;
}
}
}
/**********************************************************************
* 名称 : KEY();
* 功能 : 按键控制
* 输入 : 无
* 输出 : 无
***********************************************************************/
void KEY()
{
uint lum_mean,lum_all;
uchar b,c;
if(change==0) //自动切换按键按下
{
delay(10); //去抖
if(change==0) //再次判断按键按下
{
buzz=0; //蜂鸣器鸣响
flag_auto=!flag_auto; //自动模式标志位取反
if(flag_auto==1) //当切换到手动模式时 首先将LED发光比例PWM设置在50%
scale=20;
}
while(!change) display();buzz=1; //等待按键释放 松开按键后关闭蜂鸣器、刷新显示
}
if(jiejin==0&&flag_jiejin==1) //接近传感器检测到障碍时 开启报警
{
buzz=0;
flag_jiejin=0;
}
if(jiejin!=flag_jiejin) //接近传感器检测不到障碍时 关闭报警
{
buzz=1;
flag_jiejin=1;
}
if(set==0) //设置键按下时
{
delay(10);
if(set==0)
{
buzz=0;
flag_set++; //设置变量++
if(flag_set==3) //加到3时回复回正常模式
flag_set=0;
flag_bs=0; //按下设置 关闭报警
}
while(!set) display(); buzz=1;//等待按键释放 松开按键后关闭蜂鸣器、刷新显示
}
if(flag_set==1) //加键按键只有在设置状态(flag_set!=0)时按下才有效 调分
{
if(add==0) //加按键按下时
{
delay(10); //消抖
if(add==0)
{
buzz=0; //蜂鸣器响
min++; //分++
if(min>=60)
min=0;
}
while(!add) display(); buzz=1; //等待按键释放 松开按键后关闭蜂鸣器、刷新显示
}
if(sub==0) //减按键按下时
{
delay(10); //消抖
if(sub==0)
{
buzz=0; //蜂鸣器响
min--; //分--
if(min>0)
min=59;
}
while(!sub) display(); buzz=1; //等待按键释放 松开按键后关闭蜂鸣器、刷新显示
}
}
if(flag_set==2) //调秒
{
if(add==0) //加键按下
{
delay(10); //消抖
if(add==0)
{
buzz=0; //蜂鸣器响
sec++; //秒++
if(sec>=60)
sec=0;
}
while(!add) display(); buzz=1; //等待按键释放 松开按键后关闭蜂鸣器、刷新显示
}
if(sub==0) //减键按下
{
delay(10);
if(sub==0) //消抖
{
buzz=0; //蜂鸣器响
sec--; //秒--
if(sec<0)
sec=59;
}
while(!sub) display(); buzz=1; //等待按键释放 松开按键后关闭蜂鸣器、刷新显示
}
while(!sub);
}
if(flag_auto==0) //自动模式
{
if(flag_rsd==1) //且有人在范围内时 环境发光强度控制灯光变化
{
for(b=0;b<49;b++) //将空数组tt[]内数值整体左移一位
{
tt[b]=tt[b+1]; //将后一数值放到前一位置
}
tt[49]=ADC0809(); //将读出的ad0809数值放入tt[49]
for(c=0;c<50;c++) //将tt[]内数值相加
{
lum_all=lum_all+tt[c];
}
lum_mean=lum_all/50; //将总数/50取出平均值
// lum_all=0; //将总数清零
if(lum_mean<=30) scale=1; //判断取出平均值大小 小于30 发光强度0%
else if(lum_mean>=150) scale=41; //大于150 发光强度100%
else scale=((lum_mean-30)/3)+1; //其他值时将其计算得到发光强度 (计算目的是为了得到一个1-41之间的数值 控制灯光变化)
}
else
scale=1; //没有人在范围内时 将灯光亮度调至0%
}
else //手动模式下
{
if(flag_set==0) //正常模式下
{
if(add==0) //加键按下
{
delay(10);
if(add==0)
{
// buzz=0; //蜂鸣器响
scale++; //灯光比例++
if(scale>=41)
scale=41;
display();
}
// while(!add) display(); buzz=1;
}
if(sub==0) //减键按下时
{
delay(10);
if(sub==0)
{
// buzz=0; //蜂鸣器响
scale--; //灯光比例--
if(scale>1)
scale=1;
display();
}
// while(!sub) display(); buzz=1;
}
}
}
}
/**********************************************************************
* 名称 : init();
* 功能 : 初始化定时器
* 输入 : 无
* 输出 : 无
***********************************************************************/
void init()
{
TMOD=0x11; //工作方式1
TH1=0x3c;
TL1=0xb0; //T1赋初值50ms
TH0=0xff;
TL0=0xe7; //T0赋初值25us
ET0=1;
ET1=1; //打开中断允许开关
EA=1; //中断总开关
TR0=1; //开定时器0 开关
TR1=0; //关定时器0 开关
}
/**********************************************************************
* 名称 : main();
* 功能 : 主函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void main()
{
init(); //调用初始化函数
flag_auto=1; //初始化手动模式
rsd=0; //热释电引脚置低(有信号时时高电平)
delay(500); //延时500ms后开机
while(1) //大循环
{
KEY(); //调用按键函数
display(); //调用显示函数
}
}
/**********************************************************************
* 名称 : delay();
* 功能 : 延时函数:大约1ms
* 输入 : 无
* 输出 : 无
***********************************************************************/
void delay(uchar i)
{
uchar j,k;
for(j=i;j>0;j--)
for(k=125;k>0;k--);
}
/**********************************************************************
* 名称 : void time0() interrupt 1
* 功能 : 定时器T0 中断服务函数:PWM脉冲发生函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void time0() interrupt 1
{
uchar n;
TH0=0xff;
TL0=0xe7; //重新赋初值
n++; //每25us n++
if(n>scale) //n<设置比例时,打开灯
{
LED=1;
}
else if(n<=scale)//n大于等于设置比例时 关闭灯
{
LED=0;
}
if(n==40) //n==40 :25us*40=1ms 1kHZ
{
n=0; //n=0
}
else ;
}
/**********************************************************************
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
智能台灯.rar
(246.46 KB, 下载次数: 81)
2020-4-8 09:04 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
xuwei517
时间:
2020-5-5 11:32
程序里的 码表代码 没看懂是用共阴还是共阳的数码管呢? 请教下
作者:
??4554
时间:
2020-8-11 20:52
接5伏,是共阳
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1