⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcf8576.c

📁 用于测试笔段的LCD屏
💻 C
字号:
/*用于测试笔段的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;     //从新按键值确认
          keycode_send=1; //允许按键值发送
	 }
   }
}


 //================================================
 // 主程序
 //================================================
 main ()
 {
 
  uchar address=3;
  uchar ii,addr_number;
  uchar temp=0;
  
  iic_delay(5);
  mcuinti();
  pled=pled|0x84;//1/4duty,1/3bias LED on
  lcminti(mode_set);
  //===================
 for(;;)     //无终止循环体
     {
  //===============================
   if(key_delay500ms==1)   //0.5s显示一段
           {
           if(reset_w==1){address=3,temp=0,reset_w=0;}
           function_work(address,display_dat[temp]);
           key_delay500ms=0;
           temp++;
           if(temp>7)
               {
               temp=0;
               ii++;
               if(duty_buf==0){address=address+2;addr_number=18;}
               if(duty_buf==1){address=address+8;addr_number=4;}
               if(duty_buf==2){address=address+4;addr_number=9;}
               if(duty_buf==3){address=address+3;addr_number=12;}
               if(ii==addr_number)
                 {
                 address=3;
                 ii=0;
                 clear_display();
                 }      //4*8
               }
           }
 //=======================================
   if(key_delay10ms==1)   //10ms检测一次键盘
           {
            keypad_chack();
            key_delay10ms=0;
           }
   if(keycode_send==1)//有按键释放可以执行
  	    {
            EA=0;
            reset_w=1;
            key_work(keybuf);
            keycode_send=0; //发送完毕
            EA=1;
  	    }
    }
 }








⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -