test.c

来自「I2c如 IIc 24LC64等器件的51单片机驱动程序,已经通过实际验证,很好」· C语言 代码 · 共 303 行

C
303
字号
#include<reg51.h>

#define uint unsigned int
#define uchar unsigned char
 
#define delaylcd 1
#define LCD_Data P1 
#define HIGH 1
#define LOW 0 
uchar tmp[4] ;
sbit  RS  = P2^0 ;
sbit  RW  = P2^1 ;
sbit  EN  = P2^2 ;

sbit SDA=P2^3;
sbit SCL=P2^4; 

void Delay_nms(uint Delay); // f = 4 MHZ
 
void WRiteData(unsigned char WDLCM);
 
void WRiteCommand(unsigned char WCLCM); 

void LCDInit(void);
 
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData); 

void DisplayOnedata(unsigned char X, unsigned char Y, unsigned int DData); 

void DisplayListChar(unsigned char X, unsigned char Y, unsigned char const *DData); 



void delay( uint a)  //100<->2.424ms
{ 
  uint K;
  for( K=0;K<a;K++)
  ;
}

////////////////////////////////I2C///////////////////////////////////////
//提供I2C总线工作时序中的起始位
void I_start(void)
{
	SDA = HIGH;
	delay(4);
	SCL = HIGH;
	delay(4);
	SDA = LOW;//当SCL为高时,SDA的一个下降沿作为起始位
	delay(4);
	SCL = LOW;
	delay(4);
}
//提供I2C总线工作时序中的停止位
void I_stop(void)
{
	SDA = LOW;
	delay(4);
	SCL = HIGH;
	delay(4);
	SDA = HIGH;//当SCL为高时,SDA的一个上升沿作为停止位
	delay(4);
	SCL = LOW;
	delay(4);
}
  
//提供I2C总线的时钟信号,并返回时钟电平为高期间SDA信号线上状态
bit I_clock(void)
{
	bit sample;
	SCL = HIGH;
	delay(4);
	sample = SDA;
	SCL = LOW;
	delay(4);
	return (sample);
}
//向I2C总线发送8位数据,并请求一个应答信号ACK。如果收到ACK应答,则返回1,否则返回0。
bit I_send(uchar I_data)
{
	register uchar i;
	/*发送8位数据*/
 
	for(i=0;i<8;i++)
	{
		SDA = (bit)(I_data & 0x80);
		I_data <<= 1;
		I_clock();
	}
	/*请求应答信号ACK*/
	SDA = HIGH;
	delay(4);
	return(~I_clock());
}
//从I2C总线上接收8位数据信号,并将接收到的8位数据作为一个字节返回,不回送应答信号。
//主函数在调用本函数之前应保证SDA信号线处于浮置状态,SDA=1.
uchar I_receive(void)
{
	uchar I_data = 0;
	register uchar i;
	for(i=0;i<8;i++)
	{
		I_data*=2;
		if(I_clock())I_data++;
	}
	return (I_data);
}

uchar readI2c ( uchar address )
{
  uchar ibuf = 0 ;
  I_start() ;
  I_send(0xa0);
  Delay_nms(5);
  I_send(0x00);
  Delay_nms(5);
  I_send( address );
  Delay_nms(5);
  I_start() ;
  Delay_nms(5);
  I_send(0xa1);
  ibuf = I_receive() ;
  I_stop( ) ;
  return ibuf ;
}
   
 

void writeI2c ( ) // 首地址 秒/分/时/天
{

  I_start() ;
  I_send(0xa0);
  Delay_nms(5);
  I_send(0x00);
  Delay_nms(5);
  I_send(0x00);
  Delay_nms(5);
  I_send(0x01);  
  Delay_nms(5);
  I_send(0x02);  
  Delay_nms(5);
  I_send(0x03);
  Delay_nms(5);
  I_send(0x04);  
  Delay_nms(5);
  I_stop( ) ;
  Delay_nms(5);
}

 
void main(void) 
{ 
  uchar buf = 0 ;
  LCDInit() ; 
  DisplayOnedata(0,0,123 ) ;

  writeI2c() ;
  DisplayOnedata(0,1,readI2c(0)) ; 
  DisplayOnedata(3,1,readI2c(1)) ; 
  DisplayOnedata(6,1,readI2c(2)) ; 
  DisplayOnedata(9,1,readI2c(3)) ;
  
  DisplayOnedata(5,0,456 ) ;
  while( 1 ) ;
    
   
 }

