PIC12F508單片機(jī)是沒有中斷的,定時器、按鍵中斷只能是查詢方式。
編譯器用的XC8,編譯環(huán)境IDE用的是MPLAB X IDE。
下載器是PICKIT3.
原來的電風(fēng)扇就兩個檔,不能搖頭,一直對著人吹,對健康不利。所以進(jìn)行改造。
功能與結(jié)構(gòu):
兩個LED是指示燈,閃爍是為了省電。
控制器交流電用的是TLP3503,是光耦可控硅。
按鍵可以選擇弱風(fēng)、中風(fēng)、強(qiáng)風(fēng)和關(guān)機(jī),關(guān)機(jī)后,單片機(jī)是掉電模式。關(guān)機(jī)模式時,此按鍵可以把單片機(jī)喚醒。
不管什么情況,只要不按鍵,半個小時候,關(guān)機(jī),處于掉電模式
電路圖:

用萬用板焊接的線路板以及和風(fēng)扇的結(jié)合。

程序:
/
void wind ();
uchar read_key(void);
void keycount();
void DelayMs(unsigned int msec);
void Init()
{
TRIS=~0x3F; //GP3輸入,其它輸出
OPTION = 0x84; //分頻器給定時器 32 4MHz
TMR0=0x64; //5ms x=257-tJ/4F
Fan_Open=1;
LED1_F=1;
LED2_F=1;
Delay_Time=1800;
}
void main()
{
Init();
while(1)
{
// if((GPWUF==1)&&(KEY1==0)) //引腳引起的中斷喚醒
// {
// Init();
// }
if(Fan_Open==0)
{
FAN1=OFF;
FAN2=OFF;
LED1=OFF;
LED2=OFF;
LED2_F=0;
LED1_F=0;
DelayMs(2000);//延時一段時間,避免按鍵沒有起來就喚醒單片機(jī)了。
OPTION =0x24; //引腳中斷喚醒使能 弱上拉使能
// KEY_F2=KEY2;
KEY_F1=KEY1; //讀出休眠前的按鍵狀態(tài)。
SLEEP();
}
if(TMR0==0xFF)
{
TMR0=0x63; //
keycount();
count++;
if((count==100)||(count==200))
{
if(LED1_F==1)
{
LED1=~LED1;
}
if(LED2_F==1)
{
LED2=~LED2;
}
}
if(count==200)//1s
{
count=0;
if(Fan_Open==1)
{
wind ();
}
Delay_Time--;
if(Delay_Time==0)//30分鐘后全關(guān)閉,要重新按鍵開機(jī)才行
{
Fan_Open=0;
}
}
}
}
}
void wind ()
{
static unsigned char KeyTask1=0,KeyTime1;
{
switch(KeyTask1)
{
case 0:
FAN1=ON;
FAN2=OFF;
KeyTime1=speed1;
KeyTask1=1;
break;
case 1:
KeyTime1--;
if(KeyTime1==0) KeyTask1=2;
break;
case 2:
FAN1=OFF;
FAN2=OFF;
KeyTime1=speed2;
KeyTask1=3;
break;
case 3:
KeyTime1--;
if(KeyTime1==0) KeyTask1=4;
break;
case 4:
FAN1=OFF;
FAN2=ON;
KeyTime1=speed3;
KeyTask1=5;
break;
case 5:
KeyTime1--;
if(KeyTime1==0) KeyTask1=6;
break;
case 6:
FAN1=OFF;
FAN2=OFF;
KeyTime1=speed4;
KeyTask1=7;
break;
case 7:
KeyTime1--;
if(KeyTime1==0) KeyTask1=0;
break;
default:
break;
}
}
}
uchar read_key(void)
{
static unsigned char KeyTask=0,KeyTime;
unsigned char KeyVal=0;
switch(KeyTask)
{
case 0:
if (KEY1==0)
{
KeyTime=4;
KeyTask++;
}
break;
case 1: KeyTime--;
if(KeyTime==0) KeyTask++;
break;
case 2:
if (KEY1==0)
{
if(KEY1==0) {KeyVal=1;}
KeyTask++;
}
else KeyTask=0;
break;
case 3:
if(KEY1==1)
{
KeyTime=4;
KeyTask++;
}
break;
case 4:
KeyTime--;
if(KeyTime==0)KeyTask++;
break;
case 5:
if(KEY1==1)
{
KeyTask=0;
}
else
{
KeyTask=3;
}
break;
default:
break;
}
return KeyVal;
}
void keycount()
{
uchar Key=0;
Key = read_key();
if(Key!=0)
{
Delay_Time=1800;
if((Key==1)&&(Fan_Open==1)) //關(guān)閉的時候不響應(yīng)
{
if(++model==5)
{
model=0;
}
switch(model)
{
case 1: //弱風(fēng)
speed1=1;
speed2=5;
speed3=3;
speed4=5;
LED2=OFF;
LED1=ON;
LED1_F=1;
LED2_F=0;
break;
case 2: //中風(fēng)
speed1=5;
speed2=5;
speed3=5;
speed4=5;
LED1=OFF;
LED2=ON;
LED2_F=1;
LED1_F=0;
break;
case 3: //強(qiáng)風(fēng)
speed1=5;
speed2=3;
speed3=5;
speed4=3;
LED1=ON;
LED2=ON;
LED1_F=1;
LED2_F=1;
break;
case 4:
Fan_Open=0;
break;
default:
break;
}
}
}
Key=0;
}
void DelayMs(unsigned int msec)
{
unsigned int x,y;
for(x=0; x<=msec;x++)
{
for(y=0;y<=110;y++);
}
}
/
void wind ();
uchar read_key(void);
void keycount();
void DelayMs(unsigned int msec);
void Init()
{
TRIS=~0x3F; //GP3輸入,其它輸出
OPTION = 0x84; //分頻器給定時器 32 4MHz
TMR0=0x64; //5ms x=257-tJ/4F
Fan_Open=1;
LED1_F=1;
LED2_F=1;
Delay_Time=1800;
}
void main()
{
Init();
while(1)
{
// if((GPWUF==1)&&(KEY1==0)) //引腳引起的中斷喚醒
// {
// Init();
// }
if(Fan_Open==0)
{
FAN1=OFF;
FAN2=OFF;
LED1=OFF;
LED2=OFF;
LED2_F=0;
LED1_F=0;
DelayMs(2000);//延時一段時間,避免按鍵沒有起來就喚醒單片機(jī)了。
OPTION =0x24; //引腳中斷喚醒使能 弱上拉使能
// KEY_F2=KEY2;
KEY_F1=KEY1; //讀出休眠前的按鍵狀態(tài)。
SLEEP();
}
if(TMR0==0xFF)
{
TMR0=0x63; //
keycount();
count++;
if((count==100)||(count==200))
{
if(LED1_F==1)
{
LED1=~LED1;
}
if(LED2_F==1)
{
LED2=~LED2;
}
}
if(count==200)//1s
{
count=0;
if(Fan_Open==1)
{
wind ();
}
Delay_Time--;
if(Delay_Time==0)//30分鐘后全關(guān)閉,要重新按鍵開機(jī)才行
{
Fan_Open=0;
}
}
}
}
}
void wind ()
{
static unsigned char KeyTask1=0,KeyTime1;
{
switch(KeyTask1)
{
case 0:
FAN1=ON;
FAN2=OFF;
KeyTime1=speed1;
KeyTask1=1;
break;
case 1:
KeyTime1--;
if(KeyTime1==0) KeyTask1=2;
break;
case 2:
FAN1=OFF;
FAN2=OFF;
KeyTime1=speed2;
KeyTask1=3;
break;
case 3:
KeyTime1--;
if(KeyTime1==0) KeyTask1=4;
break;
case 4:
FAN1=OFF;
FAN2=ON;
KeyTime1=speed3;
KeyTask1=5;
break;
case 5:
KeyTime1--;
if(KeyTime1==0) KeyTask1=6;
break;
case 6:
FAN1=OFF;
FAN2=OFF;
KeyTime1=speed4;
KeyTask1=7;
break;
case 7:
KeyTime1--;
if(KeyTime1==0) KeyTask1=0;
break;
default:
break;
}
}
}
uchar read_key(void)
{
static unsigned char KeyTask=0,KeyTime;
unsigned char KeyVal=0;
switch(KeyTask)
{
case 0:
if (KEY1==0)
{
KeyTime=4;
KeyTask++;
}
break;
case 1: KeyTime--;
if(KeyTime==0) KeyTask++;
break;
case 2:
if (KEY1==0)
{
if(KEY1==0) {KeyVal=1;}
KeyTask++;
}
else KeyTask=0;
break;
case 3:
if(KEY1==1)
{
KeyTime=4;
KeyTask++;
}
break;
case 4:
KeyTime--;
if(KeyTime==0)KeyTask++;
break;
case 5:
if(KEY1==1)
{
KeyTask=0;
}
else
{
KeyTask=3;
}
break;
default:
break;
}
return KeyVal;
}
void keycount()
{
uchar Key=0;
Key = read_key();
if(Key!=0)
{
Delay_Time=1800;
if((Key==1)&&(Fan_Open==1)) //關(guān)閉的時候不響應(yīng)
{
if(++model==5)
{
model=0;
}
switch(model)
{
case 1: //弱風(fēng)
speed1=1;
speed2=5;
speed3=3;
speed4=5;
LED2=OFF;
LED1=ON;
LED1_F=1;
LED2_F=0;
break;
case 2: //中風(fēng)
speed1=5;
speed2=5;
speed3=5;
speed4=5;
LED1=OFF;
LED2=ON;
LED2_F=1;
LED1_F=0;
break;
case 3: //強(qiáng)風(fēng)
speed1=5;
speed2=3;
speed3=5;
speed4=3;
LED1=ON;
LED2=ON;
LED1_F=1;
LED2_F=1;
break;
case 4:
Fan_Open=0;
break;
default:
break;
}
}
}
Key=0;
}
void DelayMs(unsigned int msec)
{
unsigned int x,y;
for(x=0; x<=msec;x++)
{
for(y=0;y<=110;y++);
}
}