Chinaunix首页 | 论坛 | 博客
  • 博客访问: 265808
  • 博文数量: 54
  • 博客积分: 1425
  • 博客等级: 上尉
  • 技术积分: 541
  • 用 户 组: 普通用户
  • 注册时间: 2005-08-27 23:26
文章分类

全部博文(54)

文章存档

2018年(2)

2015年(3)

2014年(6)

2013年(5)

2012年(5)

2011年(7)

2010年(14)

2009年(1)

2008年(3)

2007年(6)

2006年(1)

2005年(1)

我的朋友

分类: 嵌入式

2011-03-12 12:44:14

    抄了一位兄台的程序的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的方法,迷糊,就是不怎么好用,最后被我改成这样了,然后程序就通过了!

下面贴程序(事先声明,这些不是我写的,我只是把大家写的综合了一下!)

 

  1. #include <reg51.h>
  2. #include <intrins.h>
  3. /*********************************LCD定义部分********************************/
  4. //输入方式设置

  5. #define LCD_AC_AUTO_INCREMENT 0x06 //数据读、写操作后,AC自动增一

  6. #define LCD_AC_AUTO_DECREASE 0x04 //数据读、写操作后,AC自动减一

  7. #define LCD_MOVE_ENABLE 0x05 //数据读、写操作,画面平移

  8. #define LCD_MOVE_DISENABLE 0x04 //数据读、写操作,画面不动

  9. #define LCD_GO_HOME 0x02 //AC=0,光标、画面回HOME位

  10. //设置显示、光标及闪烁开、关

  11. #define LCD_DISPLAY_ON 0x0C //显示开

  12. #define LCD_DISPLAY_OFF 0x08 //显示关

  13. #define LCD_CURSOR_ON 0x0A //光标显示

  14. #define LCD_CURSOR_OFF 0x08 //光标不显示

  15. #define LCD_CURSOR_BLINK_ON 0x09 //光标闪烁

  16. #define LCD_CURSOR_BLINK_OFF 0x08 //光标不闪烁

  17. //光标、画面移动,不影响DDRAM

  18. #define LCD_LEFT_MOVE 0x18 //LCD显示左移一位

  19. #define LCD_RIGHT_MOVE 0x1C //LCD显示右移一位

  20. #define LCD_CURSOR_LEFT_MOVE 0x10 //光标左移一位

  21. #define LCD_CURSOR_RIGHT_MOVE 0x14 //光标右移一位

  22. //工作方式设置

  23. #define LCD_DISPLAY_DOUBLE_LINE 0x38 //两行显示

  24. #define LCD_DISPLAY_SINGLE_LINE 0x30 //单行显示

  25. #define LCD_CLEAR_SCREEN 0X01 //清屏

  26. /***********************LCD1602地址相关******************************/
  27. #define LINE1_HEAD 0x80 // 第一行DDRAM起始地址

  28. #define LINE2_HEAD 0xc0 // 第二行DDRAM起始地址

  29. #define LINE1 0 //第一行

  30. #define LINE2 1 //第二行

  31. #define LINE_LENGTH 16 //每行的最大字符长度

  32. /***********************LCD1602接线引脚定义**************************
  33. **********************可根据实际电路改变*******************************/
  34. #define LCDIO P3 //定义P2口与LCD1602的数据口相接

  35.   sbit LCD_RS=P1^4;
  36.   sbit LCD_RW=P1^3;
  37.   sbit LCD_EN=P1^2;
  38.   sbit LCD_BUSY=LCDIO^7;
  39.  /**********************另外相关的定义*********************************/
  40.  #define HIGH 1
  41.  #define LOW 0
  42.  #define TURE 1
  43.  #define FALSE 0
  44.  #define uchar unsigned char
  45.  #define uint unsigned int
  46.  #define NUM 12
  47.  /*************************以下是函数的申明部分*************************/
  48.  void LCD_init(void); //LCD1602初始化

  49.  void LCD_send_command(uchar command); //

  50.  void LCD_send_data(uchar dat);
  51.  void LCD_write_char(uchar x,uchar y,uchar dat);
  52.  void LCD_write_string(uchar x,uchar y,char *Data);
  53.  void delay_ms(uint n);
  54.  void LCD_check_busy(void);
  55.  /*********************结束***********************************************/
  56. //at24c02 part

  57. #define WRITE24C02 0xA0
  58. #define READ24C02 0xA1
  59. //I2C part

  60. #define Wait1us _nop_();
  61. #define Wait2us {_nop_();_nop_();}
  62. #define Wait4us {Wait2us;Wait2us;}
  63. #define Wait8us {Wait4us;Wait4us;}
  64. #define Wait10us {Wait8us;Wait2us;}
  65. sbit SDA=P2^7; //AT24C02 serial data pin 5

  66. sbit SCL=P2^6; //AT24C02 serial clock pin 6

  67. /********************************************************************/
  68. void I2C_start(void);//I2C start function

  69. void I2C_stop(void);//I2C stop function

  70. //void I2C_send_ack(void);//I2C send responsion function

  71. void I2C_send_noack(void);
  72. bit I2C_write_byte(unsigned char IIC_data);//I2C bus write byte function

  73. unsigned char I2C_read_byte(void);//I2C bus read byte function

  74. /********************************************************************/
  75. void AT24C02_write(unsigned char address,unsigned char *buf,unsigned char n);//write 24c02 information function

  76. void AT24C02_read(unsigned char address,unsigned char *buf,unsigned char n);//read 24c02 information function

  77. /********************************************************************/
  78. void Mcu_init(void);//system initize funcition

  79. void I2C_init(void);
  80. unsigned char count[2];
  81. unsigned char sharebuf[NUM]={'A','B','C','D','1','2','3',')','\0','\0','\0','\0'};
  82. //unsigned char sharebuf[NUM];

  83. unsigned char readbuf[NUM];
  84. /********************************************************************/
  85. delay32()
  86. {
  87. unsigned int i=300;
  88. while(i--);
  89. }

  90. void main()
  91. {
  92.  unsigned char temp;
  93.  Mcu_init();
  94.      AT24C02_write(0x00,sharebuf,8);
  95.      AT24C02_read(0x00,readbuf,8);
  96.      //LCD_write_char(0x08,LINE2,(readbuf[3]/10)|0x30);

  97.      //LCD_write_char(0x09,LINE2,(readbuf[3]%10)|0x30);

  98.      //LCD_write_char(0x0a,LINE2,(readbuf[4]/10)|0x30);

  99.      //LCD_write_char(0x0b,LINE2,(readbuf[4]%10)|0x30);

  100.      //LCD_write_char(0x0c,LINE2,(readbuf[5]/10)|0x30);

  101.      //LCD_write_char(0x0d,LINE2,(readbuf[5]%10)|0x30);

  102.      //LCD_write_char(0x0e,LINE2,(readbuf[6]/10)|0x30);

  103.      //LCD_write_char(0x0f,LINE2,(readbuf[6]%10)|0x30);

  104.       LCD_write_string(0x00,LINE1,sharebuf);
  105.      LCD_write_string(0x00,LINE2,readbuf);
  106.      while(1){}
  107.     
  108.  /*while(1)
  109.  {
  110.      
  111.      sharebuf[0]=count[1];
  112.      sharebuf[1]=count[0];
  113.      AT24C02_write(0x00,sharebuf,2);
  114.      AT24C02_read(0x00,sharebuf,2);
  115.        temp=sharebuf[0];
  116.      LCD_write_string(0x00,LINE1,"AT24C02 TEST");
  117.      LCD_write_char(0x0e,LINE1,(temp/10)|0x30);
  118.      LCD_write_char(0x0f,LINE1,(temp%10)|0x30);
  119.      LCD_write_string(0x00,LINE2,"TIMER0 JISHU");
  120.      LCD_write_char(0x0e,1,(count[1]/10)|0x30);
  121.      LCD_write_char(0x0f,1,(count[1]%10)|0x30);
  122.   }*/
  123. }
  124. /***********************************************************************/
  125. void timer0(void) interrupt 1 using 1
  126. {
  127.  TH0=-(12000/256);
  128.  TL0=-(12000%256);
  129.  count[0]=count[0]+1;
  130.  if(count[0]==100)
  131.     {
  132.      count[0]=0;
  133.      count[1]=count[1]+1;
  134.      if(count[1]==99)
  135.      count[1]=0;
  136.  }
  137.  //12ms中断1次

  138. }
  139. /***********************************************************************/
  140. void Mcu_init(void)
  141. {
  142.  TMOD=0x01;
  143.  TH0=-(12000/256);
  144.  TL0=-(12000%256);
  145.  EA=HIGH; //启用所有中断功能

  146.  ET0=HIGH; //启用TF0中断功能;

  147.  //以上两句相当于 IE= 0x82;

  148.  TR0=HIGH; //启动定时器0;

  149.  LCD_init();
  150. }
  151. /***********************************************************************/
  152. /******************************** I2C PART **************************/
  153. void I2C_start(void)
  154. {
  155.  SCL=1; Wait2us;
  156.  SDA=1; Wait2us;
  157.  SDA=0; Wait2us;
  158.  SCL=0; Wait2us;
  159. }
  160. /***********************************************************************/
  161. void I2C_stop(void)
  162. {
  163.   SDA=0;Wait2us;
  164.   SCL=1;Wait2us;
  165.   SDA=1;Wait2us;
  166.   SCL=0;Wait2us;
  167. }
  168. /***********************************************************************/
  169. void I2C_send_ack(bit sig)
  170. {
  171.  SDA=0;Wait2us
  172.  SCL=1;Wait2us
  173.  SCL=0;Wait2us
  174.  SDA=1;
  175. }
  176. /*************************************************************************/
  177. void I2C_send_noack(void)
  178. {
  179.  SDA=1;Wait2us
  180.  SCL=1;Wait2us
  181.  SCL=0;
  182. }
  183. /*****************************************************************************/
  184. void I2C_send_ackold(bit sig)
  185. {
  186.     SDA=sig;
  187.     SCL=0;Wait2us;
  188.     SCL=1;Wait2us;
  189.     SCL=0;Wait2us;
  190. }
  191. void I2C_TestACK(void){
  192.   Wait10us;
  193.   
  194. }
  195. /***********************************************************************/
  196. bit I2C_write_byte(unsigned char input)
  197. {
  198.  bit ack;
  199.  unsigned char temp;
  200.  for(temp=0;temp<8;temp++)
  201.   {
  202.   SDA=0;
  203.   if ((input<<temp)&0x80){SDA=1;}
  204.   SCL=1;Wait2us;
  205.   SCL=0;
  206.   }
  207.   SDA=1;Wait2us;//释放数据线,准备接收应答信号

  208.   ack=SDA;
  209.   SCL=1;Wait2us;
  210.   SCL=0;
  211.   return ack;
  212.   }
  213. /***********************************************************************/
  214. unsigned char I2C_read_byte(void)
  215. {
  216.   unsigned char temp,rbyte=0;
  217.   SDA=1;
  218.  for(temp=0;temp<8;temp++)
  219.   {
  220.      SCL=0;Wait2us
  221.      SCL=1;
  222.      rbyte<<=1;
  223.      if (SDA==1){rbyte+=1;}
  224.   }
  225.  SCL=0;
  226.  return(rbyte);
  227. }
  228. /************************************************************************/
  229. void AT24C02_write(unsigned char address,unsigned char *buf,unsigned char Nbyte)
  230. {

  231.     I2C_start();
  232.     I2C_write_byte(WRITE24C02);
  233.     I2C_TestACK();
  234.     I2C_write_byte(address);
  235.     I2C_TestACK();
  236.     for(;Nbyte!=0;Nbyte--)
  237.     {
  238.       I2C_write_byte(*buf);
  239.       I2C_TestACK();
  240.       buf++;
  241.     }
  242.     I2C_TestACK();
  243.     I2C_stop();
  244.     delay_ms(10);//这个很重要,调了几天问题就是出在h里的,最好在每个函数之间加延时

  245. }
  246. /************************************************************************/
  247. void AT24C02_read(unsigned char address,unsigned char *buf,unsigned char Nbyte)
  248. {

  249.      I2C_start();
  250.      I2C_write_byte(WRITE24C02);
  251.      I2C_TestACK();
  252.      I2C_write_byte(address);
  253.      I2C_TestACK();
  254.   
  255.      I2C_start();
  256.      I2C_write_byte(READ24C02);
  257.      I2C_TestACK();
  258.      while(Nbyte!=1)
  259.       {
  260.         *buf=I2C_read_byte();
  261.         I2C_send_ack(0);
  262.         buf++;
  263.         Nbyte--;
  264.       }
  265.     *buf=I2C_read_byte();
  266.     I2C_send_noack();
  267.     I2C_stop();
  268. }
  269. /**************LCD1602的初始化***************************/
  270. void LCD_init(void)
  271. {
  272.  LCD_send_command(LCD_DISPLAY_DOUBLE_LINE);
  273.  LCD_send_command(LCD_AC_AUTO_INCREMENT|LCD_MOVE_DISENABLE);
  274.  LCD_send_command(LCD_DISPLAY_ON|LCD_CURSOR_OFF);
  275.  LCD_send_command(LCD_CLEAR_SCREEN);
  276. }
  277. /***********************检测LCD状态*********************************/

  278. void LCD_check_busy(void)
  279. {
  280.  do
  281.   {
  282.    LCD_EN=0;
  283.    LCD_RS=0;
  284.    LCD_RW=1;
  285.    LCDIO=0xff;
  286.    LCD_EN=1;
  287.    }
  288.    while(LCD_BUSY==1);
  289.   
  290.     LCD_EN=0;
  291. }
  292. /************LCD1602写命令*******************************/
  293. void LCD_send_command(uchar command)
  294. {
  295.  LCD_check_busy();
  296.  LCD_RS=LOW;
  297.  LCD_RW=LOW;
  298.  LCD_EN=HIGH;
  299.  LCDIO=command;
  300.  LCD_EN=LOW;
  301. }
  302. /********************************************************/
  303. /*****************LCD1602写数据**************************/
  304. void LCD_send_data(uchar dat)
  305. {
  306.  LCD_check_busy();
  307.  LCD_RS=HIGH;
  308.  LCD_RW=LOW;
  309.  LCD_EN=HIGH;
  310.  LCDIO=dat;
  311.  LCD_EN=LOW;
  312. }
  313. /***********************LCD1602显示字符*********************************/
  314. void LCD_write_char(uchar x,uchar y,uchar dat)
  315. {
  316.      unsigned char address;
  317.      if (y == LINE1)
  318.          address = LINE1_HEAD + x;
  319.      else
  320.         address = LINE2_HEAD + x;
  321.      LCD_send_command(address);
  322.     LCD_send_data(dat);
  323. }
  324. /******************LCD1602显示字符串*********************/
  325. void LCD_write_string(uchar x,uchar y,uchar *Data)
  326. {
  327.  if(y==LINE1)
  328.  {
  329.   if(x<LINE_LENGTH)
  330.   {
  331.    LCD_send_command(LINE1_HEAD+x);
  332.    for(;x<LINE_LENGTH&&(*Data!='\0');x++)
  333.    {
  334.     LCD_send_data(*(Data++));
  335.    }
  336.    if(*Data!='\0')
  337.    {
  338.     x=0;
  339.     y=LINE2;
  340.    }
  341.   }
  342.  }
  343.  if(y==LINE2)
  344.  {
  345.   LCD_send_command(LINE2_HEAD+x);
  346.   for(;x<LINE_LENGTH&&*Data!='\0';x++)
  347.   {
  348.    LCD_send_data(*(Data++));
  349.   }
  350.  }
  351. }
  352. /****************************************************************/
  353. /********************延时函数***********************************/
  354.   
  355. /***************************************************************/
  356. void delay_ms(uint n)
  357. {
  358.  uint i,j;
  359.  for(i=n;i>0;i--)
  360.     for(j=0;j<1140;j++)
  361.     ;
  362. }
  363. /*********************************************************************/
不插连接图了,看的懂的看程序就知道线是怎么连的。
阅读(8481) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~