导航: 老古网老古论坛XMOS公共讨论区XMOS开源项目区单片机程序设计嵌入式系统广告区域
→24C01读写问题[求助]

* 54440: 24C01读写问题[求助]

   koji 
koji发表的帖子 

 24C01读写问题[求助]
//-----------------------函数声明,变量定义--------------------------------------------------------
#include   <reg51.h>  
#include   <intrins.h>  
sbit SDA=P1^0;                          // 将p1.0口模拟数据口
sbit SCL=P1^1;                          // 将p1.1口模拟时钟口
#define  NUM  8                      // 接收和发送缓存区的深度
#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};                  
unsigned char idata sendbuf[NUM];       // 数据发送缓冲区
unsigned char idata receivebuf[NUM];    // 数据接收缓冲区
bit   bdata SystemError;                // 从机错误标志位
//--------------------------------------------------------------------------------------------------
// 函数名称: iic_start()
// 函数功能: 启动I2C总线子程序
//--------------------------------------------------------------------------------------------------
void iic_start(void)
{  EA=0;            //时钟保持高,数据线从高到低一次跳变,I2C通信开始
 SDA = 1;         
 SCL = 1;
 delayNOP();      // 延时5us 
 SDA = 0;
 delayNOP();
 SCL = 0;
}
//--------------------------------------------------------------------------------------------------
// 函数名称: iic_stop()
// 函数功能: 停止I2C总线数据传送子程序
//--------------------------------------------------------------------------------------------------
void iic_stop(void)

 SDA = 0;       //时钟保持高,数据线从低到高一次跳变,I2C通信停止
 SCL = 1;
 delayNOP();
 SDA = 1;
 delayNOP();
 SCL = 0;
}
//--------------------------------------------------------------------------------------------------
// 函数名称: slave_ACK
// 函数功能: 从机发送应答位子程序
//--------------------------------------------------------------------------------------------------
void slave_ACK(void)
{
 SDA = 0;    
 SCL = 1;
 delayNOP();   
 SDA = 1;
 SCL = 0;
}
//--------------------------------------------------------------------------------------------------
// 函数名称: slave_NOACK
// 函数功能: 从机发送非应答位子程序,迫使数据传输过程结束
//--------------------------------------------------------------------------------------------------
void slave_NOACK(void)

 SDA = 1;   
 SCL = 1;
 delayNOP();
 SDA = 0;
 SCL = 0;
}
//--------------------------------------------------------------------------------------------------
// 函数名称: check_ACK
// 函数功能: 主机应答位检查子程序,迫使数据传输过程结束
//--------------------------------------------------------------------------------------------------
void check_ACK(void)

 SDA = 1;      // 将p1.0设置成输入,必须先向端口写1
 SCL = 1;
 F0 = 0;
 if(SDA == 1)    // 若SDA=1表明非应答,置位非应答标志F0
  F0 = 1;
 SCL = 0;
}

