C51 I2C传输问题

[复制链接]
2548|1
 楼主| yuchongjike 发表于 2010-5-14 10:36 | 显示全部楼层 |阅读模式
I2c, C51, AD, TE, TI
我用89C51访问24C02无反应.
24C02时钟接P1.7,数据接P1.6,A0 A1 A2接地

执行函数:I2C_Write(0xA0,0x01,0);I2C_Read(0xA1,0x01,&c);都直接返回0
我是用Proteus仿真的.89C51时钟为24MHz

执行写入命令:
Write(0xA0,0x00,'T');
Write(0xA0,0x01,'E');
Write(0xA0,0x02,'S');
Write(0xA0,0x03,'T');
Write(0xA0,0x10,'O');
Write(0xA0,0x11,'K');
用Proteus的I2C窗口查看:
S A0 N 00 N 54 N P
S A0 N 01 N 45 N P
S A0 N 02 N 53 N P
S A0 N 03 N 54 N P
S A0 N 10 N 4F N P  
S A0 N 11 N 4B N P
查看I2C的内容均为FF.

这里的N说的是没有应答?????24C02没应答????

24C02.H

  1. #ifndef __24C02_H__
  2. #define __24C02_H__

  3. #ifndef uchar
  4. #define uchar unsigned char
  5. #endif
  6. #ifndef uint
  7. #define uint unsigned int
  8. #endif
  9. #ifndef ulong
  10. #define ulong unsigned long
  11. #endif

  12. #define I2C_TIMEOUT    255
  13. #define CTRL_BASE_ADDR_I2C 0x90
  14. #define I2C_CLK_PIN    7
  15. #define I2C_DATA_PIN 6

  16. //Extern Function
  17. bit I2C_Read(uint I2C_Addr,uint Byte_Addr,uchar *c);
  18. bit I2C_Write(uint I2C_Addr,uint Byte_Addr,uchar dat);

  19. //Internal Function
  20. void I2CSend(uchar dat);
  21. uchar I2CRecv();
  22. void I2C_Start();
  23. void I2C_Stop();
  24. void I2C_ACK();
  25. void I2C_NOACK();
  26. bit  I2C_CHK_ACK();
  27.      
  28. #endif



24C02.C

  1. #include "24C02.H"
  2. #include "Process.h"
  3. #include <intrins.h>

  4. #define Nop4();    {_nop_();_nop_();_nop_();_nop_();}

  5. sbit SCLK_I2C = CTRL_BASE_ADDR_I2C^I2C_CLK_PIN;
  6. sbit SDATA_I2C = CTRL_BASE_ADDR_I2C^I2C_DATA_PIN;
  7. bit  I2CACK;

  8. void I2C_Start()
  9. {
  10.     SCLK_I2C = 0;
  11.     SDATA_I2C = 1;
  12.     _nop_();
  13.     SCLK_I2C = 1;
  14.     Nop4();
  15.     SDATA_I2C = 0;
  16.     Nop4();
  17.     SCLK_I2C = 0;
  18.     _nop_();   
  19. }

  20. void I2C_Stop()
  21. {
  22.     SCLK_I2C = 0;
  23.     SDATA_I2C = 0;
  24.     _nop_();
  25.     SCLK_I2C = 1;
  26.     Nop4();
  27.     SDATA_I2C = 1;
  28.     Nop4();
  29. }

  30. void I2C_ACK()
  31. {
  32.     SDATA_I2C = 0;
  33.     Nop4();
  34.     SCLK_I2C = 1;
  35.     Nop4();
  36.     SCLK_I2C = 0;
  37.     _nop_();
  38.     _nop_();
  39. }

  40. void I2C_NOACK()
  41. {
  42.     SDATA_I2C = 1;
  43.     Nop4();
  44.     SCLK_I2C = 1;
  45.     Nop4();
  46.     SCLK_I2C = 0;
  47.     _nop_();
  48.     _nop_();
  49. }

  50. bit I2C_Read(uint I2C_Addr,uint Byte_Addr,uchar *c)
  51. {
  52.     I2C_Start();

  53.     I2CSend(I2C_Addr & 0xFE);
  54.     if(!I2CACK) return 0;
  55.     I2CSend(Byte_Addr);
  56.     if(!I2CACK) return 0;

  57.     I2C_Start();
  58.     I2CSend(I2C_Addr | 0x01);
  59.    
  60.     *c = I2CRecv();
  61.     I2C_NOACK();
  62.    
  63.     I2C_Stop();
  64. }

  65. bit I2C_Write(uint I2C_Addr,uint Byte_Addr,uchar dat)
  66. {
  67.     I2C_Start();

  68.     I2CSend(I2C_Addr & 0xFE);
  69.     if(!I2CACK) return 0;

  70.     I2CSend(Byte_Addr);
  71.     if(!I2CACK) return 0;

  72.     I2CSend(dat);
  73.     if(!I2CACK) return 0;

  74.     I2C_Stop();
  75.     return 1;
  76. }

  77. bit  I2C_CHK_ACK()
  78. {
  79.     bit bStatus = 1;
  80.     ulong iTimeout = I2C_TIMEOUT;

  81.     SCLK_I2C = 0;
  82.     SDATA_I2C = 1;
  83.     Nop4();
  84.     SCLK_I2C = 1;
  85.     Nop4();
  86.     while(SDATA_I2C)
  87.     {
  88.         iTimeout--;
  89.         if(!iTimeout)
  90.         {
  91.              I2C_Stop();
  92.             bStatus = 0;
  93.             return bStatus;
  94.         }   
  95.     }
  96.     SCLK_I2C = 0;
  97.     _nop_();
  98.     return bStatus;
  99. }

  100. void I2CSend(uchar dat)
  101. {
  102.     uchar i=8;
  103.     while(i--)
  104.     {
  105.         SDATA_I2C = (bit)(dat & (0x01<<(i-1)));
  106.         _nop_();
  107.         _nop_();
  108.         SCLK_I2C = 1;
  109.         Nop4();
  110.         SCLK_I2C = 0;
  111.     }
  112.     _nop_();
  113.     _nop_();
  114.     I2CACK = I2C_CHK_ACK();
  115.     _nop_();
  116. }

  117. uchar I2CRecv()
  118. {
  119.     uchar temp = 0x00;
  120.     uchar i = 8;

  121.     SCLK_I2C = 0;
  122.     SDATA_I2C = 1;
  123.     while(i--)
  124.     {
  125.         SCLK_I2C = 0;
  126.         Nop4();
  127.         SCLK_I2C = 1;
  128.         _nop_();
  129.         _nop_();
  130.         temp |= ((uchar)(SDATA_I2C )<< (i-1));
  131.         _nop_();
  132.         _nop_();                 
  133.     }
  134.    
  135.     return temp;
  136. }


yuyetufu 发表于 2010-5-15 15:53 | 显示全部楼层
个人觉得晶振太快,24时序 延时就不够了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

11

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部