/*用于测试笔段的LCD屏
可以改变占空比(duty)和偏压(bias)设置
占空比(duty)有:静态,2 duty,3 duty,4 duty;默认为4 duty;
偏压(bias)有: 1/2bais,1/3bias 默认为1/3bias
2008-12-04 VER1.0 LIN
改变占空比能自动改变到相应的偏压
2008-12-05 VER1.1 LIN
*/
#include <reg51.h>
#include <intrins.h>
sbit SDA=P1^0;
sbit SCL=P1^1;
sbit duty_4=P1^2;
sbit duty_1=P1^3;
sbit duty_2=P1^4;
sbit duty_3=P1^5;
sbit bias_2=P1^6;
sbit bias_3=P1^7;
sbit key_reset=P3^2;
sbit key_bias=P3^3;
sbit key_duty=P3^4;
//=======================
#define uchar unsigned char
#define uint unsigned int
#define duty 0x01
#define bias 0x02
#define reset 0x03
#define pkey P3
#define pled P1
//========================
uchar key_delay500ms=0;
uchar key_delay10ms=0;
uchar key_true=0;
uchar key_one=0;
uchar keycode_send=0;
uchar reset_w=0;
uchar iic_work=0;
//==========================
uchar counter=0;
uchar mode_set=0xc8;
uchar duty_buf=0; // 1/4duty
uchar bias_buf=0; // 1/3bias
uchar keybuf=0;
uchar timer;
uchar timeout=0;
uchar code display_dat[]= {//1 2 3 4 5 6 7 8 //
0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0xFF };
//==============================
// 延时
//==============================
void longdelay(uchar tt)
{
uchar ii,kk;
while (tt)
{
for (ii=0;ii<255;ii++)
{
for (kk=0;kk<255;kk++){}
}
tt--;
}
}
//=========================
void iic_delay(uchar n)
{
uchar i,ii;
for(ii=0;ii<n;ii++)
{
for(i=0;i<100;i++) { }
}
}
//==============================
void i2c_delay()
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
///////////////////////////////////
//#pragma disable
void I2C_Stop() //I2C STOP
{
SDA=0;
_nop_();
SCL=1;
_nop_();
_nop_();
SDA=1;
}
//=============================
void I2C_ack() //I2C STOP
{
iic_work=1;
timer=0;
timeout=0;
SDA=1;
SCL=0;
_nop_();
SCL=1;
_nop_();
//while(SDA){;}
while(SDA)
{
if(timeout==1)
{
i2c_delay();
I2C_Stop();
longdelay(1);
goto out;
}
}
SCL=0;
_nop_();
out: iic_work=0;
}
//////////////////////////////////////////
//#pragma disable
void I2C_SendByte(uchar SData)
{
uchar i;
SCL=0;
i2c_delay();
for(i=0;i<8;i++)
{
SDA=(bit)(SData&0x80);
SCL=1;
_nop_();
_nop_();
SCL=0;
SData=SData<<1;
}
I2C_ack();
}
/////////////////////////////////
void I2C_Start(uchar ICaddr) //I2C START
{
SDA=1;
SCL=1;
i2c_delay();
SDA=0;
i2c_delay();
SCL=0;
I2C_SendByte(ICaddr); //EEPROM address(write device)
}
//=====================================
//
//=====================================
void clear_display()
{
uchar i,n;
if(duty_buf==0){n=18;} //4 duty 40/2-1
if(duty_buf==1){n=4;} //1 duty 40/8-1
if(duty_buf==2){n=9;} //2 duty 40/4-1
if(duty_buf==3){n=12;} // 3 duty 40/2-1
do
{
I2C_Start(0x70); //send sub address */
I2C_SendByte(0x00); //lcd address
for (i=0;i<n;i++)
{
I2C_SendByte(0x00); //display data
}
}
while(timeout==1);
I2C_Stop();
iic_delay(1); //5cm
}
//=============================
//
//============================
void int_t0() interrupt 1 using 2
{
TH0=0xdc; //中断0,工作在方式1,定时初值10ms
TL0=0x00;
if(iic_work==1)
{
timer++;
if(timer==2)
{
timer=0;
timeout=1;
}
}
counter++;
if(counter==50)
{
counter=0;
key_delay500ms=1;
}
key_delay10ms=1;
}
//===============================
//
//===============================
void lcminti(uchar dat)
{
do
{
I2C_Start(0x70); //send sub address */
I2C_SendByte(dat); //mode set
}
while(timeout==1);
I2C_Stop();
iic_delay(1); //5cm
clear_display();
}
//========================================
//
//========================================
void function_work(uchar addr,uchar dat)
{
do
{
I2C_Start(0x70); //send sub address */
I2C_SendByte(addr); //lcd address
I2C_SendByte(dat); //display data
}
while(timeout==1);
I2C_Stop();
iic_delay(1); //5cm
}
//=========================================
// //============OK=============//
//=========================================
void mcuinti()
{
pled=pled&0x03;
TMOD=0x21; //置T1工作方式2 置T0工作方式1
TH0=0xdc; //T0,工作在方式1,定时初值10ms
TL0=0x00;
TR0=1; //启动T0,启动T1,
ET0=1,EA=1; // 开中断
}
//=====================================
//
//====================================
void key_work(uchar s)
{
uchar temp;
switch (s)
{
case reset:
{
clear_display(); //clear display
reset_w=1; //set address=0;
break;
}
case duty:
{
duty_buf++;
if (duty_buf==4){duty_buf=0;}
pled=pled&0xc3;
pled=pled|(0x04<<duty_buf);
temp=mode_set|duty_buf;
if(duty_buf==0) //等于4duty 自动变为1/3bias
{
bias_buf=0;
pled=pled&0x3f;
pled=pled|0x80;
}
else //小于4duty 自动变为1/2bias
{
temp=temp|0x04;
bias_buf=1;
pled=pled&0x3f;
pled=pled|0x40;
}
// if(bias_buf==1){temp=temp|0x04;}
lcminti(temp);
break;
}
case bias:
{
bias_buf++;
if (bias_buf==2){bias_buf=0;}
pled=pled&0x3f;
pled=pled|(0x80>>bias_buf);
temp=mode_set|duty_buf;
if(bias_buf==1){temp=temp|0x04;}
lcminti(temp);
break;
}
default: break;
}
}
//==========================================
// //============OK=============//
//==========================================
uchar scan_keypad(void)
{
uchar dat;
dat=0;
key_reset=1;
key_bias=1;
key_duty=1;
switch (pkey&0x1c)
{
case 0x0c: //duty
{
dat=duty;
break;
}
case 0x14: // bias
{
dat=bias;
break;
}
case 0x18: // reset
{
dat=reset;
break;
}
default: break;
}
return(dat);
}
//=========================
// //============OK=============//
//=========================
void keypad_chack()
{
uchar dat;
dat=scan_keypad();//进行按键检测
if(key_true==0) //按键值确认
{ //NO
if(key_one==0) //是第一次键值吗?
{
if(dat!=0) //有按键吗?
{
keybuf=dat; //save keypad code
key_one=1;
}
}
else //是第二次
{
if(keybuf==dat)//第一次数据与后一次数据相同
{ key_true=1; } //YES 按键值确认
key_one=0;
}
}
else
{
if(dat==0) //按键释放吗?
{ //YES
key_true=0; //从新按键
评论0