• 回复
  • 收藏
  • 点赞
  • 分享
  • 发新帖

【原创】高山云----STC单片机改调光台灯

很多现有的台灯都不具备调光的功能,只有一个电源开关,现用STC15F104E/STC15F104W等8脚芯片进行改造。利用单片机内部的EEPROM功能进行数据的掉电保存。

项目设计要求:

     1.通过台灯适配器上的电源开关来进行调光切换。

     2.调光分成4个档位,分别对应pwm占空比的:25%,50%,75%,100%

     3.程序带记忆功能,上电时间超过6秒钟单片机将记住此时的亮度数据(及占空比),关灯后下次打开依旧为上次的亮度

     4.调光切换,上电后在6秒钟以内,每开关一次,亮度将向后变化一次,如果当前为100%,下次切换后为25%的亮度

有了以上的设计要求后就可以自己写代码和搭硬件电路了。

全部回复(45)
正序查看
倒序查看
2014-05-29 14:55

台灯适配器图片:

台灯开关,增加的电路会装在这个开关中

最暗时候的灯珠亮度

最暗时候的PWM波形

实际调试的电路

一下是原理图,方块内部的部分电路最后全部装到适配器上的开关里

0
回复
2014-05-29 15:06
@yueyunno1
台灯适配器图片:[图片]台灯开关,增加的电路会装在这个开关中[图片]最暗时候的灯珠亮度[图片]最暗时候的PWM波形[图片]实际调试的电路[图片]一下是原理图,方块内部的部分电路最后全部装到适配器上的开关里[图片]
#include "reg51.h"
#include "intrins.h"

typedef bit BOOL;
typedef unsigned char BYTE;
typedef unsigned int WORD;

#define T1MS (65536-500) //12T模式

sfr AUXR = 0x8e;                    //Auxiliary register

/*---------------------------------------------------------------------*/
/*--   端口定义                 ---------------------------------------*/
/*---------------------------------------------------------------------*/
#define PORT_3 P3
#define HIGH 1
#define LOW	 0

sbit PWM_OUT_PORT   = P3^2;		   //	LED_RED	 LED_GREEN
sbit LED   = P3^3;
/*---------------------------------------------------------------------*/
/*--   变量定义                 ---------------------------------------*/
/*---------------------------------------------------------------------*/
BYTE i,j;
BYTE test_num;
BYTE POWER_ON_TEMP_f;
BYTE POWER_ON_TIME;
BYTE READ_POWER_ON_TIME;
BOOL ON_OFF_Flag;

unsigned long POWER_ON_TEMP;

//-----------------------------------------------
sfr IAP_DATA    =   0xC2;               //IAP数据寄存器
sfr IAP_ADDRH   =   0xC3;               //IAP地址寄存器高字节
sfr IAP_ADDRL   =   0xC4;               //IAP地址寄存器低字节
sfr IAP_CMD     =   0xC5;               //IAP命令寄存器
sfr IAP_TRIG    =   0xC6;               //IAP命令触发寄存器
sfr IAP_CONTR   =   0xC7;               //IAP控制寄存器

sfr WDT_CONTR   =   0xC1;               //0000,0000 看门狗控制寄存器

sfr P3M0        =   0xB2;   //0000,0000 端口3模式寄存器0
sfr P3M1        =   0xB1;   //0000,0000 端口3模式寄存器1

#define CMD_IDLE    0                   //空闲模式
#define CMD_READ    1                   //IAP字节读命令
#define CMD_PROGRAM 2                   //IAP字节编程命令
#define CMD_ERASE   3                   //IAP扇区擦除命令
#define ENABLE_IAP 0x83                 //if SYSCLK<12MHz

#define IAP_ADDRESS  0x0100		        //测试地址
#define OFF_TIME_ADD 0x0300		        //测试地址
/*----------------------------
关闭IAP
----------------------------*/
void IapIdle()
{
    IAP_CONTR = 0;                  //关闭IAP功能
    IAP_CMD = 0;                    //清除命令寄存器
    IAP_TRIG = 0;                   //清除触发寄存器
    IAP_ADDRH = 0x80;               //将地址设置到非IAP区域
    IAP_ADDRL = 0;
}

/*----------------------------
从ISP/IAP/EEPROM区域读取一字节
----------------------------*/
BYTE IapReadByte(WORD addr)
{
    BYTE dat;                       //数据缓冲区
    IAP_CONTR = ENABLE_IAP;         //使能IAP
    IAP_CMD = CMD_READ;             //设置IAP命令
    IAP_ADDRL = addr;               //设置IAP低地址
    IAP_ADDRH = addr >> 8;          //设置IAP高地址
    IAP_TRIG = 0x5a;                //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                //写触发命令(0xa5)
    _nop_();                        //等待ISP/IAP/EEPROM操作完成
    dat = IAP_DATA;                 //读ISP/IAP/EEPROM数据
    IapIdle();                      //关闭IAP功能
    return dat;                     //返回
}

