|
大家好。今天我要分享的是一款DIY延時(shí)插座。延時(shí)插座并不是新東西,壇子里好幾位前輩分享過(guò)類似制作。正是因?yàn)榭吹剿麄兊淖髌罚也湃滩蛔∽约阂沧鲆粋(gè),這樣才能真正鍛煉自已。先上制作出來(lái)的成品圖如下:
成品.jpg (111.01 KB, 下載次數(shù): 218)
下載附件
2021-1-24 20:13 上傳
功能:
* 可選擇延時(shí)斷電或延時(shí)上電工作方式,在開(kāi)機(jī)前操作黑色的小開(kāi)關(guān)進(jìn)行設(shè)置。
* 定時(shí)時(shí)間可設(shè)置范圍:1分鐘~99小時(shí)59分鐘。
* 短按按鍵1分鐘加1,長(zhǎng)按按鍵1小時(shí)加1 ,在停止和啟動(dòng)狀態(tài)下均可調(diào)整時(shí)間。
* 短按按鍵2啟動(dòng)定時(shí),長(zhǎng)按按鍵2復(fù)位。
* 使用繼電器控制插座輸出,250V電壓下額定電流10A,建議實(shí)際使用不超過(guò)1kW。
為方便快速制作,本設(shè)計(jì)選用模塊化零部件,主要模塊包括單片機(jī)STC15F104W、220V轉(zhuǎn)5V電源模塊、TM1637四位時(shí)鐘數(shù)碼管模塊、繼電器模塊等。全部材料均可在網(wǎng)上采購(gòu),總材料費(fèi)用30元左右(含盒子和電源線)。
接線圖:
接線圖.png (334.52 KB, 下載次數(shù): 223)
下載附件
2021-1-24 20:21 上傳
實(shí)物內(nèi)部結(jié)構(gòu):
內(nèi)部接線.jpg (218.12 KB, 下載次數(shù): 208)
下載附件
2021-1-24 20:22 上傳
分享經(jīng)驗(yàn):
* STC15F104W是一款非常方便實(shí)用的小單片機(jī),8個(gè)腳的芯片除Vcc和Gnd外6個(gè)腳全是IO口,無(wú)須外部晶振和復(fù)位,供個(gè)電就能直接使用,實(shí)用是搞小制作的絕佳選擇。
* TM1637數(shù)碼管模塊使用I2C通信,只占用兩個(gè)IO口就行,而且程序非常簡(jiǎn)單,再也不用考慮常規(guī)數(shù)碼管的刷新和消隱什么的。加載封裝好的頭文件即可輕松調(diào)用顯示。
* 繼電器選用了可硬件設(shè)置高低電平驅(qū)動(dòng)的模塊,我使用了高電平驅(qū)動(dòng)。一開(kāi)始輸出高電平發(fā)現(xiàn)驅(qū)動(dòng)不了,原來(lái)要把IO口設(shè)置為強(qiáng)推挽模式才能驅(qū)動(dòng)。
* 因?yàn)閱纹瑱C(jī)IO口數(shù)量限制,需要按鍵復(fù)用,這就引入了長(zhǎng)按短按識(shí)別機(jī)制。我使用了10ms中斷掃描一次按鍵狀態(tài),使用自己琢磨了一套長(zhǎng)按短按機(jī)制,可能有點(diǎn)粗糙,但親測(cè)好用。
* 一開(kāi)始寫的程序顯示倒計(jì)時(shí),是直接顯示計(jì)時(shí)時(shí)間,比如倒計(jì)時(shí)剩不到1分鐘時(shí),數(shù)碼管顯示的是00:00,總感覺(jué)這樣不科學(xué)。后來(lái)改為只要這一分鐘的秒還沒(méi)走到0,就仍算1分鐘。比如只剩20秒時(shí),仍顯示00:01,只有倒計(jì)時(shí)結(jié)束剩0秒時(shí),才顯示00:00。程序作了相應(yīng)修改實(shí)現(xiàn)了此功能。但總感覺(jué)還能寫的更簡(jiǎn)練。。。
* 制作產(chǎn)品當(dāng)然少不了一個(gè)好看的外殼。我經(jīng)常在網(wǎng)上買防水塑料盒,各種規(guī)格都有,這個(gè)延時(shí)插座使用的盒子尺寸是158mm*90mm*40mm。盒子的切割鉆孔也有技巧。工具方面電鉆當(dāng)然少不了,還有帶倒鉤的割刀也非常實(shí)用,盒子在小太陽(yáng)前烘烤一下會(huì)更軟更好切割。
* 這個(gè)延時(shí)插座沒(méi)裝輸出電源指示燈,忘了。。。如有朋友也制作一個(gè)的話可以加上。
歡迎朋友們一起交流。
單片機(jī)源程序:
- /*********************************************/
- /* DIY延時(shí)插座 */
- /* 創(chuàng)建者 :sven */
- /* 創(chuàng)建時(shí)間:2021/1/23 */
- /*********************************************/
- #include "STC15.H"
- #include "TM1637.H"
- #include "intrins.h"
- sbit key1=P3^0; //按鍵1,時(shí)間設(shè)置:短按分鐘+,長(zhǎng)按小時(shí)+
- sbit key2=P3^1; //按鍵2,短按啟動(dòng),長(zhǎng)按復(fù)位
- sbit key3=P3^2; //開(kāi)關(guān)按鍵3,切換延時(shí)斷電/延時(shí)上電功能,只在開(kāi)機(jī)時(shí)檢測(cè)
- sbit relay=P3^3; //繼電器觸發(fā)信號(hào),硬件設(shè)置為高電平時(shí)線圈通電
- unsigned char mode=0; //mode為工作模式0,1 分別表示停止模式和運(yùn)行模式
- unsigned char hour=0,minute=0,second=0,time_count=0; //真實(shí)計(jì)時(shí)的時(shí),分,秒,10ms計(jì)數(shù)器
- unsigned char show[6]={0,0,0,0,0,0}; //TM1637四位數(shù)碼管顯示數(shù)組:小時(shí)的十位和個(gè)位,分鐘的十位和個(gè)位,最后兩個(gè)為小時(shí)和分鐘。
- unsigned int uiKeyTimeCnt1; //按鍵1計(jì)數(shù)
- unsigned int uiKeyTimeCnt2; //按鍵2計(jì)數(shù)
- bit ShortTouchFlag1=0; //按鍵1短按按鍵有效標(biāo)志
- bit LongTouchFlag1=0; //按鍵1長(zhǎng)按按鍵有效標(biāo)志
- bit LongTouchRelease1=1; //按鍵1長(zhǎng)按釋放過(guò)的標(biāo)志
- bit ShortTouchFlag2=0; //按鍵2短按按鍵有效標(biāo)志
- bit LongTouchFlag2=0; //按鍵2長(zhǎng)按按鍵有效標(biāo)志
- bit LongTouchRelease2=1; //按鍵2長(zhǎng)按釋放過(guò)的標(biāo)志
- bit delay_OnOff=0; //延時(shí)上電和延時(shí)斷電選擇位,開(kāi)機(jī)檢查Key3設(shè)置此位,0表示延時(shí)斷電,1表示延時(shí)上電。
- bit flag_1s=1; //秒任務(wù)標(biāo)志位
- bit flag_500ms=1; //半秒標(biāo)志位
- bit stat_500ms=0; //半秒狀態(tài)位,控制時(shí)間冒號(hào)閃爍
- /******************************
- 函數(shù)說(shuō)明:延時(shí)函數(shù),STC_ISP軟件給出 @6MHz 1T單片機(jī)
- 入口參數(shù):us=延時(shí)微秒數(shù)
- 出口參數(shù):無(wú)
- ******************************/
- void Delay_US(unsigned int us)
- {
- while(us--)
- {
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- }
- }
- /******************************
- 函數(shù)說(shuō)明:定時(shí)器0初始化,12T自動(dòng)重裝模式,定時(shí)10毫秒
- ******************************/
- void Timer0Init(void) //10毫秒@6.000MHz
- {
- AUXR &= 0x7F; //定時(shí)器時(shí)鐘12T模式
- TMOD &= 0xF0; //設(shè)置定時(shí)器模式
- TL0 = 0x78; //設(shè)置定時(shí)初值
- TH0 = 0xEC; //設(shè)置定時(shí)初值
- TF0 = 0; //清除TF0標(biāo)志
- TR0 = 1; //定時(shí)器0開(kāi)始計(jì)時(shí)
- ET0=1; //允許T0中斷
- EA=1; //開(kāi)全局中斷
- }
- /******************************
- 函數(shù)說(shuō)明:按鍵短按長(zhǎng)按檢測(cè)
- ******************************/
- void Key_scan(void) //在中斷里調(diào)用,每10ms檢查一次按鍵狀態(tài)
- {
- if(key1==0) //如果按鍵1按下
- {
- uiKeyTimeCnt1++; //累加按鍵計(jì)時(shí)
- }
- if(uiKeyTimeCnt1>200&&LongTouchRelease1==1) //當(dāng)按鍵超過(guò)2秒且此前釋放過(guò)一次時(shí)
- {
- LongTouchFlag1=1; //長(zhǎng)按標(biāo)志位置1,用于長(zhǎng)按2秒后立即處理長(zhǎng)按動(dòng)作
- LongTouchRelease1=0; //長(zhǎng)按釋放標(biāo)志置0,表示長(zhǎng)按未釋放
- }
- if(key1==1) //當(dāng)按鍵松開(kāi)(也可能是抖動(dòng)彈開(kāi))
- {
- if(uiKeyTimeCnt1>2&&uiKeyTimeCnt1<=200) //只有大于20mS,且小于2秒,才判為短按
- {
- uiKeyTimeCnt1=0; //清零按鍵計(jì)時(shí)
- ShortTouchFlag1=1; //短按標(biāo)志位置1
- LongTouchFlag1=0; //長(zhǎng)按標(biāo)志位置0
- }
- if(uiKeyTimeCnt1>200) //如果松開(kāi)按鍵時(shí)按鍵超過(guò)2秒,則為長(zhǎng)按釋放
- {
- uiKeyTimeCnt1=0; //清零按鍵計(jì)時(shí)
- LongTouchRelease1=1; //長(zhǎng)按釋放標(biāo)志位置1,表示長(zhǎng)按已釋放
- }
- }
- if(key2==0) //如果按鍵2按下
- {
- uiKeyTimeCnt2++; //累加按鍵計(jì)時(shí)
- }
- if(uiKeyTimeCnt2>200&&LongTouchRelease2==1) //當(dāng)按鍵超過(guò)2秒且此前釋放過(guò)一次時(shí)
- {
- LongTouchFlag2=1; //長(zhǎng)按標(biāo)志位置1,用于長(zhǎng)按2秒后立即處理長(zhǎng)按動(dòng)作
- LongTouchRelease2=0; //長(zhǎng)按釋放標(biāo)志置0,表示長(zhǎng)按未釋放
- }
- if(key2==1) //當(dāng)按鍵松開(kāi)(也可能是抖動(dòng)彈開(kāi))
- {
- if(uiKeyTimeCnt2>2&&uiKeyTimeCnt2<=200) //只有大于20mS,且小于2秒,才判為短按
- {
- uiKeyTimeCnt2=0; //清零按鍵計(jì)時(shí)
- ShortTouchFlag2=1; //短按標(biāo)志位置1
- LongTouchFlag2=0; //長(zhǎng)按標(biāo)志位置0
- }
- if(uiKeyTimeCnt2>200) //如果松開(kāi)按鍵時(shí)按鍵超過(guò)2秒,則為長(zhǎng)按釋放
- {
- uiKeyTimeCnt2=0; //清零按鍵計(jì)時(shí)
- LongTouchRelease2=1; //長(zhǎng)按釋放標(biāo)志位置1,表示長(zhǎng)按已釋放
- }
- }
- }
- /******************************
- 函數(shù)說(shuō)明:按鍵處理
- ******************************/
- void Key_process(void)
- {
- if(ShortTouchFlag1==1) //當(dāng)按鍵1短按標(biāo)志位為1時(shí)進(jìn)行按鍵1短按處理
- {
- ShortTouchFlag1=0; //清除短按標(biāo)志位
- minute++; //短按按鍵1的效果:分鐘加1
- if(minute==60) //如果設(shè)置分鐘達(dá)到60分
- minute=0; //將分鐘清零
- if(second>0) //以下將實(shí)際計(jì)時(shí)的小時(shí)和分鐘轉(zhuǎn)換為數(shù)碼管顯示的小時(shí)和分鐘。比如計(jì)時(shí)還有00:00:20秒時(shí),數(shù)碼管顯示的是00:01。
- show[5]=minute+1; //只要秒不為零,則顯示出來(lái)的分鐘應(yīng)該比實(shí)際計(jì)時(shí)的分鐘加1
- else
- show[5]=minute; //只有秒為零時(shí),顯示的分鐘才和計(jì)時(shí)的分鐘一致
- if(show[5]==60) //如果顯示的分鐘為60分,則顯示的小時(shí)比實(shí)際計(jì)時(shí)的小時(shí)+1。
- {
- show[5]=0;
- show[4]=hour+1;
- }
- else
- show[4]=hour; //如果顯示的分鐘比實(shí)際的加1后還不到60分鐘,則顯示的小時(shí)和計(jì)時(shí)的小時(shí)一致。
- show[0]=show[4]/10%10; //顯示的小時(shí)十位數(shù)
- show[1]=show[4]%10; //顯示的小時(shí)個(gè)位數(shù)
- show[2]=show[5]/10%10; //顯示的分鐘十位數(shù)
- show[3]=show[5]%10; //顯示的分鐘個(gè)位數(shù)
- TM1637_display(show[0],show[1],show[2],show[3],1); //顯示定時(shí)時(shí)間。在按鍵調(diào)時(shí)狀態(tài)下,時(shí)間的冒號(hào)固定顯示不閃爍。
- }
- if(LongTouchFlag1==1) //當(dāng)按鍵1長(zhǎng)按標(biāo)志位為1時(shí)進(jìn)行按鍵1長(zhǎng)按處理
- {
- LongTouchFlag1=0; //清除長(zhǎng)按標(biāo)志位
- hour++; //按鍵1長(zhǎng)按的效果:小時(shí)加1
- if(hour==100) //如果設(shè)定的小時(shí)到100了
- hour=0; //小時(shí)清零。定時(shí)時(shí)間最高只能設(shè)定99小時(shí)59分鐘。
- if(second>0) //以下將實(shí)際計(jì)時(shí)的小時(shí)和分鐘轉(zhuǎn)換為數(shù)碼管顯示的小時(shí)和分鐘,同上。
- show[5]=minute+1;
- else
- show[5]=minute;
- if(show[5]==60)
- {
- show[5]=0;
- show[4]=hour+1;
- }
- else
- show[4]=hour;
- show[0]=show[4]/10%10; //顯示的小時(shí)十位數(shù)
- show[1]=show[4]%10; //顯示的小時(shí)個(gè)位數(shù)
- show[2]=show[5]/10%10; //顯示的分鐘十位數(shù)
- show[3]=show[5]%10; //顯示的分鐘個(gè)位數(shù)
- TM1637_display(show[0],show[1],show[2],show[3],1); //顯示定時(shí)時(shí)間。在按鍵調(diào)時(shí)狀態(tài)下,時(shí)間的冒號(hào)固定顯示不閃爍。
- }
- if(ShortTouchFlag2==1) //按鍵2短按處理,在停止?fàn)顟B(tài)下短按為啟動(dòng)運(yùn)行
- {
- ShortTouchFlag2=0; //清除短按標(biāo)志位
- if(mode==0&&(minute>0||hour>0)) //只在停止?fàn)顟B(tài)下且設(shè)定了有效的定時(shí)時(shí)間,才能響應(yīng)短按
- {
- mode=1; //短按的效果:?jiǎn)?dòng)定時(shí)
- relay=~delay_OnOff; //開(kāi)始定時(shí)后,根據(jù)開(kāi)機(jī)時(shí)設(shè)定的延時(shí)斷電或延時(shí)上電,繼電器進(jìn)行相應(yīng)動(dòng)作。如設(shè)定的是延時(shí)斷電(delay_OnOff為0),啟動(dòng)后繼電器應(yīng)該先通電動(dòng)作。
- }
- }
- if(LongTouchFlag2==1) //按鍵2長(zhǎng)按處理,長(zhǎng)按為復(fù)位。在運(yùn)行和停止?fàn)顟B(tài)下均可長(zhǎng)按復(fù)位。
- {
- LongTouchFlag2=0; //清除長(zhǎng)按標(biāo)志位
- mode=0; //復(fù)位后狀態(tài)為停止?fàn)顟B(tài)
- relay=0; //繼電器釋放
- hour=minute=second=0; //計(jì)時(shí)時(shí)間清0
- TM1637_display(0,0,0,0,1); //數(shù)碼管顯示時(shí)間00:00,時(shí)間冒號(hào)不閃爍
- }
- }
- void main(void)
- {
- P3M1&=~(1<<3); //將繼電器驅(qū)動(dòng)腳P3.3設(shè)置為推挽輸出
- P3M0|=(1<<3);
- relay=0; //繼電器硬件選擇為高電平驅(qū)動(dòng),開(kāi)機(jī)后默認(rèn)插座無(wú)電
- delay_OnOff=key3; //延時(shí)斷電或延時(shí)上電選擇。1:延時(shí)上電,0:延時(shí)斷電。只在開(kāi)機(jī)前操作Key3有效。
- TM1637_display(0,0,0,0,1); //上電后默認(rèn)顯示00:00
- Timer0Init(); //定時(shí)器T0初始化并啟動(dòng)
- while(1)
- {
- Key_process(); //調(diào)用按鍵處理函數(shù)
- if(flag_500ms==1) //每500毫秒進(jìn)行一次顯示處理,主要是為了實(shí)現(xiàn)時(shí)間冒號(hào)的閃爍
- {
- flag_500ms=0; //清除半秒標(biāo)志位
- stat_500ms=~stat_500ms; //時(shí)間冒號(hào)每秒亮滅一次
- if(mode==1) //只在啟動(dòng)定時(shí)的狀態(tài)下刷新顯示時(shí)間
- {
- if(second>0) //以下為將實(shí)際計(jì)時(shí)的時(shí)間轉(zhuǎn)換為數(shù)碼管顯示的時(shí)間。比如定時(shí)還剩20秒時(shí),數(shù)碼管實(shí)際顯示的是00:01。
- show[5]=minute+1;
- else
- show[5]=minute;
- if(show[5]==60)
- {
- show[5]=0;
- show[4]=hour+1;
- }
- else
- show[4]=hour;
- show[0]=show[4]/10%10; //顯示的小時(shí)十位數(shù)
- show[1]=show[4]%10; //顯示的小時(shí)個(gè)位數(shù)
- show[2]=show[5]/10%10; //顯示的分鐘十位數(shù)
- show[3]=show[5]%10; //顯示的分鐘個(gè)位數(shù)
- TM1637_display(show[0],show[1],show[2],show[3],stat_500ms); //顯示時(shí)間,冒號(hào)位是0還是1由stat_500ms確定,每半秒變化一次。
- }
- if(mode==1&&flag_1s==1) //以下為定時(shí)狀態(tài)下更新計(jì)時(shí)時(shí)間,當(dāng)秒任務(wù)標(biāo)志位為1時(shí)進(jìn)行倒計(jì)時(shí)
- {
- flag_1s=0; //清除秒任務(wù)標(biāo)志位
- if(second>0) //如果秒大于0,則減1秒
- {
- second--;
- }
- else if(minute>0) //如果秒等于0,則從分鐘借位,分鐘減1,秒變?yōu)?9
- {
- minute--;
- second=59;
- }
- else if(hour>0) //如果秒和分鐘都為0,則從小時(shí)借位,小時(shí)減1,分鐘和秒都為59
- {
- hour--;
- minute=59;
- second=59;
- }
- else //如果時(shí)分秒都為0
- {
- mode=0; //倒計(jì)時(shí)結(jié)束,進(jìn)入停止?fàn)顟B(tài)
- relay=delay_OnOff; //依據(jù)開(kāi)機(jī)時(shí)設(shè)置的延時(shí)斷電或延時(shí)上電,設(shè)置計(jì)時(shí)完成后的繼電器狀態(tài)。如果設(shè)置的是延時(shí)斷電,計(jì)時(shí)到后繼電器驅(qū)動(dòng)為0。
- TM1637_display(0,0,0,0,1); //計(jì)時(shí)到后時(shí)間顯示00:00,時(shí)間冒號(hào)不閃爍
- }
- }
- }//半秒任務(wù)結(jié)束
- }//while(1)結(jié)束
- }//main函數(shù)結(jié)束
- void time0(void) interrupt 1 //T0中斷服務(wù),每10ms響應(yīng)一次
- {
- time_count++; //計(jì)數(shù)加1
- Key_scan(); //每10ms掃描一次按鍵狀態(tài)
- if(time_count==50) //每500ms時(shí)設(shè)置一次半秒標(biāo)志位
- flag_500ms=1;
- if(time_count==100) //每1秒設(shè)置一次半秒標(biāo)志位和秒任務(wù)標(biāo)志位
- {
- time_count=0;
- flag_500ms=1;
- flag_1s=1;
- }
- }
復(fù)制代碼 完整程序可從附件下載。
DIY延時(shí)插座.rar
(372.65 KB, 下載次數(shù): 394)
2021-1-24 20:41 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
評(píng)分
-
查看全部評(píng)分
|