当产品需求段码LCD显现时,假设运用不带LCD驱动器的MCU,则需求外接LCD驱动IC,这会增加本钱和PCB面积。事实上,许多小项目,比方很多的小家电,需求显现的段码不多,常见的是4个8带小数点或时钟的冒号“:”,这样假设运用IO口直接扫描显现,则会减小PCB面积,降低本钱。
可是,本计划不合适驱动太多的段(占用IO太多),也不合适十分低功耗的场合。
段码LCD驱动简略原理:如图1所示。
LCD是一种特别的液态晶体,在电场的作用下晶体的摆放方向会产生改动,因此改动其透光性,然后能够看到显现内容。LCD有一个改动阀值,当LCD两头电压高于此阀值时,显现内容,低于此阀值时,不显现。一般LCD有3个参数:作业电压、DUTY(对应COM数)和BIAS(即偏压,对应阀值),比方4.5V、1/4DUTY、1/3BIAS,表明LCD显现电压为4.5V,4个COM,阀值大约是1.5V,当加在某段LCD两头电压大于1.5V时(一般加4.5V)显现,而加1.5V时不显现。可是LCD关于驱动电压的反响不是很明显的,比方加2V时,可能会弱小显现,这便是一般说的“鬼影”。所以要确保驱动显现时,要大于阀值电压比较多,而不显现时,要用比阀值小比较多的电压。
留意:LCD的两头不能加直流电压,不然时刻稍长就会损坏,所以要确保加在LCD两头的驱动电压的均匀电压为0。LCD运用时切割扫描法,任何时候一个COM扫描有用,别的的COM处于无效状况。
驱动1/4Duty1/2BIAS3V的计划电路见图1,LCD扫描原理见图3,MCU为3V作业,用双向口做COM,PUSH-PULL或STANDARD输出口接SEG,而且每个COM都接一个47K电阻到一个电容,RC滤波后得到一个中点电压。在轮到某个COM扫描时,设置成PUSH-PULL输出,假设与本COM衔接的SEG不显现,则SEG输出与COM同相,假设显现,则反相。扫描完后,这个COM的IO就设置成高阻,这样这个COM就经过47K电阻衔接到1/2VDD电压,而SEG持续输出方波,这样加在LCD上的电压,显现时是+-VDD,不显现时是+-1/2VDD,确保了LCD两头均匀直流电压为0。
驱动1/4Duty1/3BIAS3V的计划电路见图4,LCD扫描原理见图5,,MCU为5V作业,SEG线经过电阻分压输出1.5V、3.5V,COM线经过电阻分压输出0.5V、2.5V(高阻时)、4.5V。在轮到某个COM扫描时,设置成PUSH-PULL输出,假设与本COM衔接的SEG不显现,则SEG输出与COM同相,假设显现,则反相。扫描完后,这个COM的IO就设置成高阻,这样这个COM就经过47K电阻衔接到2.5V电压,而SEG持续输出方波,这样加在LCD上的电压,显现时是+-3.0V,不显现时是+-1.0V,彻底满意LCD的扫描要求。
当需求睡觉省电时,把一切COM和SEG驱动IO悉数输出低电平,LCD驱动部分不会增加额定电流。
图1:驱动1/4Duty1/2BIAS3VLCD的电路
图2:段码称号图
图3:1/4Duty1/2BIAS扫描原理图
图4:驱动1/4Duty1/3BIAS3VLCD的电路
图5:1/4Duty1/3BIAS扫描原理图
为了运用方便,显现内容放在一个显存中,其间的各个位与LCD的段一一对应,见图6。
图6:LCD真值表和显存影射表
图7:驱动作用相片
本LCD扫描程序仅需求两个函数:
1、LCD段码扫描函数void LCD_scan(void)
程序隔必定的时刻调用这个函数,就会将LCD显现缓冲的内容显现到LCD上,悉数扫描一次需求8个调用周期,调用距离一般是1~2ms,假设运用1ms,则扫描周期便是8ms,刷新率便是125HZ。
2、LCD段码显现缓冲装载函数voidLCD_load(u8n,u8dat)
本函数用来将显现的数字或字符放在LCD显现缓冲中,比方LCD_load(1,6),便是要在第一个数字方位显现数字6,支撑显现0~9,A~F,其它字符用户能够自己增加。
别的,用宏来显现、平息或闪耀冒号或小数点。
具体的程序请从STC的官网www.stcmcu.com下载。
/******************LCD段码扫描函数***************************
u8 codeT_COM[4]={0x08,0x04,0x02,0x01};
void LCD_scan(void) //5us@22.1184MHZ
{u8 j;
j=scan_index>>1;//COMx
P2n_pure_input(0x0f);//悉数COM输出高阻,COM为中点电压
if(scan_index&1)//反相扫描
{P1=~LCD_buff[j]; //送SEG驱动码
P2=~(LCD_buff[j|4]&0xf0);//送SEG驱动码和COM驱动码
}
else //正相扫描
{P1=LCD_buff[j];//送SEG驱动码
P2=LCD_buff[j|4]&0xf0;//送SEG驱动码和COM驱动码
}
P2n_push_pull(T_COM[j]); //某个COM设置为推挽输出
if(++scan_index>=8) scan_index=0;//扫描完结,重复扫描
}
/******************LCD段码显现缓冲装载函数***************************/
/******************对第1~6数字装载显现函数***************************/
u8 codeT_LCD_mask[4]={~0xc0,~0x30,~0x0c,~0x03};
u8 codeT_LCD_mask4[4]={~0x40,~0x10,~0x04,~0x01};
void LCD_load(u8n,u8dat) //n为第几个数字,为1~6,dat为要显现的数字 10us@22.1184MHZ
{u8 i,k;
u8 *p;
if((n==0)||(n>6)) return;
i=t_display[dat];
if(n<=4) //1~4
{n–;
p=LCD_buff;
}
else
{n=n-5;
p=&LCD_buff[4];
}
k=0;
if(i&0x08) k|=0x40; //D
*p=(*p&T_LCD_mask4[n])|(k>>2*n);
p++;
k=0;
if(i&0x04) k|=0x40; //C
if(i&0x10) k|=0x80; //E
*p=(*p&T_LCD_mask[n])|(k>>2*n);
p++;
k=0;
if(i&0x02) k|=0x40; //B
if(i&0x40) k|=0x80; //G
*p=(*p&T_LCD_mask[n])|(k>>2*n);
p++;
k=0;
if(i&0x01) k|=0x40; //A
if(i&0x20) k|=0x80; //F
*p=(*p&T_LCD_mask[n])|(k>>2*n);
}
文档结束。