原创 【原创】I2C总线与24C02存储器的测试源代码程序(一)

2012-9-6 00:43 4451 25 26 分类: MCU/ 嵌入式

    I2C、24C02的读写,这是个老掉牙了的问题,还有必要浪费时间来讨论吗?事情是这样,笔者在移植一个已经过验证、正确的24C32程序到《HDQ-51E》单片机学习板上、读写板上的24C02时,发现读写的过程总是很不稳定,一时无法判断是程序代码问题,还是电路故障问题,还是24C02芯片问题。经过了2天时间,最终确定是24C02芯片质量问题。更换了进口的ATMEL 24C02后,读写正常了。在此过程中,笔者编写了一些测试24C02的程序,发现这些代码也许适合单片机初学者用来学习I2C总线原理,并用来读写24C02存储器,因为这些代码更简单易用。

    大家已经见过了很多有关I2C、24C02的单片机程序,为了实现对24C02的读写,一般都需要7、8个函数,甚至更多。其实,只需要4个函数(加上一个延时函数),就能很容易地实现I2C读写,见下:

sbit SDA = P2^6;     //管脚定义
sbit SCL = P2^7;


//SCL时钟的频率对于正确操作E2很重要;一般地,频率要求<100KHz。
void i2c_dly(void)
{
 DelayNms(1);     //ok
}

//IIC最基本的操作可以归结为下面4个函数:启始、停止、写、读

//IIC start
void i2c_start(void)
{
  SDA = 1;             // i2c start bit sequence
  i2c_dly();
  SCL = 1;
  i2c_dly();
  SDA = 0;
  i2c_dly();
  SCL = 0;
  i2c_dly();
}

//IIC stop
void i2c_stop(void)
{
  SDA = 0;             // i2c stop bit sequence
  i2c_dly();
  SCL = 1;
  i2c_dly();
  SDA = 1;
  i2c_dly();
}

//IIC read
//ack: 主机发送ACK位
unsigned char i2c_rx(char ack)
{
  char x, d=0;
 
  SDA = 1;
  for(x=0; x<8; x++) //读8个bit,高bit在前
 {
    d <<= 1;     //存储中间结果
    do
  {
      SCL = 1;
    }
    while(SCL==0);    //如果SCL被IIC设备拉低,则等待
   
  i2c_dly();
    if(SDA) d |= 1;  //读取数据线
    SCL = 0;
  }
 
 //发送ACK/NACK
  if(ack) SDA = 1;
  else SDA = 0;
 
  SCL = 1;
  i2c_dly();             // send (N)ACK bit
  SCL = 0;
  SDA = 1;
  return d;
}

//IIC write
//d: 待发送字节,高位先发送
//返回:0 -- ACK, 1 -- NACK
bit i2c_tx(unsigned char d)
{
  char x;
  static bit b;
 
 for(x=8; x; x--) //发送8个bit
 {
    if(d&0x80) SDA = 1;
    else SDA = 0;
    i2c_dly();
   
  SCL = 1;
    i2c_dly();
    d <<= 1;
    SCL = 0;
    i2c_dly();
  }
 
  SDA = 1;
  SCL = 1;
  i2c_dly();
  b = SDA;          //读取ACK bit
  SCL = 0;
  i2c_dly();

  return b;
}

    这4个函数完成最基本的I2C时序:起始、停止、写8bit、读8bit。通过对这4个函数合理组合,即可实现24C02的单字节读写,见附件例程。这是一个测试24C02是否有正确的ACK响应的程序,例子中的24C02设备地址为A0。

    24C02读写时序图:

at24c02_timing.jpg

 

《HDQ-51E》51学习板:http://item.taobao.com/item.htm?spm=a1z10.1.11.5&id=15769166730


欢迎加入单片机技术讨论QQ群:231033072,互相帮助、共同提高。

(待续)

(本文最初发表于ENDCHINA,转载请注明出处,谢谢!)

 

 

 

 

文章评论1条评论)

登录后参与讨论

用户1508872 2014-3-7 23:19

不错。第二部分在哪里啊。

用户913991 2012-6-25 14:37

谢谢,也祝您工作顺利,阖家欢乐!

用户403664 2012-6-25 08:51

编辑一下参加博客大赛啦!好好学习,天天向上!
相关推荐阅读
用户424443 2016-03-18 13:44
Android安卓开发环境的建立--写给初学者
几个基本概念: (一)安卓的开发主机,可以是win、linux、mac os其一;常用的是windows,比如win7. (二)开发安卓手机APP使用的编程语言是JAVA,IDE常用的是E...
用户424443 2015-01-15 17:57
安卓模拟器Genymotion虚拟设备启动失败问题的解决方法
几个基本概念: 1、Genymotion是安卓开发环境的一种模拟器,加载APP的速度比较快(模拟器本身启动也是需要相当长时间)。 2、Genymotion依赖于VirtualBox(著名的...
用户424443 2014-12-15 17:18
JLINK的SW调试模式连线方式
大家知道,JLINK有2种调试模式:JTAG和SWD(串行模式)。     JTAG是常用模式,大家都熟悉、不废话了;如果使用SW模式,需要(只需要)4根连线,连接...
用户424443 2014-02-25 11:35
给单片机初学者的忠告
现在是2014年了,回想整整20年前的1994,那时我应该坐在北京一个高校的教室里听老先生讲51单片机的课程。岁月荏苒,时过境迁,科技发展的潮流不可阻挡,技术的发展更是一日千里:“单片机”成了“嵌...
用户424443 2014-01-14 10:07
STM32休眠模式的调试方法
STM32有3种休眠模式,其中,STOP模式一旦启动后,芯片进入休眠模式,HSE等振荡器不再有效工作,JTAG调试失效。如果在STOP模式下,希望仍能使用JTAG进行正常调试,如何实现?比如,进入...
用户424443 2013-01-14 15:10
关于STM32的中断优先级设置--systick
项目中需要将systick中断的优先级调低,遇到的问题总结如下: 1. STM32中断优先级是使用4-bit来表示的,即总共有16个级别。 2. 优先级分为2个部分:抢先优先级和子优先级,...
我要评论
1
25
关闭 站长推荐上一条 /2 下一条