void Delay_nms(uint Delay) // f = 6MHZ
{ uint i;
  for(;Delay>0;Delay--)
   { for(i=0;i<83;i++)
         ;
   }
}

/*----------------------------------------------------------------*/ 
/*     写数据                                                     */
/*     输入:RS=1,WR=0,E=1,D0~D7=数据,E=高脉冲     输出:无    */ 
/*----------------------------------------------------------------*/ 

void WRiteData(unsigned char WDLCM) 
{ 
  Delay_nms( delaylcd ) ;
  //check_busy() ;
  LCD_Data = WDLCM; 
  RS=1; 
  RW=0; 
  EN=0; //若晶振速度太高可以在这后加小的延时 
   
  EN=1; 

  EN=0;

} 

/*----------------------------------------------------------------*/ 
/*     写指令                                                     */
/*     输入:RS=0,WR=0,E=1,D0~D7=指令码,E=高脉冲     输出:无  */ 
/*----------------------------------------------------------------*/ 
void WRiteCommand(unsigned char WCLCM  ) //BuysC为0时忽略忙检测 
{ 
   Delay_nms( delaylcd ) ; 
  
   LCD_Data = WCLCM; 
   RS = 0; 
   RW = 0; 
   EN=0; //若晶振速度太高可以在这后加小的延时 

   EN=1; 

   EN=0;
} 


 

void LCDInit(void) //LCM初始化 
{ 
   LCD_Data = 0; 
   WRiteCommand(0x38); //三次显示模式设置,不检测忙信号 
   Delay_nms(delaylcd); 
   WRiteCommand(0x38); 
   Delay_nms(delaylcd); 
   WRiteCommand(0x38); 
   Delay_nms(delaylcd); 

   WRiteCommand(0x38); //显示模式设置,开始要求每次检测忙信号 
   WRiteCommand(0x08); //关闭显示 
   WRiteCommand(0x01); //显示清屏 
   WRiteCommand(0x06); // 显示光标移动设置 
   WRiteCommand(0x0C); // 显示开及光标设置  
} 

//按指定位置显示一个字符 
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData) 
{ 

  Y &= 0x1; 
  X &= 0xF;         //限制X不能大于15,Y不能大于1 
  if (Y) 
     X |= 0x40;     //当要显示第二行时地址码+0x40; 
  X |= 0x80;        // 算出指令码 
  WRiteCommand(X);  //这里不检测忙信号,发送地址码 
  WRiteData(DData); 

} 

void DisplayOnedata(unsigned char X, unsigned char Y, unsigned int DData)
{
	 unsigned char i = 0 ;
      tmp[3] = tmp[2]= tmp[1] = tmp[0]= 0 ;
      while( DData )
       {
	       tmp[i] = 0x30 + DData% 10 ;
	       i++;
           DData /=10 ;
       }
       i--;
      while( i !=0xff ) 
        { 
	        DisplayOneChar( X, Y, tmp[i] ) ;
	        X++ ;
	        i--;
	    }  
 } 
//按指定位置显示一串字符  
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char const *DData) 
{ 
  unsigned char ListLength; 

  ListLength = 0; 
  Y &= 0x1; 
  X &= 0xF;  
  while ( DData[ListLength] != '\0' )  
  { 
     
     DisplayOneChar(X, Y, DData[ListLength]);  
     ListLength++; 
     X++; 
	 if ( X == 16  )
       {  Y ++ ;
          X = 0;
		  if( Y == 2 )
		    {
			  Y = 0 ;
		      Delay_nms(2000);
		      WRiteCommand(0x01 );  
 		    }
       }
   } 
} 

    

 


 

 

⌨️ 快捷键说明

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