抄了一位兄台的程序的1602的显示部分,后来又看了多位高手的AT24C02的读写部分,
大家真是怎么写的都有哇!尤其SCL和SDA电平的变化顺序,除了Start信号和Stop信号,
在read_byte和write_byte时,由于是循环操作,顺序上出入较大,不过大体相同,在此
感谢老古开发网的“I2C读写心得(AT24C02篇)(转)”和“电子制作实验室网站提供的AT89C51访问AT24C02。下面是它的电路图。
图中AT24C02的1、2、3脚是三条地址线,用于确定芯片的硬件地址。在AT89C51试验开发板上它们都接地,第8脚和第4脚分别为正、负电源。第5脚SDA为串行数据输入/输出,数据通过这条双向I2C总线串行传送,在AT89C51试验开发板上和单片机的P3.5连接。第6脚SCL为串行时钟输入线,在AT89C51试验开发板上和单片机的P3.6连接。SDA和SCL都需要和正电源间各接一个5.1K的电阻上拉。第7脚需要接地。
及百度知道里的一位仁兄,找不到那篇文档了,不过感谢!我觉得就你写的最好。最后说下这个
void I2C_TestACK(void){
Wait10us;
} //试验了多种测试ack的方法,迷糊,就是不怎么好用,最后被我改成这样了,然后程序就通过了!
下面贴程序(事先声明,这些不是我写的,我只是把大家写的综合了一下!)
- #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 P3 //定义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 12
- /*************************以下是函数的申明部分*************************/
- 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);
- bit 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]={'A','B','C','D','1','2','3',')','\0','\0','\0','\0'};
- //unsigned char sharebuf[NUM];
- unsigned char readbuf[NUM];
- /********************************************************************/
- delay32()
- {
- unsigned int i=300;
- while(i--);
- }
- void main()
- {
- unsigned char temp;
- Mcu_init();
- AT24C02_write(0x00,sharebuf,8);
- AT24C02_read(0x00,readbuf,8);
- //LCD_write_char(0x08,LINE2,(readbuf[3]/10)|0x30);
- //LCD_write_char(0x09,LINE2,(readbuf[3]%10)|0x30);
- //LCD_write_char(0x0a,LINE2,(readbuf[4]/10)|0x30);
- //LCD_write_char(0x0b,LINE2,(readbuf[4]%10)|0x30);
- //LCD_write_char(0x0c,LINE2,(readbuf[5]/10)|0x30);
- //LCD_write_char(0x0d,LINE2,(readbuf[5]%10)|0x30);
- //LCD_write_char(0x0e,LINE2,(readbuf[6]/10)|0x30);
- //LCD_write_char(0x0f,LINE2,(readbuf[6]%10)|0x30);
- LCD_write_string(0x00,LINE1,sharebuf);
- LCD_write_string(0x00,LINE2,readbuf);
- while(1){}
-
- /*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;
- }
- //12ms中断1次
- }
- /***********************************************************************/
- void Mcu_init(void)
- {
- TMOD=0x01;
- TH0=-(12000/256);
- TL0=-(12000%256);
- EA=HIGH; //启用所有中断功能
- ET0=HIGH; //启用TF0中断功能;
- //以上两句相当于 IE= 0x82;
- TR0=HIGH; //启动定时器0;
- LCD_init();
- }
- /***********************************************************************/
- /******************************** I2C PART **************************/
- void I2C_start(void)
- {
- SCL=1; Wait2us;
- SDA=1; Wait2us;
- SDA=0; Wait2us;
- SCL=0; Wait2us;
- }
- /***********************************************************************/
- void I2C_stop(void)
- {
- SDA=0;Wait2us;
- SCL=1;Wait2us;
- SDA=1;Wait2us;
- SCL=0;Wait2us;
- }
- /***********************************************************************/
- void I2C_send_ack(bit sig)
- {
- SDA=0;Wait2us
- SCL=1;Wait2us
- SCL=0;Wait2us
- SDA=1;
- }
- /*************************************************************************/
- void I2C_send_noack(void)
- {
- SDA=1;Wait2us
- SCL=1;Wait2us
- SCL=0;
- }
- /*****************************************************************************/
- void I2C_send_ackold(bit sig)
- {
- SDA=sig;
- SCL=0;Wait2us;
- SCL=1;Wait2us;
- SCL=0;Wait2us;
- }
- void I2C_TestACK(void){
- Wait10us;
-
- }
- /***********************************************************************/
- bit I2C_write_byte(unsigned char input)
- {
- bit ack;
- unsigned char temp;
- for(temp=0;temp<8;temp++)
- {
- SDA=0;
- if ((input<<temp)&0x80){SDA=1;}
- SCL=1;Wait2us;
- SCL=0;
- }
- SDA=1;Wait2us;//释放数据线,准备接收应答信号
- ack=SDA;
- SCL=1;Wait2us;
- SCL=0;
- return ack;
- }
- /***********************************************************************/
- unsigned char I2C_read_byte(void)
- {
- unsigned char temp,rbyte=0;
- SDA=1;
- for(temp=0;temp<8;temp++)
- {
- SCL=0;Wait2us
- SCL=1;
- rbyte<<=1;
- if (SDA==1){rbyte+=1;}
- }
- SCL=0;
- return(rbyte);
- }
- /************************************************************************/
- void AT24C02_write(unsigned char address,unsigned char *buf,unsigned char Nbyte)
- {
- I2C_start();
- I2C_write_byte(WRITE24C02);
- I2C_TestACK();
- I2C_write_byte(address);
- I2C_TestACK();
- for(;Nbyte!=0;Nbyte--)
- {
- I2C_write_byte(*buf);
- I2C_TestACK();
- buf++;
- }
- I2C_TestACK();
- I2C_stop();
- delay_ms(10);//这个很重要,调了几天问题就是出在h里的,最好在每个函数之间加延时
- }
- /************************************************************************/
- void AT24C02_read(unsigned char address,unsigned char *buf,unsigned char Nbyte)
- {
- I2C_start();
- I2C_write_byte(WRITE24C02);
- I2C_TestACK();
- I2C_write_byte(address);
- I2C_TestACK();
-
- I2C_start();
- I2C_write_byte(READ24C02);
- I2C_TestACK();
- while(Nbyte!=1)
- {
- *buf=I2C_read_byte();
- I2C_send_ack(0);
- 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<LINE_LENGTH)
- {
- LCD_send_command(LINE1_HEAD+x);
- for(;x<LINE_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(;x<LINE_LENGTH&&*Data!='\0';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++)
- ;
- }
- /*********************************************************************/
不插连接图了,看的懂的看程序就知道线是怎么连的。
阅读(8636) | 评论(0) | 转发(0) |