/*一、功能說明:
此程序是一款普通的彩燈,它通過電源
開關控制四種模式,即關掉電源然后打開電源就可以改變
一種模式,它的功能主要有四種模式分別如下:第一種模式
:開機四種顏色以0.5秒速度循環1次,然后在白顏色上停止
循環,即顯示白光第二種模式:按下功能鍵后,它以1秒
速度四種顏色不停的循環第三種模式:當按鍵按下后它會
記住第二種模式的顏色,比如第二種模式現在亮得是綠色,
你按下按鍵時,它會先閃一下,然后在綠顏色上停下來第
四模式:當你再按下開關時,它自動回到模式一下,在模式
三下,當它斷電時,可以記住模式三 些產品特點:利用
電源開關切換功能,斷電數據保存,起到減小EEPROM擦除
次數.程序部分轉自51單片機www.zg4o1577.cn已測試ok*/
/*三、完整的參考程序:點擊下載 */
#include<reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
sfr DATA=0xE2;//數據寄存器
sfr ADDRH=0xE3;//地址寄存器高八位
sfr ADDRL=0xE4;//地址寄存器低八位
sfr CMD=0xE5;//命令模式寄存器
sfr TRIG=0xE6;//命令觸發寄存器
sfr CONTR=0xE7;//控制寄存器
sbit RJ=P2^5;//紅燈IO口
sbit GJ=P2^6;//綠燈IO口
sbit BJ=P2^7;//蘭燈IO口
uchar ding3,yin,x,m;//分別為定時器變量,標志位變量,以及顏色標志位變量
bit a=1,b,c;//分別為模式1.2.3標志位
/*******************************/
/***********延時子程序***********/
/*******************************/
void delay(uint z)
{
uint x,y;
for(x=100;x>0;x--)
for(y=z;y>0;y--);
}
/*******************************/
/*********讀EEPROM子程序*********/
/*******************************/
uchar read(uint add)
{
CONTR=0x81;//控制寄存器打開,12MHZ晶體,所以將時間設為01
CMD=0x01;//設置EEPROM為讀的方式(1)
ADDRH=(add>>=8);//給高位數
ADDRL=add&(0x00ff);//給低位數
TRIG=0x46;//激活
TRIG=0xb9;//激活
_nop_();//延時
CONTR=0x00;//保護起來
TRIG=0X00;//保護起來
return DATA;//將讀出來的值返回
}
/*******************************/
/*********寫EEPROM子程序*********/
/*******************************/
void program(uint add,uchar vale)//add為寫數地址 vale為要存得數
{
CONTR=0x81;//控制寄存器打開,12MHZ晶體,所以將時間設為01
CMD=0X02;//設置EEPROM為寫的方式(2)
ADDRH=(add>>=8);
ADDRL=add&(0x00ff);
DATA=vale;//將要存的數放到寄存器內
TRIG=0x46;
TRIG=0xb9;
_nop_();
CONTR=0x00;
TRIG=0X00;
}
/*******************************/
/*****擦除EEPROM子程序*******/
/*******************************/
void sector(uint add)
{
CONTR=0x81;//控制寄存器打開,12MHZ晶體,所以將時間設為01
CMD=0x03;//設置EEPROM為擦除的方式(3)
ADDRH=(add>>=8);//給高位數
ADDRL=add&(0x00ff);//給低位數
TRIG=0x46;
TRIG=0xb9;
_nop_();
CONTR=0x00;
TRIG=0X00;
}
/*******************************/
/*******三種模式顯示子程序******/
/*******************************/
void xian()
{
if(a!=0)//第一種模式以0.5秒速度循環閃爍一次,然后在白光處停下來
{
if(ding3>=10)//定時器到了0.5秒嗎?
{
ding3=0;
x++;//將標志位加1,以便進入下一種顏色
switch(x)
{
case 1:RJ=1;GJ=0;BJ=0;//亮紅光
break;
case 2:RJ=0;GJ=1;BJ=0;//亮綠光
break;
case 3:RJ=0;GJ=0;BJ=1;//亮蘭光
break;
case 4:RJ=1;GJ=1;BJ=1;a=0;//亮白光,//將標志位a清0,以便再次循環
break;
}
}
}
if(b!=0)//第二種模式以1秒速度一直循環閃爍。
{
if(ding3>=20)
{
ding3=0;
x++;
switch(x)
{
case 1:RJ=1;GJ=0;BJ=0;m=x;//將x變量內給m保存起來,以便進入模式三時能準確的鎖定一種狀態
break;
case 2:RJ=0;GJ=1;BJ=0;m=x;
break;
case 3:RJ=0;GJ=0;BJ=1;m=x;
break;
case 4:RJ=1;GJ=1;BJ=1;m=x;x=0;
break;
}
}
}
if(c!=0)//第三種模式記住模式二時按鍵按下的顏色,然后鎖定。
{
RJ=0;GJ=0;BJ=0;
delay(550);
switch(m)//判斷上一次模式三的狀態,然后確定顯示哪種顏色
{
case 1:RJ=1;GJ=0;BJ=0;
break;
case 2:RJ=0;GJ=1;BJ=0;
break;
case 3:RJ=0;GJ=0;BJ=1;
break;
case 4:RJ=1;GJ=1;BJ=1;
break;
}
c=0;//將標志位清0,以便再次循環
}
}
/*******************************/
/*************主程序************/
/*******************************/
void main()
{
RJ=0;//將R LED關閉
GJ=0;//將G LED關閉
BJ=0;//將B LED關閉
TMOD=0X01;//寄存器工作方式
EA=1;//開總中斷
TR0=1;//開定時器
ET0=1;//開定時器中斷
IT0=1;
EX0=1;
TH0=(65536-50000)/256;//賦值給高位
TL0=(65536-50000)%256;//賦值給低位
if(read(0x2200)==0x03)//開機檢測是否是在第三種模式下,如果下則讀出斷電時的數據(即顏色)
{
m=read(0x2000);//讀出斷電時的顏色
a=0;//將模式1關閉
b=0;//將模式2關閉
c=1;//將模式3打開
}
else
{
a=1;//將模式1打開
b=0;//將模式2關閉
c=0;//將模式3關閉
}
while(1)
xian();//調用顯示子程序
}
void zhong() interrupt 1//T1中斷服務程序
{
TH0=(65536-50000)/256;//賦值給高位
TL0=(65536-50000)%256;//賦值給低位
ding3++;//將按鍵計數器加1
}
void zhongk() interrupt 0
{
/*******************************/
/****按鍵處理及數據保存子程序***/
/*******************************/
EX0=0;
switch(yin)//執行一鍵多功能程序
{
case 0://如果0與yin比較相等,則執行break前的所有內容
delay(100);
sector(0x2200);//擦除
program(0x2200,0x02);//在0x2200地址處寫入數0x02
delay(100);
yin++;//將變量加1,此句很重要,作用是以使下次按下時好執行下一開關語句
a=0;//將a變為0
c=0;
b=1;//將b變為1,即打開按鍵程序中的第二段程序
x=0;//清掉顏色計數變量,以便它從紅色開始循環
break;//退出開關語句
case 1:
delay(100);
sector(0x2200);//擦除
program(0x2200,0x03);//在0x2200地址處寫入數0x03
sector(0x2000);////擦除
program(0x2000,m);//在0x2000地址處寫入變量m,以便在模式三下形成斷電保護
delay(100);
yin++;//將變量加1,此句很重要,作用是以使下次按下時好執行下一開關語句
b=0;
c=1;//打開第三種模式標志位,即鎖定狀態
a=0;
x=0;//清掉顏色計數變量,以便它從紅色開始循環
break;//退出開關語句
case 2:
delay(100);
sector(0x2200);//擦除
program(0x2200,0x01);//在0x2200地址處寫入數0x01
delay(100);
b=0;//將b變為0,即關閉上一次功能
c=0;//關閉上前面的功能
a=1;//打開第1次功能,即0.5秒循環閃爍
yin=0;
x=0;//清掉顏色計數變量,以便它從紅色開始循環
break;//退出開關語句
}
delay(255);
EX0=1;
}