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

📄 at03.c

📁 基于AT24C02的LCD显示
💻 C
字号:
/* 这里举出一个实例(读写串行EEPROM芯片at2402) */ 
/************************************************************************/ 
/* Name:AT24C02存储器的读写程序,用到I2C总线,含相对独立的I2C总线读写函数 */ 
/************************************************************************/ 
#include<string.h> 
#include<reg52.h> 
#include<intrins.h> 
#define uchar unsigned char
#define uint unsigned int
//#define DELAY_TIME 60 /*经实验,不要小于50!否则可能造成时序混乱*/ 
//#define TRUE 1 
//#define FALSE 0 
sbit SCL=P2^6;/*假设由P3.4和P3.5控制*/ 
sbit SDA=P2^7;
 
sbit LCD_RS=P3^5;
sbit LCD_RW=P3^6;
sbit LCD_E=P3^7;

/********** Function Definition 函数定义 ************/ 
void DELAY(unsigned int t) /*延时函数*/ 
{ 
while(t!=0) 
t--; 
} 
void I2C_Start(void) 
{ 
/*启动I2C总线的函数,当SCL为高电平时使SDA产生一个负跳变*/ 
SDA=1; 
SCL=1; 
DELAY(60); 
SDA=0; 
DELAY(60); 
SCL=0; 
DELAY(60); 
} 
void I2C_Stop(void) 
{ 
/*终止I2C总线,当SCL为高电平时使SDA产生一个正跳变*/ 
SDA=0; 
SCL=1; 
DELAY(60); 
SDA=1; 
DELAY(60); 
SCL=0; 
DELAY(60); 
} 
void SEND_0(void) /* SEND ACK */ 
{ 
/*发送0,在SCL为高电平时使SDA信号为低*/ 
SDA=0; 
SCL=1; 
DELAY(60); 
SCL=0; 
DELAY(60); 
} 
void SEND_1(void) 
{ 
/*发送1,在SCL为高电平时使SDA信号为高*/ 
SDA=1; 
SCL=1; 
DELAY(60); 
SCL=0; 
DELAY(60); 
} 
bit Check_Acknowledge(void) 
{ 
/*发送完一个字节后检验设备的应答信号*/ 
SDA=1; 
SCL=1; 
DELAY(30); 
F0=SDA; 
DELAY(30); 
SCL=0; 
DELAY(60); 
if(F0==1) 
return 0; 
return 1; 
} 
void WriteI2CByte(char b)reentrant 
{ 
/*向I2C总线写一个字节*/ 
char i; 
for(i=0;i<8;i++) 
if((b<<i)&0x80) 
SEND_1(); 
else 
SEND_0(); 
} 
char ReadI2CByte(void)reentrant 
{ 
/*从I2C总线读一个字节*/ 
char b=0,i; 
for(i=0;i<8;i++) 
{ 
SDA=1; /*释放总线*/ 
SCL=1; /*接受数据*/ 
DELAY(10); 
F0=SDA; 
DELAY(10); 
SCL=0; 
if(F0==1) 
{ 
b=b<<1; 
b=b|0x01; 
} 
else 
b=b<<1; 
} 
return b; 
} 
/**********以下为读写24c02的函数**********/ 
void Write_One_Byte(char addr,char thedata) 
{ 
bit acktemp=1; 
/*write a byte to mem*/ 
I2C_Start(); 
WriteI2CByte(0xa0); 
acktemp=Check_Acknowledge(); 
WriteI2CByte(addr); /*address*/ 
acktemp=Check_Acknowledge(); 
WriteI2CByte(thedata); /*thedata*/ 
acktemp=Check_Acknowledge(); 
I2C_Stop();
 DELAY(60); 
} 

void Write_A_Page(char addr,char *buffer,char num) 
{ 
bit acktemp=1; 
//bit wrtmp; 
int i; 
/*write a page to at24c02*/ 
I2C_Start(); 
WriteI2CByte(0xa0); 
acktemp=Check_Acknowledge(); 
WriteI2CByte(addr);/*address*/ 
acktemp=Check_Acknowledge(); 
for(i=0;i<num;i++) 
{ 
WriteI2CByte(buffer[i]); 
if(!Check_Acknowledge()) 
{ 
I2C_Stop(); 
} 
} 
I2C_Stop(); 
DELAY(60); 

} 

char Read_One_Byte(char addr) 
{ 
bit acktemp=1; 
char mydata; 
/*read a byte from mem*/ 
I2C_Start(); 
WriteI2CByte(0xa0); 
acktemp=Check_Acknowledge(); 
WriteI2CByte(addr);/*address*/ 
acktemp=Check_Acknowledge(); 
I2C_Start(); 
WriteI2CByte(0xa1); 
acktemp=Check_Acknowledge(); 
mydata=ReadI2CByte(); 
acktemp=Check_Acknowledge(); 
return mydata; 
I2C_Stop(); 
} 

