軟開(kāi)關(guān)設(shè)計(jì):典型電路及軟件代碼
簡(jiǎn)介:何為軟開(kāi)關(guān)?軟開(kāi)關(guān)是相對(duì)于硬開(kāi)關(guān)而言。硬開(kāi)關(guān)顧名思義,電源的開(kāi)斷完全取決于硬件,是物理層上的開(kāi)合;而軟開(kāi)關(guān),則是必須借助于軟件,準(zhǔn)確地說(shuō)是借助軟件來(lái)進(jìn)行關(guān)閉。
本文引用地址:http://butianyuan.cn/article/201808/387605.htm兩者各有優(yōu)劣。前者因?yàn)槭俏锢韺拥牟僮鳎梢灾v電源和系統(tǒng)部分完全阻隔,所以關(guān)閉時(shí)漏電流非常小,但缺陷是關(guān)閉時(shí)無(wú)法給予軟件任何通知信息;而后者的關(guān)閉只是電平的操作,關(guān)閉后無(wú)法將電源部分與系統(tǒng)部分隔離,因此相對(duì)而言,漏電流會(huì)比較大,但優(yōu)點(diǎn)在于,關(guān)閉是由軟件進(jìn)行控制,所以能在關(guān)閉前做好相應(yīng)的準(zhǔn)備工作。正是因?yàn)榇颂匦?,故電子設(shè)備來(lái)說(shuō)采用硬開(kāi)關(guān)的設(shè)計(jì)非常少,更多的是軟開(kāi)關(guān)。舉個(gè)簡(jiǎn)單的例子,我們常用的家用電腦就是軟開(kāi)關(guān)設(shè)計(jì)。試想加入電腦采用的是硬開(kāi)關(guān)的設(shè)計(jì),會(huì)是什么結(jié)果?結(jié)果估計(jì)就如同我們?cè)谡J褂秒娔X時(shí),突然將插頭給拔掉一樣。這樣,對(duì)于電腦的設(shè)備,特別是硬盤而言,所造成的損害是不可估量的。
軟開(kāi)關(guān)設(shè)計(jì) 硬件篇
對(duì)于軟開(kāi)關(guān)而言,在我們按下那一瞬間,因?yàn)檫€沒(méi)有給CPU上電,不存在任何程序執(zhí)行的可能,所以注定“打開(kāi)”這一個(gè)操作只能用硬件完成。當(dāng)系統(tǒng)跑起來(lái)以后,此時(shí)軟件已經(jīng)開(kāi)始運(yùn)作,我們就能通過(guò)對(duì)GPIO進(jìn)行操作來(lái)關(guān)閉設(shè)備。綜上所述,如果要實(shí)現(xiàn)軟開(kāi)關(guān),我們必須具備兩個(gè)GPIO口。一個(gè)為DETECT_KEY,作為輸入,用來(lái)檢測(cè)按鍵是否按下;另一個(gè)為GPIO_SHDW,作為輸出,用來(lái)控制電源的閉合。
現(xiàn)在,我們來(lái)看一個(gè)典型的軟開(kāi)關(guān)電路(圖一,以下講解都以電路圖的標(biāo)號(hào)為指代):
該電路很簡(jiǎn)單,對(duì)外的節(jié)點(diǎn)有四處,分別如下:
PWR_ON:用來(lái)控制系統(tǒng)的電源。當(dāng)其為high時(shí),系統(tǒng)正常供電。
VDD33D:直接接3.3V電壓
GPIO_SHDW:當(dāng)其為low時(shí)關(guān)閉系統(tǒng)電源
DETECT_KEY:檢測(cè)按鍵S1的狀態(tài)。
我們現(xiàn)在根據(jù)開(kāi)機(jī)到關(guān)機(jī)的過(guò)程來(lái)一步一步來(lái)分析該電路:
1.未開(kāi)機(jī),S1未按下。
此時(shí)GPIO_SHDN為low,直接控制了Q1和Q2的控制腳(PIN1),令VDD33D的電壓無(wú)法輸出到POW_ON端。而D1因?yàn)镾1未按下,該二極管也處于阻隔狀態(tài),S1端的VDD33D也無(wú)法輸送到POW_ON端。故整個(gè)系統(tǒng)還處于關(guān)閉狀態(tài)。
2.S1按下,開(kāi)機(jī)。
S1按下,二極管D1導(dǎo)通,S1端的VDD33D電壓輸送到PWR_ON端,系統(tǒng)開(kāi)始啟動(dòng)。系統(tǒng)啟動(dòng)時(shí),將GPIO_SHDN置high。此時(shí)PWR_ON已經(jīng)輸入了R2,R3端的VDD33D電壓,D1兩邊電壓基本上處于平衡狀態(tài),D1相當(dāng)于斷開(kāi),S1端的電壓無(wú)法加載到PWR_ON。
3.S1放開(kāi),系統(tǒng)正常運(yùn)行。
S1放開(kāi),D1不可能再導(dǎo)通,而此時(shí)電壓已經(jīng)主要是從R2,R3端的VDD3D輸入,令PWR_ON一直保持high狀態(tài),故系統(tǒng)一直處于正常運(yùn)行狀態(tài)。
4.S1按下,系統(tǒng)正常運(yùn)行。
因?yàn)镾1按下,導(dǎo)致Q3導(dǎo)通,拉低R6端下方的電壓,此時(shí)DETECT_KEY這個(gè)GPIO口檢測(cè)到電平為low,軟件開(kāi)始進(jìn)入計(jì)時(shí)狀態(tài)。
5.S1放開(kāi)。
因?yàn)镾1已經(jīng)放開(kāi),Q3不再導(dǎo)通,R6下端電壓恢復(fù),DETECT_KEY檢測(cè)到電平為high。此時(shí)軟件和閾值做比較,如果超過(guò)預(yù)定的閾值,則關(guān)閉系統(tǒng);否則,將本次操作忽略。在這里之所以和閾值進(jìn)行比較,是出自于防抖的需要。因?yàn)樵趯?shí)際使用中,可能R6端會(huì)有微小的極為短暫的電壓降,如果軟件不設(shè)置閾值,檢測(cè)到該電壓降就會(huì)關(guān)閉,這對(duì)于產(chǎn)品而言是不允許的。
軟開(kāi)關(guān)設(shè)計(jì) 軟件篇
相對(duì)于硬件來(lái)說(shuō),軟開(kāi)關(guān)的軟件代碼更為簡(jiǎn)單,只需要檢測(cè)DETECT_KEY即可。該功能的實(shí)現(xiàn)主要是通過(guò)GPIO,而wince并沒(méi)有對(duì)GPIO做上層定義,并且每款CPU的GPIO的操作方式又各自不同,所以本文無(wú)法給出一個(gè)完整可用的代碼,只能用偽代碼作為示例講解。雖然是偽代碼,但對(duì)于了解其流程還是有一定的意義。
void Power_On()
{
...
//設(shè)置GPIO_SHDN為high
SetGPIO_HIGH(GPIO_SHDN);
...
}
DWORD PWR_IntrThread(PVOID pParam)
{
....
//使能中斷
EnableInterrupt();
//初始化中斷
InterruptInitialize(btnSysIntr, hNotifyEvent, 0, 0)
while(TRUE)
{
//等待中斷事件
dwRet = WaitForSingleObject(hNotifyEvent, INFINITE);
if(dwRet == WAIT_OBJECT_0)
{
//中斷處理完畢,讓中斷再次進(jìn)入處理
InterruptDone(btnSysIntr);
//再次等待中斷處理事件
dwRet = WaitForSingleObject(hNotifyEvent, 1000);
if(dwRet == WAIT_TIMEOUT)
{
//當(dāng)其位WAIT_TIMEOUT時(shí),意味著為長(zhǎng)按,進(jìn)入poweroff函數(shù)
EnterPowerOff();
}
}
}
....
}
void EnterPowerOff()
{
...
while(TRUE)
{
if(IsGPIOHigh(GPIO_DETECT_KEY) != FALSE)
{
//S1已經(jīng)松開(kāi),跳出循環(huán)
break;
}
}
//關(guān)閉系統(tǒng)電源
SetGPIO_LOW(GPIO_SHDN);
...
}
這里唯一需要注意的是EnterPowerOff函數(shù),在這里必須要檢測(cè)S1是否已經(jīng)松開(kāi)。如果還沒(méi)有松開(kāi)S1就將GPIO_SHDN置為L(zhǎng)OW,因?yàn)镾1端還有VDD33D電壓輸入到PWR_ON端,所以系統(tǒng)還是無(wú)法關(guān)閉。
評(píng)論