工业控制 | 能源技术 | 汽车电子 | 通信网络 | 安防监控 | 智能电网 | 移动手持 | 无线技术 | 家用电器 | 数字广播 | 消费电子 | 应用软件 | 其他方案

I2C读写心得(AT24C02篇)

作者:dolphin时间:2012-10-31

困扰我几的程序终于搞定了,前几天我对AT24C02一直读不准确,找了N长时间的程序都没有头绪,后来在板哥的指点下,一下子明白了,原因很简单,我在AT24C02_read()最后没有加延时,
主要还是对时序没有控制好呀,用板哥的一句话是我们对器件的了解还不很熟,我现在也感到,一定要先了解了器件的特性,我们才能游刃有余把握住每一个容易疏忽的细节,在这里,板哥确实教会了我好多东西,在我刚学单片机时,他就对我说时序很重要,现在终于是看到了.
好了不罗嗦了,最后得出一点,最好在每个读写结束时加个延时,如果对时间要求不是很重要的话,加的长一点无所谓,如果要求比较高的话,那先加长延时,然后慢慢的减.
#include reg51.h
#include intrins.h
/*********************************LCD定义部分********************************/
//输入方式设置
#define LCD_AC_AUTO_INCREMENT 0x06 //数据读、写操作后,AC自动增一
#define LCD_AC_AUTO_DECREASE 0x04 //数据读、写操作后,AC自动减一
#define LCD_MOVE_ENABLE 0x05 //数据读、写操作,画面平移
#define LCD_MOVE_DISENABLE 0x04 //数据读、写操作,画面不动
#define LCD_GO_HOME 0x02 //AC=0,光标、画面回HOME位
//设置显示、光标及闪烁开、关
#define LCD_DISPLAY_ON 0x0C //显示开
#define LCD_DISPLAY_OFF 0x08 //显示关
#define LCD_CURSOR_ON 0x0A //光标显示
#define LCD_CURSOR_OFF 0x08 //光标不显示
#define LCD_CURSOR_BLINK_ON 0x09 //光标闪烁
#define LCD_CURSOR_BLINK_OFF 0x08 //光标不闪烁
//光标、画面移动,不影响DDRAM
#define LCD_LEFT_MOVE 0x18 //LCD显示左移一位
#define LCD_RIGHT_MOVE 0x1C //LCD显示右移一位
#define LCD_CURSOR_LEFT_MOVE 0x10 //光标左移一位
#define LCD_CURSOR_RIGHT_MOVE 0x14 //光标右移一位
//工作方式设置
#define LCD_DISPLAY_DOUBLE_LINE 0x38 //两行显示
#define LCD_DISPLAY_SINGLE_LINE 0x30 //单行显示
#define LCD_CLEAR_SCREEN 0X01 //清屏
/***********************LCD1602地址相关******************************/
#define LINE1_HEAD 0x80 // 第一行DDRAM起始地址
#define LINE2_HEAD 0xc0 // 第二行DDRAM起始地址
#define LINE1 0 //第一行
#define LINE2 1 //第二行
#define LINE_LENGTH 16 //每行的最大字符长度
/***********************LCD1602接线引脚定义**************************
**********************可根据实际电路改变*******************************/
#define LCDIO P2 //定义P2口与LCD1602的数据口相接
sbit LCD_RS=P1^4;
sbit LCD_RW=P1^3;
sbit LCD_EN=P1^2;
sbit LCD_BUSY=LCDIO^7;
/**********************另外相关的定义*********************************/
#define HIGH 1
#define LOW 0
#define TURE 1
#define FALSE 0
#define uchar unsigned char
#define uint unsigned int
#define NUM 10
/*************************以下是函数的申明部分*************************/
void LCD_init(void); //LCD1602初始化
void LCD_send_command(uchar command); //
void LCD_send_data(uchar dat);
void LCD_write_char(uchar x,uchar y,uchar dat);
void LCD_write_string(uchar x,uchar y,char *Data);
void delay_ms(uint n);
void LCD_check_busy(void);
/*********************结束***********************************************/
//at24c02 part
#define WRITE24C02 0xA0
#define READ24C02 0xA1
//I2C part
#define Wait1us _nop_();
#define Wait2us {_nop_();_nop_();}
#define Wait4us {Wait2us;Wait2us;}
#define Wait8us {Wait4us;Wait4us;}
#define Wait10us {Wait8us;Wait2us;}
sbit SDA=P2^7; //AT24C02 serial data pin 5
sbit SCL=P2^6; //AT24C02 serial clock pin 6
/********************************************************************/
void I2C_start(void);//I2C start function
void I2C_stop(void);//I2C stop function
//void I2C_send_ack(void);//I2C send responsion function
void I2C_send_noack(void);
void I2C_write_byte(unsigned char IIC_data);//I2C bus write byte function
unsigned char I2C_read_byte(void);//I2C bus read byte function
/********************************************************************/
void AT24C02_write(unsigned char address,unsigned char *buf,unsigned char n);//write 24c02 information function
void AT24C02_read(unsigned char address,unsigned char *buf,unsigned char n);//read 24c02 information function
/********************************************************************/
void Mcu_init(void);//system initize funcition
void I2C_init(void);
unsigned char count[2];
unsigned char sharebuf[NUM];
/********************************************************************/
void main()
{
unsigned char temp;
Mcu_init();
while(1)
{
sharebuf[0]=count[1];
sharebuf[1]=count[0];
AT24C02_write(0x00,sharebuf,2);

AT24C02_read(0x00,sharebuf,2);
temp=sharebuf[0];
LCD_write_string(0x00,LINE1,AT24C02 TEST);
LCD_write_char(0x0e,LINE1,(temp/10) 0x30);
LCD_write_char(0x0f,LINE1,(temp%10) 0x30);
LCD_write_string(0x00,LINE2,TIMER0 JISHU);
LCD_write_char(0x0e,1,(count[1]/10) 0x30);
LCD_write_char(0x0f,1,(count[1]%10) 0x30);

}
}
/***********************************************************************/
void timer0(void) interrupt 1 using 1
{
TH0=-(12000/256);
TL0=-(12000%256);
count[0]=count[0]+1;
if(count[0]==100)
{
count[0]=0;
count[1]=count[1]+1;
if(count[1]==99)
count[1]=0;
}
}
/***********************************************************************/
void Mcu_init(void)
{
TMOD=0x01;
TH0=-(12000/256);
TL0=-(12000%256);
EA=HIGH;
ET0=HIGH;
TR0=HIGH;
LCD_init();
}
/***********************************************************************/
/******************************** I2C PART **************************/
void I2C_start(void)
{
SDA=1;
SCL=1;
SDA=0;
SCL=0;


}
/***********************************************************************/
void I2C_stop(void)
{
SCL=0;
SDA=0;
SCL=1;
SDA=1;

}
/***********************************************************************/
void I2C_send_ack(void)
{
SDA=0;
SCL=1;
SCL=0;
SDA=1;
}
/*************************************************************************/
void I2C_send_noack(void)
{
SDA=1;
SCL=1;
SCL=0;
}
/*****************************************************************************/
bit TestAck()
{
bit ErrorBit;
SDA=1;
SCL=1;
ErrorBit=SDA;
SCL=0;
return(ErrorBit);
}
/***********************************************************************/
void I2C_write_byte(unsigned char input)
{
unsigned char temp;
for(temp=8;temp!=0;temp--)
{
SDA=(bit)(input0x80);
SCL=1;
SCL=0;
input=input1;
}
}
/***********************************************************************/
unsigned char I2C_read_byte(void)
{
unsigned char temp,rbyte=0;
for(temp=8;temp!=0;temp--)
{
SCL=1;
rbyte=rbyte1;
rbyte=rbyte ((unsigned char)(SDA));
SCL=0;
}
return(rbyte);
}
/************************************************************************/
void AT24C02_write(unsigned char address,unsigned char *buf,unsigned char Nbyte)
{

I2C_start();
I2C_write_byte(WRITE24C02);
TestAck();
I2C_write_byte(address);
TestAck();
for(;Nbyte!=0;Nbyte--)
{
I2C_write_byte(*buf);
TestAck();
buf++;

}
I2C_stop();
delay_ms(10);//这个很重要,调了几天问题就是出在h里的,最好在每个函数之间加延时
}
/************************************************************************/
void AT24C02_read(unsigned char address,unsigned char *buf,unsigned char Nbyte)
{

I2C_start();
I2C_write_byte(WRITE24C02);
TestAck();
I2C_write_byte(address);
TestAck();

I2C_start();
I2C_write_byte(READ24C02);
TestAck();
while(Nbyte!=1)
{
*buf=I2C_read_byte();
I2C_send_ack();
buf++;

Nbyte--;
}
*buf=I2C_read_byte();
I2C_send_noack();
I2C_stop();



}
/**************LCD1602的初始化***************************/
void LCD_init(void)
{
LCD_send_command(LCD_DISPLAY_DOUBLE_LINE);
LCD_send_command(LCD_AC_AUTO_INCREMENT LCD_MOVE_DISENABLE);
LCD_send_command(LCD_DISPLAY_ON LCD_CURSOR_OFF);
LCD_send_command(LCD_CLEAR_SCREEN);
}
/***********************检测LCD状态*********************************/

