| 困扰我几的程序终于搞定了,前几天我对AT24C02一直读不准确,找了N长时间的程序都没有头绪,后来在板哥的指点下,一下子明白了,原因很简单,我在AT24C02_read()最后没有加延时,主要还是对时序没有控制好呀,用板哥的一句话是我们对器件的了解还不很熟,我现在也感到,一定要先了解了器件的特性,我们才能游刃有余把握住每一个容易疏忽的细节,在这里,板哥确实教会了我好多东西,在我刚学单片机时,他就对我说时序很重要,现在终于是看到了.
好了不罗嗦了,最后得出一点,最好在每个读写结束时加个延时,如果对时间要求不是很重要的话,加的长一点无所谓,如果要求比较高的话,那先加长延时,然后慢慢的减. #include #include /*********************************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)(input&0x80); SCL=1; SCL=0; input=input<<1; } } /***********************************************************************/ unsigned char I2C_read_byte(void) { unsigned char temp,rbyte=0; for(temp=8;temp!=0;temp--) { SCL=1; rbyte=rbyte<<1; 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(x { LCD_send_command(LINE1_HEAD+x); for(;x { LCD_send_data(*(Data++)); } if(*Data!=''''\0'''') { x=0; y=LINE2; } } } if(y==LINE2) { LCD_send_command(LINE2_HEAD+x); for(;x { LCD_send_data(*(Data++)); } } } /****************************************************************/ /********************延时函数***********************************/ /***************************************************************/ void delay_ms(uint n) { uint i,j; for(i=n;i>0;i--) for(j=0;j<1140;j++) ; } /*********************************************************************/
|