能輕松控制LCD顯示屏亮度的環(huán)境光傳感器(附源代碼)
發(fā)布時間:2017-02-23 來源:Ilya Veygman 責(zé)任編輯:wenwei
【導(dǎo)讀】本應(yīng)用筆記主要講述采用MAX44009環(huán)境光傳感器控制便攜式設(shè)備(譬如智能手機(jī)和平板電腦)背光亮度的應(yīng)用。針對背光亮度調(diào)節(jié),本文介紹了兩種不同的控制方案。此外,本文還就如何獲得更好的控制效果提供了相關(guān)建議,同時也提供了實(shí)現(xiàn)本文所述算法的源代碼。
引言
環(huán)境光傳感器(ALS)集成電路正越來越多地用于各種顯示器和照明設(shè)備,以節(jié)省電能,改善用戶體驗(yàn)。借助ALS解決方案,系統(tǒng)設(shè)計(jì)師可根據(jù)環(huán)境光強(qiáng)度,自動調(diào)節(jié)顯示屏的亮度。因?yàn)楸彻庹彰鞯暮碾娏吭谙到y(tǒng)的總耗電量中占據(jù)很大的比例,實(shí)行動態(tài)的背光亮度控制,可節(jié)省大量的電能。此外,它還能夠改善用戶體驗(yàn),讓顯示屏亮度根據(jù)環(huán)境光條件自行調(diào)整到最佳狀態(tài)。
系統(tǒng)實(shí)現(xiàn)需要三大部分:監(jiān)測環(huán)境光強(qiáng)的光傳感器、數(shù)據(jù)處理裝置(通常是微控制器)、控制背光輸入電流的執(zhí)行器。
背光控制:環(huán)境光傳感器
圖1是實(shí)施背光控制的系統(tǒng)示范框圖。在這套組合中,光傳感器是關(guān)鍵的組成部分,因?yàn)樗蛳到y(tǒng)的其他模塊提供環(huán)境光強(qiáng)信息。光傳感器必須具備將光信號轉(zhuǎn)換成電信號的信號轉(zhuǎn)換器(譬如光電二極管或CdS光敏電阻)和信號放大和/或調(diào)節(jié)裝置以及模/數(shù)轉(zhuǎn)換器(ADC)。
圖1. 實(shí)施背光控制的系統(tǒng)框圖
圖2所示為分立光電二極管電路,從圖中可以看出,該電路需要一個或多個運(yùn)算放大器:一個用于電流到電壓的轉(zhuǎn)換,可能還需要一級放大,提供附加增益。它還包括一些分支電路,用于供電,確保高度可靠的信號鏈。而在空間極其寶貴的應(yīng)用中,所需元件的數(shù)量過多可能導(dǎo)致空間受限問題。
圖2. 光電二極管電路分立設(shè)計(jì)
這里還存在一個更細(xì)微的問題。具體而言,理想情況下,應(yīng)確保環(huán)境光的測量模擬了人眼對光線的響應(yīng)機(jī)制。這通常借助CIE提供的視覺亮度曲線(圖3)。然而,光電二極管很少能夠完全模擬這種響應(yīng)機(jī)制,因?yàn)樗鼈兺ǔ>哂泻芨叩募t外(IR)靈敏度。在IR強(qiáng)度較大的光照條件(譬如白熾燈或日光)下,這種紅外靈敏度會造成錯誤地判斷光線強(qiáng)度。
解決上述問題的方法之一是使用兩個光電二極管:一個采用對可見光和紅外光都很敏感的元件,另一個采用只對紅外光敏感的元件。最終用前者的響應(yīng)值減去后者的響應(yīng)值,將紅外干擾降至最小,獲得準(zhǔn)確的可見光響應(yīng)。
這種解決方案雖然有效,卻增加了分立電路的占用空間。通常還很難、甚至不可能讓兩個分立的光電二極管配合得足夠緊密,以實(shí)現(xiàn)消除紅外干擾的目的。如果不配備精密放大器(譬如對數(shù)放大器),動態(tài)范圍可能很小。換句話說,很難利用這種組合獲得可重復(fù)的結(jié)果。
圖3. CIE曲線和典型的光電二極管
高集成度解決方案不僅能夠獲得比人眼光學(xué)系統(tǒng)更真實(shí)的光強(qiáng)數(shù)據(jù),還能夠節(jié)省大量空間MAX44009等環(huán)境光傳感器,可將所有信號調(diào)節(jié)和模/數(shù)轉(zhuǎn)換器集成在一個小封裝(2mm x 2mm UTDFN封裝)內(nèi),從而在空間受限應(yīng)用中有效節(jié)省電路板面積。
圖4提供了MAX44009的功能框圖,采用I²C通信協(xié)議,使其與微控制器的連接方式更簡單,數(shù)據(jù)傳輸速度更快。除此之外,該解決方案的高集成特性使其能夠置于柔性電纜,安裝在離主電路板距離合適的位置。
圖4. MAX44009功能框圖
背光控制:調(diào)節(jié)顯示屏亮度
該控制方案的第二部分是調(diào)節(jié)顯示屏的背光亮度。這可通過多種方式實(shí)現(xiàn),具體取決于設(shè)備中的顯示屏模塊。有兩種最簡單的方式,一種是借助脈沖寬度調(diào)制(PWM)方案的直接調(diào)節(jié)方式,另一種是采用顯示屏控制器的間接調(diào)節(jié)方式。
許多顯示屏模塊如今都配有一個集成控制器,用戶可以通過向控制器發(fā)送串行命令,直接設(shè)置背光亮度。如果顯示屏模塊未配備集成控制器,還可安裝一個簡單的背光控制執(zhí)行器,控制顯示屏后面用于背光照明的白光LED燈的輸入電流。實(shí)現(xiàn)這種控制的一種簡單辦法是:直接給LED串聯(lián)一個場效應(yīng)晶體管(FET),使用PWM信號快速打開、關(guān)閉FET (圖5)。然而,也可以利用單一芯片(用于LED控制的MAX1698升壓轉(zhuǎn)換器)準(zhǔn)確、可靠地調(diào)節(jié)(圖6),請參考應(yīng)用筆記3866“Low-power PWM output controls LED brightness”,獲取詳細(xì)信息。
圖5. 簡單的PMW控制電路
圖6. 基于MAX1698的LED亮度調(diào)節(jié)器
背光控制:建立連接
最后一步就是在傳感器和執(zhí)行器之間建立連接,通過微控制器實(shí)現(xiàn)。有人可能首先要問:“環(huán)境光強(qiáng)如何映射到背光亮度?”事實(shí)上,有些文獻(xiàn)專門介紹了相關(guān)方案。其中一種映射方式是,Microsoft®針對運(yùn)行Windows® 7¹操作系統(tǒng)的計(jì)算機(jī)提出的。圖7所示曲線是由Microsoft提供的,它可以將環(huán)境光強(qiáng)度映射到顯示屏亮度(以全部亮度的百分比表示)。
圖7. 將環(huán)境光強(qiáng)映射為最佳顯示屏亮度的曲線示例
這種特殊曲線可以用以下函數(shù)表示:
如果設(shè)備采用的是已集成亮度控制功能的LCD控制芯片,就可通過向芯片發(fā)送指令,輕松設(shè)置背光亮度。如果設(shè)備采用的是PWM直接控制亮度,則要考慮如何將比例信號映射至顯示屏亮度。
在MAX1698示例中,根據(jù)其產(chǎn)品說明書的介紹,可以將驅(qū)動電流映射為電壓。通過這個示例,我們可以假設(shè)LED電流強(qiáng)度幾乎與其電流呈線性關(guān)系。這樣,我們就可以在上述等式中乘上一個系數(shù),計(jì)算出PWM所映射的有效電壓,該電壓再被映射至LED電流,最后轉(zhuǎn)化成顯示屏亮度。
方案實(shí)施
最好不要從一個亮度級直接跳轉(zhuǎn)到另一個亮度級,而是平滑上調(diào)和下調(diào)背光亮度,確保不同亮度等級之間無縫過渡。為了達(dá)到這一目的,最好采用帶有固定或不同亮度步長、可逐步調(diào)節(jié)亮度的定時中斷,也可采用帶有可控制LED輸入電流的PWM值的定時中斷,或者是能夠發(fā)送到顯示屏控制器的串行指令的定時中斷。圖8提供了這種算法的一個示例。
圖8. 步進(jìn)式亮度調(diào)節(jié)的算法示例
另一個問題是,系統(tǒng)響應(yīng)環(huán)境光強(qiáng)變化的速度。我們應(yīng)盡量避免過快地改變亮度等級。這是因?yàn)楣鈴?qiáng)的瞬間變化(譬如一扇窗戶打開或瞬間有一束光掃過)可能導(dǎo)致背光亮度發(fā)生不必要的變化,這往往會造成用戶感覺不適。并且,較長的響應(yīng)時間還有助于減少微控制器對光傳感器的檢測次數(shù),從而可以釋放一定的微控制器資源。
最初級的方法就是每隔一兩秒鐘檢查一次光傳感器,然后相應(yīng)地調(diào)整背光亮度。更好的方法是,只有光線強(qiáng)度偏離特定范圍一定時間后,才對背光亮度進(jìn)行調(diào)節(jié)。譬如,如果正常光強(qiáng)是200lux,我們可能只會在光強(qiáng)降到180lux以下或升至220lux以上,而且持續(xù)時間超過數(shù)秒的情況下才調(diào)節(jié)亮度。幸運(yùn)的是,MAX44009集成了中斷引腳和閾值寄存器,可輕松實(shí)現(xiàn)這個目的。
附錄:源代碼
#define MAX44009_ADDR 0x96
// begin definition of slave addresses for MAX44009
#define INT_STATUS 0x00
#define INT_ENABLE 0x01
#define CONFIG_REG 0x02
#define HIGH_BYTE 0x03
#define LOW_BYTE 0x04
#define THRESH_HIGH 0x05
#define THRESH_LOW 0x06
#define THRESH_TIMER 0x07
// end definition of slave addresses for MAX44009
extern float SCALE_FACTOR; // captures scaling factors to map from % brightness to PWM
float currentBright_pct; // the current screen brightness, in % of maximum
float desiredBright_pct; // the desired screen brightness, in % of maximum
float stepSize; // the step size to use to go from the current
// brightness to the desired brightness
uint8 lightReadingCounter;
/**
* Function: SetPWMDutyCycle
*
* Arguments: uint16 dc - desired duty cycle
*
* Returns: none
*
* Description: Sets the duty cycle of a 16-bit PWM, assuming that in this
* architecture, 0x0000 = 0% duty cycle
* 0x7FFF = 50% and 0xFFFF = 100%
**/
extern void SetPWMDutyCycle(uint16 dc);
/**
* Function: I2C_WriteByte
*
* Arguments: uint8 slaveAddr - address of the slave device
* uint8 command - destination register in slave device
* uint8 data - data to write to the register
*
* Returns: ACK bit
*
* Description: Performs necessary functions to send one byte of data to a
* specified register in a specific device on the I2C bus
**/
uint8 2C_WriteByte(uint8 slaveAddr, uint8 command, uint8 data);
/**
* Function: I2C_ReadByte
*
* Arguments: uint8 slaveAddr - address of the slave device
* uint8 command - destination register in slave device
* uint8 *data - pointer data to read from the register
*
* Returns: ACK bit
*
* Description: Performs necessary functions to get one byte of data from a
* specified register in a specific device on the I2C bus
**/
uint8 I2C_ReadByte(uint8 slaveAddr, uint8 command, uint8* data);
/**
* Function: getPctBrightFromLuxReading
*
* Arguments: float lux - the pre-computed ambient light level
*
* Returns: The % of maximum brightness to which the backlight should be set
* given the ambient light (0 to 1.0)
*
* Description: Uses a function to map the ambient light level to a backlight
* brightness by using a predetermined function
**/
float getPctBrightFromLuxReading(float lux);
/**
* Function: mapPctBrighttoPWM
*
* Arguments: float pct
*
* Returns: PWM counts needed to achieve the specified % brightness (as
* determined by some scaling factors)
**/
uint16 mapPctBrighttoPWM(float pct);
/**
* Function: getLightLevel
*
* Arguments: n/a
*
* Returns: the ambient light level, in lux
*
* Description: Reads both the light registers on the device and returns the
* computed light level
**/
float getLightLevel(void);
/**
* Function: stepBrightness
*
* Arguments: n/a
*
* Returns: n/a
*
* Description: This function would be called by an interrupt. It looks at the
* current brightness setting, then the desired brightness setting.
* If there is a difference between the two, the current brightness
* setting is stepped closer to its goal.
**/
void stepBrightness(void);
/**
* Function: timerISR
*
* Arguments: n/a
*
* Returns: n/a
*
* Description: An interrupt service routine which fires every 100ms or so. This
* handles all the ambient light sensor and backlight
* control code.
**/
void timerISR(void);
void main() {
SetupMicro(); // some subroutine which initializes this CPU
I2C_WriteByte(MAX44009_ADDR, CONFIG_REG, 0x80); // set to run continuously
lightReadingCounter = 0;
stepSize = .01;
currentBright_pct = 0.5;
desiredBright_pct = 0.5;
SetPWMDutyCycle(mapPctBrighttoPWM(currentBright_pct));
InitializeTimerInterrupt(); // set this to fire every 100ms
while(1) {
// do whatever else you need here, the LCD control is done in interrupts
Idle();
}
} // main routine
// the point at which the function clips to 100%
#define MAXIMUM_LUX_BREAKPOINT 1254.0
float getPctBrightFromLuxReading(float lux) {
if (lux > MAXIMUM_LUX_BREAKPOINT)
return 1.0;
else
return (9.9323*log(x) + 27.059)/100.0;
} // getPctBrightFromLuxReading
uint16 mapPctBrighttoPWM(float pct) {
return (uint16)(0xFFFF * pct * SCALE_FACTOR);
} // mapPctBrighttoPWM
float getLightLevel(void) {
uint8* lowByte;
uint8* highByte;
uint8 exponent;
uint8 mantissa;
float result;
I2C_ReadByte(MAX44009_ADDR, HIGH_BYTE, highByte);
I2C_ReadByte(MAX44009_ADDR, LOW_BYTE, lowByte);
exponent = (highByte & 0xF0) >> 4;// upper four bits of high byte register
mantissa = (highByte & 0x0F) << 4;// lower four bits of high byte register =
// upper four bits of mantissa
mantissa += lowByte & 0x0F; // lower four bits of low byte register =
// lower four bits of mantissa
result = mantissa * (1 << exponent) * 0.045;
return result;
} //getLightLevel
void stepBrightness(void) {
// if current is at desired, don''t do anything
if (currentBright_pct == desiredBright_pct)
return;
// is the current brightness above the desired brightness?
else if (currentBright_pct > desiredBright_pct) {
// is the difference between the two less than one step?
if ( (currentBright_pct-stepSize) < desiredBright_pct)
currentBright_pct = desiredBright_pct;
else
currentBright_pct -= stepSize;
} // else if
else if (currentBright_pct < desiredBright_pct) {
// is the difference between the two less than one step?
if ( (currentBright_pct+stepSize) > desiredBright_pct)
currentBright_pct = desiredBright_pct;
else
currentBright_pct += stepSize;
} // else if
SetPWMDutyCycle(mapPctBrighttoPWM(currentBright_pct));
return;
} // stepBrightness
void timerISR(void) {
float lux;
float pctDiff;
stepBrightness();
if (lightReadingCounter)
lightReadingCounter--;
else {
lightReadingCounter = 20; // 2 second delay
lux = getLightLevel();
desiredBright_pct = getPctBrightFromLuxReading(lux);
pctDiff = abs(desiredBright_pct - currentBright_pct);
stepSize = (pctDiff <= 0.01) ? 0.01:pctDiff/10;
} // else
ClearInterruptFlag();
} // timerISR
本文來源于Maxim。
推薦閱讀:
特別推薦
- AMTS 2025展位預(yù)訂正式開啟——體驗(yàn)科技驅(qū)動的未來汽車世界,共迎AMTS 20周年!
- 貿(mào)澤電子攜手安森美和Würth Elektronik推出新一代太陽能和儲能解決方案
- 功率器件熱設(shè)計(jì)基礎(chǔ)(六)——瞬態(tài)熱測量
- 貿(mào)澤開售Nordic Semiconductor nRF9151-DK開發(fā)套件
- TDK推出用于可穿戴設(shè)備的薄膜功率電感器
- 日清紡微電子GNSS兩款新的射頻低噪聲放大器 (LNA) 進(jìn)入量產(chǎn)
- 中微半導(dǎo)推出高性價比觸控 MCU-CMS79FT72xB系列
技術(shù)文章更多>>
- 意法半導(dǎo)體推出首款超低功耗生物傳感器,成為眾多新型應(yīng)用的核心所在
- 是否存在有關(guān) PCB 走線電感的經(jīng)驗(yàn)法則?
- 智能電池傳感器的兩大關(guān)鍵部件: 車規(guī)級分流器以及匹配的評估板
- 功率器件熱設(shè)計(jì)基礎(chǔ)(八)——利用瞬態(tài)熱阻計(jì)算二極管浪涌電流
- AHTE 2025展位預(yù)訂正式開啟——促進(jìn)新技術(shù)新理念應(yīng)用,共探多行業(yè)柔性解決方案
技術(shù)白皮書下載更多>>
- 車規(guī)與基于V2X的車輛協(xié)同主動避撞技術(shù)展望
- 數(shù)字隔離助力新能源汽車安全隔離的新挑戰(zhàn)
- 汽車模塊拋負(fù)載的解決方案
- 車用連接器的安全創(chuàng)新應(yīng)用
- Melexis Actuators Business Unit
- Position / Current Sensors - Triaxis Hall
熱門搜索
單向可控硅
刀開關(guān)
等離子顯示屏
低頻電感
低通濾波器
低音炮電路
滌綸電容
點(diǎn)膠設(shè)備
電池
電池管理系統(tǒng)
電磁蜂鳴器
電磁兼容
電磁爐危害
電動車
電動工具
電動汽車
電感
電工電路
電機(jī)控制
電解電容
電纜連接器
電力電子
電力繼電器
電力線通信
電流保險絲
電流表
電流傳感器
電流互感器
電路保護(hù)
電路圖