原创 关于24C02与IIC

2013-7-31 01:30 1897 23 24 分类: MCU/ 嵌入式 文集: 信号与系统

      今天学习了用51单片机对24C02的操作。资料是在同学那里找的,有关于24C02的介绍,也有C代码。原理和介绍以前也看过。看时序图的时候始终觉得很麻烦,不知具体的代码该怎么写,可以看了别人写的代码又觉得这么简单就实现了想要的功能。可以还是对原理理解得不够深入,有些代码不太懂,但大概思路没问题。

      首先,24C02是IIC的方式进行通信的,所以先来看看IIC。IIC通信,涉及到的主要操作有:启动总线、停止总线、应答、非应答、写字节、读字节。下面是关于这些操作的代码.

#include
#include "intrins.h"
#include "iic.h"

void delay(void)
{
 _nop_(); _nop_(); _nop_();
 _nop_(); _nop_(); _nop_();
 _nop_(); _nop_(); _nop_();
}

/**************************************
Function:   void iic_start(void)
Description: 启动iic总线
Calls:   无
Input:   无
Output;   无
Return:   无
Others:   涉及到总线地址 scl & sda
****************************************/
void iic_start(void) //iic总线启动

 scl = 1;
 delay();
 sda = 1;
 delay();
 sda = 0;
 delay();
}

/**************************************
Function:   void iic_stop(void)
Description: 停止iic总线
Calls:   无
Input:   无
Output;   无
Return:   无
Others:   涉及到总线地址 scl & sda
****************************************/
void iic_stop(void)  //iic总线停止
{
 sda = 0;
 delay();
 scl = 1;
 delay();
 sda = 1;
 delay();
}

/***************************************
Function:   void iic_ack(void)
Description: 应答信号
Calls:   无
Input:   无
Output;   无
Return:   无
Others:   
****************************************/
void iic_ack(void)  //iic总线应答
{
 uint i;
 scl = 1;
 delay();
 while((sda==1)&&(i<200))
 {
  i++;
 }
 scl = 0;
 delay();  
}
/**************************************
Function:   void iic_noack(void)
Description: 无应答信号
Calls:   无
Input:   无
Output;   无
Return:   无
Others:   
***************************************/
void iic_noack(void) //iic总线非应答
{
 sda = 1;
 delay();
 scl = 1;
 delay();
 scl = 0;
 delay();
}
/***************************************
Function:   void iicwr_byte(void)
Description: iic总线写一位(8bit)数据
Calls:   void delay(void)
Input:   dat
Output;   无
Return:   无
Others:   涉及到总线地址 scl & sda
*****************************************/
void iicwr_byte(uchar dat)
{       //iic总线写一位(8bit)数据
 uchar i;
 scl = 0;
 for(i=0;i<8;i++)
 {
  if(dat&0x80)
  {
   sda = 1;  
  }
  else
  {
   sda = 0;
  }
  dat=dat<<1;
  delay();
  scl = 1;
  delay();
  scl = 0;
  delay(); 
 }
 sda = 1;
 delay(); 
}
/***************************************
Function:   void iicre_byte(void)
Description: iic总线写一位(8bit)数据
Calls:   void delay(void)
Input:   无
Output;   无
Return:   dat
Others:   涉及到总线地址 scl & sda
*****************************************/
uchar iicre_byte()  //iic总线读一位(8bit)数据   
{
 uchar i;
 uchar dat;
 scl = 0;
 delay();
 sda = 1;
 delay();
 for(i=0;i<8;i++)
 {
  scl = 1;
  delay();
  dat=dat<<1;
  if(sda)  dat++;
  scl = 0;
  delay();
 }
 sda = 1; 
 return dat;   //数据返回
}

在读以上代码时,有这样一些问题:1、while((sda==1)&&(i<200))
 {
  i++;
 }这句不太懂。2、非应答信号有什么用? 

 

 

然后是24C02操作的一些代码:

#include
#include "iic.h"
#include "24c02.h"

/**************************************
Function:   void write_byte(uchar add,uchar dat)
Description: 在24c02某一地址写一位数据
Calls:   iic_star(),iic_ack(),iicwr_byte(),iic_stop()
Input:   add,dat
Output;   无
Return:   无
Others:   
****************************************/
void write_byte(uchar add,uchar dat)
{
 scl = 1;     //初始化iic总线
 sda = 1;
 iic_start();
 iicwr_byte(0xa0);
 iic_ack();
 iicwr_byte(add);  //写地址上
 iic_ack();
 iicwr_byte(dat);  //要写的数据
 iic_ack();
 iic_stop();
}