void LCD_check_busy(void)
{
do
{
LCD_EN=0;
LCD_RS=0;
LCD_RW=1;
LCDIO=0xff;
LCD_EN=1;
}
while(LCD_BUSY==1);

LCD_EN=0;
}
/************LCD1602写命令*******************************/
void LCD_send_command(uchar command)
{
LCD_check_busy();
LCD_RS=LOW;
LCD_RW=LOW;
LCD_EN=HIGH;
LCDIO=command;
LCD_EN=LOW;
}
/********************************************************/
/*****************LCD1602写数据**************************/
void LCD_send_data(uchar dat)
{
LCD_check_busy();
LCD_RS=HIGH;
LCD_RW=LOW;
LCD_EN=HIGH;
LCDIO=dat;
LCD_EN=LOW;
}
/***********************LCD1602显示字符*********************************/
void LCD_write_char(uchar x,uchar y,uchar dat)
{
unsigned char address;
if (y == LINE1)
address = LINE1_HEAD + x;
else
address = LINE2_HEAD + x;
LCD_send_command(address);
LCD_send_data(dat);
}
/******************LCD1602显示字符串*********************/
void LCD_write_string(uchar x,uchar y,uchar *Data)
{
if(y==LINE1)
{
if(xLINE_LENGTH)
{
LCD_send_command(LINE1_HEAD+x);
for(;xLINE_LENGTH*Data!=''''\0'''';x++)
{
LCD_send_data(*(Data++));
}
if(*Data!=''''\0'''')
{
x=0;
y=LINE2;
}
}
}
if(y==LINE2)
{
LCD_send_command(LINE2_HEAD+x);
for(;xLINE_LENGTH*Data!=''''\0'''';x++)
{
LCD_send_data(*(Data++));
}
}
}
/****************************************************************/
/********************延时函数***********************************/

/***************************************************************/
void delay_ms(uint n)
{
uint i,j;
for(i=n;i0;i--)
for(j=0;j1140;j++)
;
}


关键词: 心得 void #define unsigned

评论

技术专区