//--------------------------------------------------------------------------------------------------
// 函数名称: IICSendByte
// 入口参数: ch
// 函数功能: 发送一个字节
//--------------------------------------------------------------------------------------------------
void IICSendByte(unsigned char ch)

 unsigned char idata n=8;     // 向SDA上发送一位数据字节,共八位
 while(n--)
 { 
  if((ch&0x80) == 0x80)    // 若要发送的数据最高位为1则发送位1
  {
   SDA = 1;    // 传送位1
   SCL = 1;
   delayNOP();
   SDA = 0;
   SCL = 0;    
  }
  else
  {  
   SDA = 0;    // 否则传送位0
   SCL = 1;
   delayNOP();
   SCL = 0;  
  }
  ch = ch  <  <1;    // 数据左移一位
 }
}
//--------------------------------------------------------------------------------------------------
// 函数名称: IICreceiveByte
// 返回接收的数据
// 函数功能: 接收一字节子程序
//--------------------------------------------------------------------------------------------------
unsigned char IICreceiveByte(void)
{
 unsigned char idata n=8;    // 从SDA线上读取一上数据字节,共八位
 unsigned char tdata;
 while(n--)
 {
  SDA = 1;
  SCL = 1;
  tdata = tdata  <  <1;    // 左移一位,或_crol_(temp,1)
  if(SDA == 1)
   tdata = tdata|0x01;    // 若接收到的位为1,则数据的最后一位置1
  else 
   tdata = tdata&0xfe;    // 否则数据的最后一位置0
  SCL=0;
 }
 return(tdata);
}
//--------------------------------------------------------------------------------------------------
// 函数名称: writeNbyte
// 入口参数: slave_add从机地址,n要发送的数据个数
// 函数功能: 发送n位数据子程序
//--------------------------------------------------------------------------------------------------
void writeNbyte(unsigned char add, unsigned char n)
{          
 unsigned char idata send_da,i=0;
 iic_start();                // 启动I2C

 IICSendByte(0x00);     // 发送写命令
 check_ACK();                // 检查应答位
    if(F0 == 1)
 { 
  SystemError = 1;
  return;    // 若非应答表明器件错误或已坏,置错误标志位SystemError
 }

 IICSendByte(add);     // 发送地址位
 check_ACK();                // 检查应答位
    if(F0 == 1)
 { 
  SystemError = 1;
  return;    // 若非应答表明器件错误或已坏,置错误标志位SystemError
 }
 while(n--)
 { 
  send_da = sendbuf[i++];  
  IICSendByte(send_da);
  check_ACK();    // 检查应答位
  if (F0 == 1)
  {
   SystemError=1;
   return;    // 若非应答表明器件错误或已坏,置错误标志位SystemError
  }
 }
 iic_stop();         // 全部发完则停止
}
//--------------------------------------------------------------------------------------------------
// 函数名称: receiveNbyte
// 入口参数: slave_add从机地址,n要接收的数据个数
// 函数功能: 接收n位数据子程序
//--------------------------------------------------------------------------------------------------
void receiveNbyte(unsigned char idata add, unsigned char n)

 unsigned char idata receive_da,i=0;
 iic_start();
 IICSendByte(0xa0);  //发送写命令
 check_ACK();
 if(F0 == 1)
 {
  SystemError = 1;
  return;
 }

 IICSendByte(add);  //发送地址
 check_ACK();
 if(F0 == 1)
 {
  SystemError = 1;
  return;
 }

 iic_start();   //再次发送开始命令
 IICSendByte(0xa1);  //发送读命令
 check_ACK();
 if(F0 == 1)
 {
  SystemError = 1;
  return;
 }

 while(n--)
 { 
  receive_da=IICreceiveByte();
  receivebuf[i++]=receive_da;
  slave_ACK();    // 收到一个字节后发送一个应答位
 }
 slave_NOACK();    // 收到最后一个字节后发送一个非应答位
 iic_stop();
}

/*简化的主函数*/
void main()
{
 for(i=0; i  <NUM; i++)
  sendbuf[i] = i+0xAA;

 writeNbyte(0x00, sendbuf, NUM);  //写数据
 delay10ms(); //延时10ms,函数原型略
 receiveNbyte(0x00, NUM);  //读数据
 P0 = receibuf[NUM-1]; //把数组中最后一个数送到P0口上,用LED指示出来
 while(1);
}

以上程序是将一个有8个数据的数组用页方式写入24C01,然后读出来,一直调试没成功。但如果将#define  NUM  8 改为#define  NUM  1,则P0端口的LED显示正确。如果是#define  NUM  8 则一直调试没成功。请大家帮忙看看程序什么地方不对!谢谢!



发表时间:2009年3月2日22:29:47

  
回复该帖

本主题共有 1 帖,分页:>>>>>该主题的所有内容[1]条

 *树形目录 只列出部分跟帖的标题以及简单的摘要信息 该主题的部分跟帖如下:

[上一篇帖子]:代理松翰单片机8BIT MCU深圳市瑞丰汇科技有限公司代理松翰单片机8BIT M
[下一篇帖子]:谁有EM1812B资料这里谁有EM1812B资料可不可以给一份啊。谢谢