有的PPC控制不是采用线性计数方式,而是采用循环计数,也即下一刻的调节数值跟前一次的调节数值是相关的。以AW9956为例:它是一款脉冲控制的LCD背光驱动芯片,共有16级亮度,采用上升沿计数。
如上,Ton是从LCD背光从关断到使能的电平,之后则是规则的等长脉冲,最后Tshdn则是关断LCD背光。亮度计数分配如下:
脉冲循环计数示例图:
(1)线性计数:虽然AW9656是一款循环计数的芯片,但是也可以采用线性计数方式工作,会有典型的屏闪。只需要在每次设置前关断后再重设即可。实例代码如下:
int Brightness_SetGpio(int gpio_num,int level)
{
int i;
int min_level = 30; //the min value for UI brightness setup
int max_level = 255; //the max value for UI brightness setup
int min_bri = 1; //the min value for adjust the brightness
int max_bri = 16; //the max value for adjust the brightness
kal_uint8 count=0, to_count=0;
static int s_bBacklightOn = 1;
mt_set_gpio_mode(gpio_num, GPIO_MODE_GPIO);
mt_set_gpio_dir(gpio_num, GPIO_DIR_OUT);
if (level)
{
if (level < min_level)
{
to_count = max_bri;
}
else if (level > 255)
{
to_count = min_bri;
}
else
{
to_count = max_bri-((level-min_level)*(max_bri-min_bri)/(max_level-min_level));
LEDS_DEBUG("[LED] infact count=%d\n", to_count);
}
mt_set_gpio_out(gpio_num, GPIO_OUT_ZERO);
mdelay(5); //turn off EN PIN
mt_set_gpio_out(gpio_num, GPIO_OUT_ONE);
udelay(20); //resetting EN PIN
to_count--; //to_count not include the first EN pluse
for (i=1; i<to_count; i++)
{
mt_set_gpio_out(gpio_num, GPIO_OUT_ZERO);
udelay(2);
mt_set_gpio_out(gpio_num, GPIO_OUT_ONE);
udelay(2);
}
}
else
{
mt_set_gpio_out(gpio_num, GPIO_OUT_ZERO);
mdelay(5);
}
return 0;
}
(2)循环计数程序,已验证,具体做法不同于下述思路。
#define SN3228_BRIGHTNESS_TOTAL_LEVEL (16)
#define SN3228_BRIGHTNESS_STEP_LEVEL (16)
int SN3228_pre_gpio_dev_level = -1;
static int Cust_SN3228_SetBacklight(int level, int div)
{
int phylevel;
int pulse_count;
int i;
phylevel = level/SN3228_BRIGHTNESS_STEP_LEVEL;
If( level>0 && phylevel == 0)
{
phylevel = 1;
}
if( SN3228_pre_gpio_dev_level != -1 && SN3228_pre_gpio_dev_level == phylevel )
{
return 0;
}
else if(SN3228_pre_gpio_dev_level == -1)
{
SN3228_pre_gpio_dev_level = SN3228_BRIGHTNESS_TOTAL_LEVEL-1;
}
if( phylevel <= SN3228_pre_gpio_dev_level )
{
pulse_count = SN3228_pre_gpio_dev_level - phylevel;
}
else
{
pulse_count = SN3228_BRIGHTNESS_TOTAL_LEVEL - (phylevel - SN3228_pre_gpio_dev_level);
}
mt_set_gpio_mode(GPIO_LCD_EN_PIN, GPIO_LCD_EN_PIN_M_GPIO);
mt_set_gpio_dir(GPIO_LCD_EN_PIN, GPIO_DIR_OUT);
If( level > 0 )
{
If( SN3228_pre_gpio_dev_level == 0 )
{
mdelay(25);
mt_set_gpio_out(GPIO_LCD_EN_PIN, GPIO_OUT_ONE);
}
mt_set_gpio_out(GPIO_LCD_EN_PIN, GPIO_OUT_ONE);
For( i=0; i<pulse_count; i++)
{
udelay(1);
mt_set_gpio_out(GPIO_LCD_EN_PIN, GPIO_OUT_ZERO);
udelay(1);
mt_set_gpio_out(GPIO_LCD_EN_PIN, GPIO_OUT_ONE);
}
}
Else
{
mt_set_gpio_out(GPIO_LCD_EN_PIN, GPIO_OUT_ZERO);
}
udelay(1);
SN3228_pre_gpio_dev_level = phylevel;
return 0;
}