/*----------------------------
写一字节数据到ISP/IAP/EEPROM区域
----------------------------*/
void IapProgramByte(WORD addr, BYTE dat)
{
    IAP_CONTR = ENABLE_IAP;         //使能IAP
    IAP_CMD = CMD_PROGRAM;          //设置IAP命令
    IAP_ADDRL = addr;               //设置IAP低地址
    IAP_ADDRH = addr >> 8;          //设置IAP高地址
    IAP_DATA = dat;                 //写ISP/IAP/EEPROM数据
    IAP_TRIG = 0x5a;                //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                //写触发命令(0xa5)
    _nop_();                        //等待ISP/IAP/EEPROM操作完成
    IapIdle();
}

/*----------------------------
扇区擦除
----------------------------*/
void IapEraseSector(WORD addr)
{
    IAP_CONTR = ENABLE_IAP;         //使能IAP
    IAP_CMD = CMD_ERASE;            //设置IAP命令
    IAP_ADDRL = addr;               //设置IAP低地址
    IAP_ADDRH = addr >> 8;          //设置IAP高地址
    IAP_TRIG = 0x5a;                //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                //写触发命令(0xa5)
    _nop_();                        //等待ISP/IAP/EEPROM操作完成
    IapIdle();
}

/*---------------------------------------------------------------------*/
/*--   延时子程序               ---------------------------------------*/
/*---------------------------------------------------------------------*/
void DELAY_1MS(unsigned int z)
{
	unsigned int x,y;
	for(x=z;x>0;x--)
		for(y=123;y>0;y--); 
}
/*---------------------------------------------------------------------*/
/*--   主程序                   ---------------------------------------*/
/*---------------------------------------------------------------------*/

void main()
{
	PORT_3=0X00;
	P3M0=0xFF;
	P3M1=0x00;
	ON_OFF_Flag=0;
	POWER_ON_TIME=0;
	READ_POWER_ON_TIME=0;

    AUXR |= 0x80;                   //定时器0为1T模式
//    AUXR &= 0x7f;                   //定时器0为12T模式
    TMOD = 0x00;                    //设置定时器为模式0(16位自动重装载)
    TL0 = T1MS;                     //初始化计时值
    TH0 = T1MS >> 8;
    TR0 = 1;                        //定时器0开始计时
    ET0 = 1;                        //使能定时器0中断
    EA = 0;
	POWER_ON_TEMP=0;
	POWER_ON_TEMP_f=0;
	j=0;
	i=100;

	DELAY_1MS(100);

	WDT_CONTR = 0x35;	   //启动看门狗
	while (1)
	{
		WDT_CONTR = 0x35;	   //启动看门狗	    
		if(ON_OFF_Flag==0)	   //上电标志,上电只执行一次
		{
			ON_OFF_Flag=1;
			READ_POWER_ON_TIME=IapReadByte(OFF_TIME_ADD);	  //////////////////////////////

			if(READ_POWER_ON_TIME!=4)   //上电时间监测,小于4切换模式
			{
				test_num=IapReadByte(IAP_ADDRESS);			  //////////////////////////////
				if(test_num<3)		 //	LED_RED	 LED_GREEN
				{
				   	test_num++;
					IapEraseSector(IAP_ADDRESS);
					IapProgramByte(IAP_ADDRESS,test_num);					
				}
				else 
				{
					test_num=0;
					IapEraseSector(IAP_ADDRESS);
					IapProgramByte(IAP_ADDRESS,test_num);
				}
			}

			else					  //上电时间监测,大于4模式记忆
			{
				test_num=IapReadByte(IAP_ADDRESS);		  /////////////////////////////////
				if(test_num>3)		 //	LED_RED	 LED_GREEN 
				{
				   	test_num=0;
					IapEraseSector(IAP_ADDRESS);
					IapProgramByte(IAP_ADDRESS,test_num);
				}	
			}
			IapEraseSector(OFF_TIME_ADD);
		}
		/*---------------------------------------------------------------------*/
		EA = 1;
		if(test_num==0)
		{
			j=4;
		}
		else if(test_num==1)
		{
			j=20;			
		}
		else if(test_num==2)
		{
			j=50;			
		}
		else if(test_num==3)
		{
			j=99;			
		}	
	}
}

//-----------------------------------------------