void Read_N_Bytes(char addr,char *buffer,char n) 
{ 
bit acktemp=1; 
int i=0; 
/*read 8 bytes from mem*/ 
I2C_Start(); 
WriteI2CByte(0xa0); 
acktemp=Check_Acknowledge(); 
WriteI2CByte(addr);/*address*/ 
acktemp=Check_Acknowledge(); 
I2C_Start(); 
WriteI2CByte(0xa1); 
acktemp=Check_Acknowledge(); 
for(i=0;i<n;i++) 
{ 
buffer[i]=ReadI2CByte(); 
if(i!=n-1) 
SEND_0(); /*发送应答*/ 
else 
SEND_1(); /*发送非应答*/ 
} 
I2C_Stop(); 
} 
/***********************************/

/*-------------------------------------- 
;模块名称:delay_n10us(); 
;功    能:延时函数,延时约n个10us
;-------------------------------------*/
void delay_n10us(uint n)  //延时n个10us@12M晶振
{       
        uint i;           
        for(i=n;i>0;i--)    
        {
        _nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); 
		}
} 

/*-------------------------------------- 
;模块名称:LCD_write_command(); 
;功    能:LCD1602写指令函数 
;-------------------------------------*/ 
void LCD_write_command(uchar dat)
{
delay_n10us(10);
LCD_RS=0;         //指令
LCD_RW=0;         //写入
LCD_E=1;          //允许
P0=dat;
delay_n10us(10);  //实践证明,我的LCD1602上,用for循环1次就能完成普通写指令。
LCD_E=0;
delay_n10us(10);  //实践证明,我的LCD1602上,用for循环1次就能完成普通写指令。
}

/*-------------------------------------- 
;模块名称:LCD_init(); 
;功    能:初始化LCD1602 
;-------------------------------------*/ 
void LCD_init(void)
{
delay_n10us(10);
LCD_write_command(0x38);//设置8位格式,2行,5x7
delay_n10us(10);
LCD_write_command(0x0c);//整体显示,关光标,不闪烁
delay_n10us(10);
LCD_write_command(0x06);//设定输入方式,增量不移位
delay_n10us(10);
LCD_write_command(0x01);//清除屏幕显示
delay_n10us(100);       //延时清屏,延时函数,延时约n个10us
LCD_write_command(0x0d);////开显示,并显示光标
delay_n10us(100);       //延时清屏,延时函数,延时约n个10us
}


/*-------------------------------------- 
;模块名称:LCD_write_data(); 
;功    能:LCD1602写数据函数 
;-------------------------------------*/
void LCD_write_data(uchar dat)
{
delay_n10us(10);
LCD_RS=1;          //数据
LCD_RW=0;          //写入
LCD_E=1;           //允许
P0=dat;
delay_n10us(10);
LCD_E=0;
delay_n10us(10);
}

/*-------------------------------------- 
;模块名称:LCD_disp_char(); 
;功    能:LCD1602显示一个字符函数,在某个屏幕位置上显示一个字符,X(0-15),y(1-2)。
;-------------------------------------*/
void LCD_disp_char(uchar x,uchar y,uchar dat)
{
  uchar address;
  if(y==1)
         address=0x80+x;
  else
         address=0xc0+x;
  LCD_write_command(address);
  LCD_write_data(dat);
}

/*-------------------------------------- 
;模块名称:LCD_disp_str(); 
;功    能:LCD1602显示字符串函数,在某个屏幕起始位置{X(0-15),y(1-2)}上显示一个字符串。
;-------------------------------------*/
void LCD_disp_str(uchar x,uchar y,uchar *str)
{
  uchar address;
  if(y==1)
         address=0x80+x;
  else
         address=0xc0+x;
  LCD_write_command(address);
  while(*str!='\0')
  { 
    LCD_write_data(*str);   
    str++;
  }
}

void main() 
{ 
//int i;

char mybyte; 
char code myarray[15]={0x46,0x4C,0x59,0x3A,0x31,0x33,0x36,0x34,0x30,0x33,0x30,0x38,0x30,0x34,0x31}; 
char code myarray2[9]={0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49};
char rdarray[20]; 

//Write_One_Byte(0x20,0x34); 
Write_A_Page(0x00,myarray2,9); 
//Write_A_Page(0x18,myarray2,9); 
mybyte=Read_One_Byte(0x00); 
Read_N_Bytes(0x00,rdarray,9); 
P1=rdarray[8];
LCD_init();
LCD_disp_str(0,1,myarray2);
LCD_disp_str(0,2,rdarray);

} 

⌨️ 快捷键说明

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