鉴于宿舍晚上会被宿管灭灯,所以制作了一个小台灯在关灯后”窥视”用,可是舍友陈某反响光线太强影响其睡觉,所以决计做个能够调光的LED小夜灯,窥视自己的隐私,让他人睡觉去吧…
查找自己的原件库,发现上半年买的STC15L104E一向没用,所以计划就用单片机来操控了,当然,假如用模仿电路,或许几个元件就能够完成了,可是,模仿对我来说更难规划,所以,,,好吧,废话多了下面贴电路:
其实也没什么,纯粹是IO操作,两个开光是调光用,AMS117是降压用,AMP4953就相当于开关,后边的电感%&&&&&%电路是避免呈现闪耀的,额,假如有问题的话能够贴出来.
下面介绍模仿PWM操作,究竟不是硬件的PWM并且要顾及程序长度,所以模仿出来的PWM频率600HZ,不过用在LED上应该足够了.
设PWM基数为PWM_NUM,PWM比较输出值为PWM_CMP.
首要思路便是运用单片机内部计时器按必定周期中止,然后在中止服务程序里令PWM_NUM加一,判别是否小于PWM_CMP比较值,假如小于,则IO输出高,不然输出低,这样,咱们就能够经过修正PWM_CMP的值来调理IO输出脉宽,到达模仿PWM的作用了.PWM周期=计时器中止周期/PWM_NUM;
好吧,我的文字表达能力欠好,贴张图来阐明或许比较好:
如图,假定PWM_CMP=6,PWM_NUM=16,也便是,PWM_NUM到达16后清零.每个计时器中止周期PWM_NUM主动加一,判别是否小于PWM_CMP,是则输出高电平,不然输出低电平,所以,如图所示,当PWM_NUM累加到6前,输出电平是一向是高的,知道PWM_NUM累加到6后,输出就拉低了,当PWM_NUM到达16后,清零,这时PWM_NUM又小于PWM_CMP,故PWM输出又为高了,循环往复,就到达模仿PWM的作用了,PWM周期就等于PWM_NUM重装周期.
当然值得注意的是,由于判别是在中止服务程序中履行,所以计时器周期不能太短.
好吧,贴整个完好的程序出来,它的功用我先阐明一下.
按下key1变亮,按下key2变暗,长按则接连调理,两个键一同按下改动显现方法,别离有四个形式,单个别离亮,两个亮,两个都不亮.每次改动亮度和形式都写入单片机EEPROM,开机读取EEPROM,这样便能开机坚持前次关机的状况,不必每次翻开都要调理了.提到这我就要吐槽了,这STC15系列A版外部中止呐,连掉电唤醒都完成不了,那几个外部中止口都是铺排的.所以本来计划运用掉电形式作为关机状况的,可是唤醒不了(除了复位键),所以只好用外部硬件开关关机了….
废话不多说,贴程序,程序有标示,看不理解或有问题指导的贴出来,虚心接受.
#include “reg52.h”
#include “intrins.h”
#define ON 0 //LED是低电平有用
#define OFF 1
#define PWM_TIME 200 //计时器计数值
#define MODEL_ADDR 0x0000 //EEPEOM地址
#define PWM_CMP_ADDR 0x0200
sfr AUXR =0x8e;
sfr P3M1 =0xb1;
sfr P3M0 =0xb2;
sfr IAP_DATA =0xc2;
sfr IAP_ADDRH=0xc3;
sfr IAP_ADDRL=0xc4;
sfr IAP_CMD =0xc5;
sfr IAP_TRIG =0xc6;
sfr IAP_CONTR=0xc7;
sbit KEY1=P3^0;
sbit KEY2=P3^1;
sbit LED1=P3^2;
sbit LED2=P3^3;
unsigned char key_down,key_cont,key_up;
//donw为上升沿,cont为长效,up为下降沿
unsigned char pwm_cmp=1; //PWM比较值
unsigned char pwm_num=0; //PWM计数值
unsigned char led_model=0; //LED形式
unsigned char pwm_delay=0; //延时暂存
unsigned char cmp_temp;
//led_cmp的暂存,用于运算是否写入EEPROM
//计时器0初始化
void timer_init()
{
TMOD=0x00; //形式0,16位主动装载形式
EA=1;
ET0=1;
TR0=1;
AUXR|=0x80; //1T形式
TL0=65536-PWM_TIME;
TH0=(65536-PWM_TIME)>>8;
}
//EEPROM读写后避免误操作
void eeprom_dle()
{
IAP_CONTR=0;
IAP_CMD =0;
IAP_TRIG =0;
IAP_ADDRH=0;
IAP_ADDRL=0;
}
//擦除EEPROM扇区
void eeprom_erase(unsigned int addr)
{
IAP_CONTR=0x83;
IAP_CMD =0x03;
IAP_ADDRL=addr;
IAP_ADDRH=addr>>8;
IAP_TRIG =0x5a;
IAP_TRIG =0xa5;
_nop_();_nop_();_nop_();
//eeprom_dle();
}
声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/xinpin/259326.html