/**************************************
Function:   write_page(uchar *buff,uchar n,uchar add)
Description: 在24c02某一地址开始,连续写一数组
Calls:   iic_star(),iic_ack(),iicwr_byte(),iic_stop()
Input:   *buff(数组名),n(要写数组的个数),add(开始写的地址)
Output;   无
Return:   无
Others:   采用指针进行数组的读操作
****************************************/
void write_page(uchar *buff,uchar n,uchar add)


 uint i;    
 iic_start();
 iicwr_byte(0xa0);
 iic_ack();
 iicwr_byte(add);
 iic_ack();
 for(i=0;i  {
  iicwr_byte(buff);  //要写的数据
  iic_ack(); 
 }
    iic_stop();
};i++)

 /**************************************
Function:   uchar read_byte(uchar add)
Description: 从24c02中任一地址读取一位数据(随机读)
Calls:   iic_star(),iic_ack(),iicwr_byte(),iicre_byte(),iic_stop()
Input:   add(读数据的地址)
Output;   无
Return:   i
Others:   使用随机读的方式,可对芯片内任一地址直接读操作
****************************************/
uchar read_byte(uchar add)   //随机读
{
 uchar i;
 scl = 1;       //初始化iic总线
 sda = 1;
 iic_start();
 iicwr_byte(0xa0);
 iic_ack();
 iicwr_byte(add);
 iic_ack();
 iic_start();
 iicwr_byte(0xa1);
 iic_ack();
 i = iicre_byte();
 iic_noack();
 iic_stop();
 return i;
}

/**************************************
Function:   uchar read_page(uchar *buff,uchar n,uchar add)
Description: 从24c02中任一地址开始连续读操作
Calls:   iic_star(),iic_ack(),iicwr_byte(),iicre_byte(),iic_stop()
Input:   *buff(数组名),n(要读数组的个数),add(开始读的地址)
Output;   buff
Return:   无
Others:   此函数之前需要定义一个合适大小的数组,调用本函数后,将24c02中数据读进数组中
****************************************/
void read_page(uchar *buff,uchar n,uchar add)
{
 uint i;
 iic_start();
 iicwr_byte(0xa0);
 iic_ack();
 iicwr_byte(add);
 iic_ack();
 iic_start();
 iicwr_byte(0xa1);
 iic_ack();
 for(i=0;i  {
  buff = iicre_byte();
  if(i!=n-1)
  {
   iic_ack();   
  }
  else
  {
      iic_noack();
  }
 }
 iic_stop(); 
};i++)

 问题:iicwr_byte(0xa0);
             iicwr_byte(0xa1);这两句不太懂。

哎,写到这儿,突然感觉自己完全没懂。

 

 

 

 

 

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

gxj-123_620130386 2013-7-31 09:58

iicwr_byte(0xa0); 
为写指令, 
iicwr_byte(0xa1); 
为读指令, 

你要读某个指定地址add的值,需要先写入地址,然后从当前地址读出数据,下面给你注释一下最后一个函数的操作
void read_page(uchar *buff,uchar n,uchar add)
{
 uint i;
 iic_start();
 iicwr_byte(0xa0);  //发出写指令
 iic_ack();
 iicwr_byte(add);   //写入地址值add
 iic_ack();
 iic_start();
 iicwr_byte(0xa1);  //发出读指令
 iic_ack();
 for(i=0;i<n;i++)
 {
  buff[i] = iicre_byte();//从当前地址读出数据
//每读出一个数据,当前地址会自动加一,故不需要重新发送当前地址,下次直接读取,便是下个地址的数据
  if(i!=n-1)
  {
   iic_ack();   
  }
  else
  {
   iic_noack();
  }
 }
 iic_stop(); 
}
相关推荐阅读
用户436773 2015-01-04 11:52
经验总结:FPGA时序约束的6种方法
对自己的设计的实现方式越了解,对自己的设计的时序要求越了解,对目标器件的资源分布和结构越了解,对EDA工具执行约束的效果越了解,那么对设计的时序约束目标就会越清晰,相应地,设计的时序收敛过程就会更可控...
用户436773 2014-08-08 11:13
评论:@FPGA学习历程 博客中提到的“【原创】基于Nios II的VGA字符显示控制”
学习...
用户436773 2014-08-08 11:12
评论:@FPGA学习历程 博客中提到的“【原创】基于Verilog的VGA显示控制(有源码)”
最近在学VGA显示,借鉴下...
用户436773 2014-02-24 09:16
如何调试数字硬件设计
工程设计项目中最令人振奋的时刻之一就是第一次将硬件移到实验室准备开始集成测试的时候。开发过程中的这个阶段通常需要很长时间,也会对所有的项目工程师造成很大的压力。不过,现有的工具和方法能减轻压力,帮助推...
用户436773 2013-12-04 16:48
AccelDSP
  AccelDSP其实是一种综合工具,所以也叫AccelDSP综合工具。它可以将特定的Matlab程序进行浮点到定点的转换,生成定点的Matlab程序或者C++程序,并综合成HDL代码和t...
用户436773 2013-12-03 09:50
sigmoid函数基于LUT的FPGA实现
在神经网络中,经常以sigmoid函数作为激励函数。sigmoid函数的实现主要有以下几种方法:泰勒级数展开、分段多项式逼近、LUT(查找表)法、以及分段多项式与查找表结合。 其中,查找法实现...
EE直播间
更多
我要评论
1
23
关闭 站长推荐上一条 /3 下一条