/* Timer0 interrupt routine */
void tm0_isr() interrupt 1 using 1
{
	if(i>0)
	{
		i--;
		if(j
0
回复
2014-05-29 15:07
@yueyunno1
#include"reg51.h"#include"intrins.h"typedefbitBOOL;typedefunsignedcharBYTE;typedefunsignedintWORD;#defineT1MS(65536-500)//12T模式sfrAUXR=0x8e;//Auxiliaryregister/*---------------------------------------------------------------------*//*--端口定义---------------------------------------*//*---------------------------------------------------------------------*/#definePORT_3P3#defineHIGH1#defineLOW0sbitPWM_OUT_PORT=P3^2;//LED_REDLED_GREENsbitLED=P3^3;/*---------------------------------------------------------------------*//*--变量定义---------------------------------------*//*---------------------------------------------------------------------*/BYTEi,j;BYTEtest_num;BYTEPOWER_ON_TEMP_f;BYTEPOWER_ON_TIME;BYTEREAD_POWER_ON_TIME;BOOLON_OFF_Flag;unsignedlongPOWER_ON_TEMP;//-----------------------------------------------sfrIAP_DATA=0xC2;//IAP数据寄存器sfrIAP_ADDRH=0xC3;//IAP地址寄存器高字节sfrIAP_ADDRL=0xC4;//IAP地址寄存器低字节sfrIAP_CMD=0xC5;//IAP命令寄存器sfrIAP_TRIG=0xC6;//IAP命令触发寄存器sfrIAP_CONTR=0xC7;//IAP控制寄存器sfrWDT_CONTR=0xC1;//0000,0000看门狗控制寄存器sfrP3M0=0xB2;//0000,0000端口3模式寄存器0sfrP3M1=0xB1;//0000,0000端口3模式寄存器1#defineCMD_IDLE0//空闲模式#defineCMD_READ1//IAP字节读命令#defineCMD_PROGRAM2//IAP字节编程命令#defineCMD_ERASE3//IAP扇区擦除命令#defineENABLE_IAP0x83//ifSYSCLK>8;//设置IAP高地址IAP_TRIG=0x5a;//写触发命令(0x5a)IAP_TRIG=0xa5;//写触发命令(0xa5)_nop_();//等待ISP/IAP/EEPROM操作完成dat=IAP_DATA;//读ISP/IAP/EEPROM数据IapIdle();//关闭IAP功能returndat;//返回}/*----------------------------写一字节数据到ISP/IAP/EEPROM区域----------------------------*/voidIapProgramByte(WORDaddr,BYTEdat){IAP_CONTR=ENABLE_IAP;//使能IAPIAP_CMD=CMD_PROGRAM;//设置IAP命令IAP_ADDRL=addr;//设置IAP低地址IAP_ADDRH=addr>>8;//设置IAP高地址IAP_DATA=dat;//写ISP/IAP/EEPROM数据IAP_TRIG=0x5a;//写触发命令(0x5a)IAP_TRIG=0xa5;//写触发命令(0xa5)_nop_();//等待ISP/IAP/EEPROM操作完成IapIdle();}/*----------------------------扇区擦除----------------------------*/voidIapEraseSector(WORDaddr){IAP_CONTR=ENABLE_IAP;//使能IAPIAP_CMD=CMD_ERASE;//设置IAP命令IAP_ADDRL=addr;//设置IAP低地址IAP_ADDRH=addr>>8;//设置IAP高地址IAP_TRIG=0x5a;//写触发命令(0x5a)IAP_TRIG=0xa5;//写触发命令(0xa5)_nop_();//等待ISP/IAP/EEPROM操作完成IapIdle();}/*---------------------------------------------------------------------*//*--延时子程序---------------------------------------*//*---------------------------------------------------------------------*/voidDELAY_1MS(unsignedintz){unsignedintx,y;for(x=z;x>0;x--)for(y=123;y>0;y--);}/*---------------------------------------------------------------------*//*--主程序---------------------------------------*//*---------------------------------------------------------------------*/voidmain(){PORT_3=0X00;P3M0=0xFF;P3M1=0x00;ON_OFF_Flag=0;POWER_ON_TIME=0;READ_POWER_ON_TIME=0;AUXR|=0x80;//定时器0为1T模式//AUXR&=0x7f;//定时器0为12T模式TMOD=0x00;//设置定时器为模式0(16位自动重装载)TL0=T1MS;//初始化计时值TH0=T1MS>>8;TR0=1;//定时器0开始计时ET0=1;//使能定时器0中断EA=0;POWER_ON_TEMP=0;POWER_ON_TEMP_f=0;j=0;i=100;DELAY_1MS(100);WDT_CONTR=0x35;//启动看门狗while(1){WDT_CONTR=0x35;//启动看门狗if(ON_OFF_Flag==0)//上电标志,上电只执行一次{ON_OFF_Flag=1;READ_POWER_ON_TIME=IapReadByte(OFF_TIME_ADD);//////////////////////////////if(READ_POWER_ON_TIME!=4)//上电时间监测,小于4切换模式{test_num=IapReadByte(IAP_ADDRESS);//////////////////////////////if(test_num3)//LED_REDLED_GREEN{test_num=0;IapEraseSector(IAP_ADDRESS);IapProgramByte(IAP_ADDRESS,test_num);}}IapEraseSector(OFF_TIME_ADD);}/*---------------------------------------------------------------------*/EA=1;if(test_num==0){j=4;}elseif(test_num==1){j=20;}elseif(test_num==2){j=50;}elseif(test_num==3){j=99;}}}//-----------------------------------------------/*Timer0interruptroutine*/voidtm0_isr()interrupt1using1{if(i>0){i--;if(j
以上是程序代码!C程序调试OK
0
回复
2014-05-29 15:47
@yueyunno1
台灯适配器图片:[图片]台灯开关,增加的电路会装在这个开关中[图片]最暗时候的灯珠亮度[图片]最暗时候的PWM波形[图片]实际调试的电路[图片]一下是原理图,方块内部的部分电路最后全部装到适配器上的开关里[图片]
乐工新帖 支持!~~~
0
回复
2014-05-29 16:21
@电源网-娜娜姐
乐工新帖支持!~~~
感谢师长支持
0
回复
daihui713
LV.6
7
2014-05-29 16:38
@yueyunno1
以上是程序代码!C程序调试OK

通电时间大于6S,断电再开电时EEP数据不加1,保持当前亮度,小于6S内切换,断电开电EEP数据加1,亮度递增。乐云兄是这样不

0
回复
2014-05-29 17:13
@daihui713
通电时间大于6S,断电再开电时EEP数据不加1,保持当前亮度,小于6S内切换,断电开电EEP数据加1,亮度递增。乐云兄是这样不
对就是这个思路!
0
回复
cltwolf
LV.5
9
2014-05-30 11:46
@yueyunno1
感谢师长支持

继续支持

0
回复
2014-05-30 11:56
@cltwolf
继续支持
0
回复
mingquan23
LV.2
11
2014-06-24 09:37
你好,现在的LED有开关调光的IC,这样就能满足你说的这种调光方式。还有你这样会导致电源不停的工作在空载跟满载之间,有的电源的开路保护电压(OVP)设置过高很容易导致烧坏负载灯珠。你这个PWM的频率好像不高吧用手机会不会看到频闪啊?
0
回复
2014-06-25 15:26
@mingquan23
你好,现在的LED有开关调光的IC,这样就能满足你说的这种调光方式。还有你这样会导致电源不停的工作在空载跟满载之间,有的电源的开路保护电压(OVP)设置过高很容易导致烧坏负载灯珠。你这个PWM的频率好像不高吧用手机会不会看到频闪啊?
我这个是在原有的电源适配器上改进,你说的这个问题我也有想过,由于适配器是恒流源,对我影响也不会太大。单片机部分的功耗也很低,再加上MOS的导通方式为PWM方式,不是一瞬间接通也对LED灯珠起到了缓冲作用,PWM的频率不是太高。
0
回复
2014-06-25 15:26
@yueyunno1
我这个是在原有的电源适配器上改进,你说的这个问题我也有想过,由于适配器是恒流源,对我影响也不会太大。单片机部分的功耗也很低,再加上MOS的导通方式为PWM方式,不是一瞬间接通也对LED灯珠起到了缓冲作用,PWM的频率不是太高。

用手机会有闪烁的感觉

0
回复
xiao245896
LV.1
14
2014-06-28 08:36
@yueyunno1
用手机会有闪烁的感觉
这个很有用,呵呵空了我也回去照着改一个。
0
回复
book11
LV.3
15
2014-07-03 10:11
@yueyunno1
台灯适配器图片:[图片]台灯开关,增加的电路会装在这个开关中[图片]最暗时候的灯珠亮度[图片]最暗时候的PWM波形[图片]实际调试的电路[图片]一下是原理图,方块内部的部分电路最后全部装到适配器上的开关里[图片]
内部的EEPROM功能,资料上写10万次,是不是开个10万次就不能用了。多谢回复!
0
回复
挑战者
LV.5
16
2014-07-04 17:24
@yueyunno1
用手机会有闪烁的感觉
IAP_ADDRH = 0x80;               //将地址设置到非IAP区域
IAP_ADDRL = 0;
乐大师,这一句我一直在用,但一直不明白,为什么“IAP_ADDRH = 0x80”是“将地址设置到非IAP区域”?好像这样设置,还是在IAP区域内。
0
回复
2014-07-04 19:33
@挑战者
IAP_ADDRH=0x80;//将地址设置到非IAP区域IAP_ADDRL=0;乐大师,这一句我一直在用,但一直不明白,为什么“IAP_ADDRH=0x80”是“将地址设置到非IAP区域”?好像这样设置,还是在IAP区域内。
这个具体的内容你要去参考STC单片机官方的数据手册,这个我也没有太多的去关注。空了我去看看是个什么意思。
0
回复
挑战者
LV.5
18
2014-07-05 10:09
@yueyunno1
这个具体的内容你要去参考STC单片机官方的数据手册,这个我也没有太多的去关注。空了我去看看是个什么意思。

有已经深究过这一问题的高手吗?请赐教。

其实这一语句在官方文档中引用,偶从开始使用EEPROM时就照抄,但一直没搞明白为什么“IAP_ADDRH=0x80;  IAP_ADDRL=0;"是将地址设置到非IAP区域。如果从官方文档上看扇区地址,这样设置后还是在IAP区域内呀。

0
回复
科长2008
LV.3
19
2014-07-05 12:08
@挑战者
有已经深究过这一问题的高手吗?请赐教。其实这一语句在官方文档中引用,偶从开始使用EEPROM时就照抄,但一直没搞明白为什么“IAP_ADDRH=0x80; IAP_ADDRL=0;"是将地址设置到非IAP区域。如果从官方文档上看扇区地址,这样设置后还是在IAP区域内呀。
直接在MCU那做一个恒流源。这样更合实际。电压的波动对光线有影响的。
0
回复
2014-07-06 22:35
@科长2008
直接在MCU那做一个恒流源。这样更合实际。电压的波动对光线有影响的。
这个帖子是在现有的无调光台灯上进行改进,如果是自己单独设计肯定还是倾向于在电源上去处理,这个电源本身是一个固定恒流源输出,最亮的时候就是固定横流输出。其实主要还是考虑外观问题,适配器的电源开关内部的空间太小了,只能装下几个小元器件,如果做恒流源势必会有一个电感,这个电感是没有地方放的。
0
回复
zsl12570
LV.2
21
2014-07-14 16:03
@yueyunno1
#include"reg51.h"#include"intrins.h"typedefbitBOOL;typedefunsignedcharBYTE;typedefunsignedintWORD;#defineT1MS(65536-500)//12T模式sfrAUXR=0x8e;//Auxiliaryregister/*---------------------------------------------------------------------*//*--端口定义---------------------------------------*//*---------------------------------------------------------------------*/#definePORT_3P3#defineHIGH1#defineLOW0sbitPWM_OUT_PORT=P3^2;//LED_REDLED_GREENsbitLED=P3^3;/*---------------------------------------------------------------------*//*--变量定义---------------------------------------*//*---------------------------------------------------------------------*/BYTEi,j;BYTEtest_num;BYTEPOWER_ON_TEMP_f;BYTEPOWER_ON_TIME;BYTEREAD_POWER_ON_TIME;BOOLON_OFF_Flag;unsignedlongPOWER_ON_TEMP;//-----------------------------------------------sfrIAP_DATA=0xC2;//IAP数据寄存器sfrIAP_ADDRH=0xC3;//IAP地址寄存器高字节sfrIAP_ADDRL=0xC4;//IAP地址寄存器低字节sfrIAP_CMD=0xC5;//IAP命令寄存器sfrIAP_TRIG=0xC6;//IAP命令触发寄存器sfrIAP_CONTR=0xC7;//IAP控制寄存器sfrWDT_CONTR=0xC1;//0000,0000看门狗控制寄存器sfrP3M0=0xB2;//0000,0000端口3模式寄存器0sfrP3M1=0xB1;//0000,0000端口3模式寄存器1#defineCMD_IDLE0//空闲模式#defineCMD_READ1//IAP字节读命令#defineCMD_PROGRAM2//IAP字节编程命令#defineCMD_ERASE3//IAP扇区擦除命令#defineENABLE_IAP0x83//ifSYSCLK>8;//设置IAP高地址IAP_TRIG=0x5a;//写触发命令(0x5a)IAP_TRIG=0xa5;//写触发命令(0xa5)_nop_();//等待ISP/IAP/EEPROM操作完成dat=IAP_DATA;//读ISP/IAP/EEPROM数据IapIdle();//关闭IAP功能returndat;//返回}/*----------------------------写一字节数据到ISP/IAP/EEPROM区域----------------------------*/voidIapProgramByte(WORDaddr,BYTEdat){IAP_CONTR=ENABLE_IAP;//使能IAPIAP_CMD=CMD_PROGRAM;//设置IAP命令IAP_ADDRL=addr;//设置IAP低地址IAP_ADDRH=addr>>8;//设置IAP高地址IAP_DATA=dat;//写ISP/IAP/EEPROM数据IAP_TRIG=0x5a;//写触发命令(0x5a)IAP_TRIG=0xa5;//写触发命令(0xa5)_nop_();//等待ISP/IAP/EEPROM操作完成IapIdle();}/*----------------------------扇区擦除----------------------------*/voidIapEraseSector(WORDaddr){IAP_CONTR=ENABLE_IAP;//使能IAPIAP_CMD=CMD_ERASE;//设置IAP命令IAP_ADDRL=addr;//设置IAP低地址IAP_ADDRH=addr>>8;//设置IAP高地址IAP_TRIG=0x5a;//写触发命令(0x5a)IAP_TRIG=0xa5;//写触发命令(0xa5)_nop_();//等待ISP/IAP/EEPROM操作完成IapIdle();}/*---------------------------------------------------------------------*//*--延时子程序---------------------------------------*//*---------------------------------------------------------------------*/voidDELAY_1MS(unsignedintz){unsignedintx,y;for(x=z;x>0;x--)for(y=123;y>0;y--);}/*---------------------------------------------------------------------*//*--主程序---------------------------------------*//*---------------------------------------------------------------------*/voidmain(){PORT_3=0X00;P3M0=0xFF;P3M1=0x00;ON_OFF_Flag=0;POWER_ON_TIME=0;READ_POWER_ON_TIME=0;AUXR|=0x80;//定时器0为1T模式//AUXR&=0x7f;//定时器0为12T模式TMOD=0x00;//设置定时器为模式0(16位自动重装载)TL0=T1MS;//初始化计时值TH0=T1MS>>8;TR0=1;//定时器0开始计时ET0=1;//使能定时器0中断EA=0;POWER_ON_TEMP=0;POWER_ON_TEMP_f=0;j=0;i=100;DELAY_1MS(100);WDT_CONTR=0x35;//启动看门狗while(1){WDT_CONTR=0x35;//启动看门狗if(ON_OFF_Flag==0)//上电标志,上电只执行一次{ON_OFF_Flag=1;READ_POWER_ON_TIME=IapReadByte(OFF_TIME_ADD);//////////////////////////////if(READ_POWER_ON_TIME!=4)//上电时间监测,小于4切换模式{test_num=IapReadByte(IAP_ADDRESS);//////////////////////////////if(test_num3)//LED_REDLED_GREEN{test_num=0;IapEraseSector(IAP_ADDRESS);IapProgramByte(IAP_ADDRESS,test_num);}}IapEraseSector(OFF_TIME_ADD);}/*---------------------------------------------------------------------*/EA=1;if(test_num==0){j=4;}elseif(test_num==1){j=20;}elseif(test_num==2){j=50;}elseif(test_num==3){j=99;}}}//-----------------------------------------------/*Timer0interruptroutine*/voidtm0_isr()interrupt1using1{if(i>0){i--;if(j
来看看!
0
回复
0565pan
LV.8
22
2014-07-27 13:55
@yueyunno1
这个帖子是在现有的无调光台灯上进行改进,如果是自己单独设计肯定还是倾向于在电源上去处理,这个电源本身是一个固定恒流源输出,最亮的时候就是固定横流输出。其实主要还是考虑外观问题,适配器的电源开关内部的空间太小了,只能装下几个小元器件,如果做恒流源势必会有一个电感,这个电感是没有地方放的。
加个点留个记号!学习!
0
回复
rocky.lgz
LV.1
23
2014-08-06 11:04
@yueyunno1
#include"reg51.h"#include"intrins.h"typedefbitBOOL;typedefunsignedcharBYTE;typedefunsignedintWORD;#defineT1MS(65536-500)//12T模式sfrAUXR=0x8e;//Auxiliaryregister/*---------------------------------------------------------------------*//*--端口定义---------------------------------------*//*---------------------------------------------------------------------*/#definePORT_3P3#defineHIGH1#defineLOW0sbitPWM_OUT_PORT=P3^2;//LED_REDLED_GREENsbitLED=P3^3;/*---------------------------------------------------------------------*//*--变量定义---------------------------------------*//*---------------------------------------------------------------------*/BYTEi,j;BYTEtest_num;BYTEPOWER_ON_TEMP_f;BYTEPOWER_ON_TIME;BYTEREAD_POWER_ON_TIME;BOOLON_OFF_Flag;unsignedlongPOWER_ON_TEMP;//-----------------------------------------------sfrIAP_DATA=0xC2;//IAP数据寄存器sfrIAP_ADDRH=0xC3;//IAP地址寄存器高字节sfrIAP_ADDRL=0xC4;//IAP地址寄存器低字节sfrIAP_CMD=0xC5;//IAP命令寄存器sfrIAP_TRIG=0xC6;//IAP命令触发寄存器sfrIAP_CONTR=0xC7;//IAP控制寄存器sfrWDT_CONTR=0xC1;//0000,0000看门狗控制寄存器sfrP3M0=0xB2;//0000,0000端口3模式寄存器0sfrP3M1=0xB1;//0000,0000端口3模式寄存器1#defineCMD_IDLE0//空闲模式#defineCMD_READ1//IAP字节读命令#defineCMD_PROGRAM2//IAP字节编程命令#defineCMD_ERASE3//IAP扇区擦除命令#defineENABLE_IAP0x83//ifSYSCLK>8;//设置IAP高地址IAP_TRIG=0x5a;//写触发命令(0x5a)IAP_TRIG=0xa5;//写触发命令(0xa5)_nop_();//等待ISP/IAP/EEPROM操作完成dat=IAP_DATA;//读ISP/IAP/EEPROM数据IapIdle();//关闭IAP功能returndat;//返回}/*----------------------------写一字节数据到ISP/IAP/EEPROM区域----------------------------*/voidIapProgramByte(WORDaddr,BYTEdat){IAP_CONTR=ENABLE_IAP;//使能IAPIAP_CMD=CMD_PROGRAM;//设置IAP命令IAP_ADDRL=addr;//设置IAP低地址IAP_ADDRH=addr>>8;//设置IAP高地址IAP_DATA=dat;//写ISP/IAP/EEPROM数据IAP_TRIG=0x5a;//写触发命令(0x5a)IAP_TRIG=0xa5;//写触发命令(0xa5)_nop_();//等待ISP/IAP/EEPROM操作完成IapIdle();}/*----------------------------扇区擦除----------------------------*/voidIapEraseSector(WORDaddr){IAP_CONTR=ENABLE_IAP;//使能IAPIAP_CMD=CMD_ERASE;//设置IAP命令IAP_ADDRL=addr;//设置IAP低地址IAP_ADDRH=addr>>8;//设置IAP高地址IAP_TRIG=0x5a;//写触发命令(0x5a)IAP_TRIG=0xa5;//写触发命令(0xa5)_nop_();//等待ISP/IAP/EEPROM操作完成IapIdle();}/*---------------------------------------------------------------------*//*--延时子程序---------------------------------------*//*---------------------------------------------------------------------*/voidDELAY_1MS(unsignedintz){unsignedintx,y;for(x=z;x>0;x--)for(y=123;y>0;y--);}/*---------------------------------------------------------------------*//*--主程序---------------------------------------*//*---------------------------------------------------------------------*/voidmain(){PORT_3=0X00;P3M0=0xFF;P3M1=0x00;ON_OFF_Flag=0;POWER_ON_TIME=0;READ_POWER_ON_TIME=0;AUXR|=0x80;//定时器0为1T模式//AUXR&=0x7f;//定时器0为12T模式TMOD=0x00;//设置定时器为模式0(16位自动重装载)TL0=T1MS;//初始化计时值TH0=T1MS>>8;TR0=1;//定时器0开始计时ET0=1;//使能定时器0中断EA=0;POWER_ON_TEMP=0;POWER_ON_TEMP_f=0;j=0;i=100;DELAY_1MS(100);WDT_CONTR=0x35;//启动看门狗while(1){WDT_CONTR=0x35;//启动看门狗if(ON_OFF_Flag==0)//上电标志,上电只执行一次{ON_OFF_Flag=1;READ_POWER_ON_TIME=IapReadByte(OFF_TIME_ADD);//////////////////////////////if(READ_POWER_ON_TIME!=4)//上电时间监测,小于4切换模式{test_num=IapReadByte(IAP_ADDRESS);//////////////////////////////if(test_num3)//LED_REDLED_GREEN{test_num=0;IapEraseSector(IAP_ADDRESS);IapProgramByte(IAP_ADDRESS,test_num);}}IapEraseSector(OFF_TIME_ADD);}/*---------------------------------------------------------------------*/EA=1;if(test_num==0){j=4;}elseif(test_num==1){j=20;}elseif(test_num==2){j=50;}elseif(test_num==3){j=99;}}}//-----------------------------------------------/*Timer0interruptroutine*/voidtm0_isr()interrupt1using1{if(i>0){i--;if(j
学习了,
0
回复
rocky.lgz
LV.1
24
2014-08-06 11:14
@yueyunno1
这个帖子是在现有的无调光台灯上进行改进,如果是自己单独设计肯定还是倾向于在电源上去处理,这个电源本身是一个固定恒流源输出,最亮的时候就是固定横流输出。其实主要还是考虑外观问题,适配器的电源开关内部的空间太小了,只能装下几个小元器件,如果做恒流源势必会有一个电感,这个电感是没有地方放的。

用低压线性IC  没有电感,一个sop8的IC就可以了。

0
回复
book11
LV.3
25
2014-08-13 17:27
@yueyunno1
#include"reg51.h"#include"intrins.h"typedefbitBOOL;typedefunsignedcharBYTE;typedefunsignedintWORD;#defineT1MS(65536-500)//12T模式sfrAUXR=0x8e;//Auxiliaryregister/*---------------------------------------------------------------------*//*--端口定义---------------------------------------*//*---------------------------------------------------------------------*/#definePORT_3P3#defineHIGH1#defineLOW0sbitPWM_OUT_PORT=P3^2;//LED_REDLED_GREENsbitLED=P3^3;/*---------------------------------------------------------------------*//*--变量定义---------------------------------------*//*---------------------------------------------------------------------*/BYTEi,j;BYTEtest_num;BYTEPOWER_ON_TEMP_f;BYTEPOWER_ON_TIME;BYTEREAD_POWER_ON_TIME;BOOLON_OFF_Flag;unsignedlongPOWER_ON_TEMP;//-----------------------------------------------sfrIAP_DATA=0xC2;//IAP数据寄存器sfrIAP_ADDRH=0xC3;//IAP地址寄存器高字节sfrIAP_ADDRL=0xC4;//IAP地址寄存器低字节sfrIAP_CMD=0xC5;//IAP命令寄存器sfrIAP_TRIG=0xC6;//IAP命令触发寄存器sfrIAP_CONTR=0xC7;//IAP控制寄存器sfrWDT_CONTR=0xC1;//0000,0000看门狗控制寄存器sfrP3M0=0xB2;//0000,0000端口3模式寄存器0sfrP3M1=0xB1;//0000,0000端口3模式寄存器1#defineCMD_IDLE0//空闲模式#defineCMD_READ1//IAP字节读命令#defineCMD_PROGRAM2//IAP字节编程命令#defineCMD_ERASE3//IAP扇区擦除命令#defineENABLE_IAP0x83//ifSYSCLK>8;//设置IAP高地址IAP_TRIG=0x5a;//写触发命令(0x5a)IAP_TRIG=0xa5;//写触发命令(0xa5)_nop_();//等待ISP/IAP/EEPROM操作完成dat=IAP_DATA;//读ISP/IAP/EEPROM数据IapIdle();//关闭IAP功能returndat;//返回}/*----------------------------写一字节数据到ISP/IAP/EEPROM区域----------------------------*/voidIapProgramByte(WORDaddr,BYTEdat){IAP_CONTR=ENABLE_IAP;//使能IAPIAP_CMD=CMD_PROGRAM;//设置IAP命令IAP_ADDRL=addr;//设置IAP低地址IAP_ADDRH=addr>>8;//设置IAP高地址IAP_DATA=dat;//写ISP/IAP/EEPROM数据IAP_TRIG=0x5a;//写触发命令(0x5a)IAP_TRIG=0xa5;//写触发命令(0xa5)_nop_();//等待ISP/IAP/EEPROM操作完成IapIdle();}/*----------------------------扇区擦除----------------------------*/voidIapEraseSector(WORDaddr){IAP_CONTR=ENABLE_IAP;//使能IAPIAP_CMD=CMD_ERASE;//设置IAP命令IAP_ADDRL=addr;//设置IAP低地址IAP_ADDRH=addr>>8;//设置IAP高地址IAP_TRIG=0x5a;//写触发命令(0x5a)IAP_TRIG=0xa5;//写触发命令(0xa5)_nop_();//等待ISP/IAP/EEPROM操作完成IapIdle();}/*---------------------------------------------------------------------*//*--延时子程序---------------------------------------*//*---------------------------------------------------------------------*/voidDELAY_1MS(unsignedintz){unsignedintx,y;for(x=z;x>0;x--)for(y=123;y>0;y--);}/*---------------------------------------------------------------------*//*--主程序---------------------------------------*//*---------------------------------------------------------------------*/voidmain(){PORT_3=0X00;P3M0=0xFF;P3M1=0x00;ON_OFF_Flag=0;POWER_ON_TIME=0;READ_POWER_ON_TIME=0;AUXR|=0x80;//定时器0为1T模式//AUXR&=0x7f;//定时器0为12T模式TMOD=0x00;//设置定时器为模式0(16位自动重装载)TL0=T1MS;//初始化计时值TH0=T1MS>>8;TR0=1;//定时器0开始计时ET0=1;//使能定时器0中断EA=0;POWER_ON_TEMP=0;POWER_ON_TEMP_f=0;j=0;i=100;DELAY_1MS(100);WDT_CONTR=0x35;//启动看门狗while(1){WDT_CONTR=0x35;//启动看门狗if(ON_OFF_Flag==0)//上电标志,上电只执行一次{ON_OFF_Flag=1;READ_POWER_ON_TIME=IapReadByte(OFF_TIME_ADD);//////////////////////////////if(READ_POWER_ON_TIME!=4)//上电时间监测,小于4切换模式{test_num=IapReadByte(IAP_ADDRESS);//////////////////////////////if(test_num3)//LED_REDLED_GREEN{test_num=0;IapEraseSector(IAP_ADDRESS);IapProgramByte(IAP_ADDRESS,test_num);}}IapEraseSector(OFF_TIME_ADD);}/*---------------------------------------------------------------------*/EA=1;if(test_num==0){j=4;}elseif(test_num==1){j=20;}elseif(test_num==2){j=50;}elseif(test_num==3){j=99;}}}//-----------------------------------------------/*Timer0interruptroutine*/voidtm0_isr()interrupt1using1{if(i>0){i--;if(j

#define T1MS (65536-500) 

TL0 = T1MS;                     //初始化计时值  

TH0 = T1MS >> 8; 

这个》8是什么意思?

我见到的写法是:

TL0 =(65536-500)/256;                 

TH0 = (65536-500)%256 ;

这有什么区别吗?

0
回复
2014-08-14 08:42
@book11
#defineT1MS(65536-500) TL0=T1MS;          //初始化计时值  TH0=T1MS>>8; 这个》8是什么意思?我见到的写法是:TL0=(65536-500)/256;         TH0=(65536-500)%256 ;这有什么区别吗?

最后的输出结果是一样的,做了右移6处理,例如:11110000   右移2位  x x111100   在C中右移后最左边以前的位置会补0,即XX=00.

0
回复
book11
LV.3
27
2014-08-14 16:47
@yueyunno1
最后的输出结果是一样的,做了右移6处理,例如:11110000 右移2位 xx111100 在C中右移后最左边以前的位置会补0,即XX=00.
这个定时器模式为什么用1T模式,  
 AUXR |= 0x80;        //定时器0为1T模式
如果不写上面的语句是默认12T模式吗,如果是12T模式,会是什么效果?
0
回复
2014-08-18 11:43
@book11
这个定时器模式为什么用1T模式,   AUXR|=0x80;//定时器0为1T模式如果不写上面的语句是默认12T模式吗,如果是12T模式,会是什么效果?
同样的初值,12T模式会比1T模式慢,就相当于1T在超频,你这样去理解。
0
回复
book11
LV.3
29
2014-08-18 12:42
@yueyunno1
同样的初值,12T模式会比1T模式慢,就相当于1T在超频,你这样去理解。
stc89c52  好像没有1T模式,我想把这个程序的PWM用在stc89c52上,试了不行,还得学习呀。
0
回复
2014-08-18 15:10
@book11
stc89c52 好像没有1T模式,我想把这个程序的PWM用在stc89c52上,试了不行,还得学习呀。
STC89c52是不行的,你直接买个STC15F2K61的芯片,但是要注意电源脚,引脚不兼容
0
回复
book11
LV.3
31
2014-08-18 15:15
@yueyunno1
STC89c52是不行的,你直接买个STC15F2K61的芯片,但是要注意电源脚,引脚不兼容
知道了,谢谢!
0
回复