I2C―― C程序

本文详细介绍了基于EasyARM2100平台的I2C通信程序设计,包括主模式和从模式的应用实例。通过对I2C中断处理程序的深入解析,展示了如何通过中断方式实现I2C的数据发送(ISendStr)和接收(IRcvStr)功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

I2C―― C程序
2012年01月09日
  一、 慨述:
  1) 这是EasyARM2100 examples 中的I2C―― C程序。
  I2CTEST.C 是I2C主模式工程应用文件;
  I2CINI.C 是基于具有硬件I2C的软件包(主模式);
  CSI24WC02.C 是I2C从模式工程应用文件。
  2) I2C的实现是基于中断方式,是有实用价值的,尤其是I2CINI.C 很精彩。
  3) I2CTEST.C 没能与I2CINI.C 的精彩相呼应,如,I2CINI.C 中对ISendStr(),
  IRcvStr()正常返回与失败退出,都有确定值,而I2CTEST.C 中都未考虑,而I2C通信的实际情况是不能不考虑――丢失仲裁、无应答等,否则,I2C通信不会成功。
  4)其实只需在I2CTEST.C 中的 main()稍稍一改(套红处为改动处),就能与I2C通信的实际情况相吻合,具体的改动详见其后三。
  二、EasyARM2100 examples 中的I2C ―― C程序原文:
  /************************************************* ***************************
  * 文件名:I2CINT.C
  * 功能:硬件I2C软件包,利用中断方式操作。
  * 说明:主程序要配置好I2C总线接口(GPIO、总线时钟)
  ************************************************** **************************/
  #include "config.h"
  /* 以下为I2C操作时所需要的变量,在调用I2C子程序前要设置好这些变量 */
  volatile uint8 I2C_sla; // 从机地址
  volatile uint8 I2C_suba; // 子地址
  volatile uint8 *I2C_buf; // 数据缓冲区指针 (读操作时会被更改)
  volatile uint8 I2C_num; // 操作数据个数 (会被更改)
  volatile uint8 I2C_end; // 操作结束标志,为1时表示操作结束,为0xFF时表示操作失败 (会被设置)
  volatile uint8 I2C_suba_en; // 子地址使能控制,读操作时请设置为1,写操作时请设置为2 (会被更改)
  /************************************************* ***************************
  * 名称:IRQ_I2C()
  * 功能:I2C中断,通过判断I2C状态字进行相应的操作。
  * 入口参数:无
  * 出口参数:无
  ************************************************** **************************/
  void __irq IRQ_I2C(void)
  { uint8 sta;
  sta = I2STAT; // 读出I2C状态字
  switch(sta)
  { case 0x08: // 己发送起始条件
  if(1==I2C_suba_en) I2DAT = I2C_sla&0xFE; // 指定子地址读时,先写入地址
  else I2DAT = I2C_sla; // 否则直接发送从机地址
  I2CONCLR = 0x28; // SI=0
  break;
  case 0x10:
  I2DAT = I2C_sla; // 重启动总线后,发送从地址
  I2CONCLR = 0x28; // SI=0
  break;
  case 0x18: // 已发送SLA+W,并已接收应答
  if(0==I2C_suba_en) // 无子地址,则直接发送数据
  { if(I2C_num>0)
  { I2DAT = *I2C_buf++;
  I2CONCLR = 0x28;
  I2C_num--;
  }
  else
  { I2CONSET = 0x10; // 无数据发送,结束总线
  I2CONCLR = 0x28;
  I2C_end = 1; // 设置总线操作结束标志
  }
  break; } if(1==I2C_suba_en) // 发送子地址
  { I2DAT = I2C_suba;
  I2CONCLR = 0x28;
  }
  if(2==I2C_suba_en)
  { I2DAT = I2C_suba;
  I2CONCLR = 0x28;
  I2C_suba_en = 0; // 子地址己处理
  }
  break;
  case 0x28: // 已发送I2C数据,并接收到应答
  if(0==I2C_suba_en) // 无子地址,则直接发送数据
  { if(I2C_num>0)
  { I2DAT = *I2C_buf++;
  I2CONCLR = 0x28;
  I2C_num--;
  }
  else
  { I2CONSET = 0x10; // 无数据发送,结束总线
  I2CONCLR = 0x28;
  I2C_end = 1;
  }
  break;
  }
  if(1==I2C_suba_en) // 若是指定地址读,则重新启动总线
  { I2CONSET = 0x20;
  I2CONCLR = 0x08;
  I2C_suba_en = 0; // 子地址己处理
  }
  break;
  case 0x20:
  case 0x30:
  case 0x38:
  I2CONCLR = 0x28; // 总线进入不可寻址从模式
  I2C_end = 0xFF; // 总线出错,设置标志
  break;
  case 0x40: // 己发送SLA+R,并已接收到应答
  if(1==I2C_num) // 最后一字节,接收数据后发送非应答信号
  { I2CONCLR = 0x2C; // AA=0,接收到数据后产生非应答
  }
  else // 接收数据并发送应答信号
  { I2CONSET = 0x04; // AA=1,接收到数据后产生应答
  I2CONCLR = 0x28;
  }
  break;
  case 0x50:
  *I2C_buf++ = I2DAT; // 读取数据
  I2C_num--;
  if(1==I2C_num)
  { I2CONCLR = 0x2C; // AA=0,接收到数据后产生非应答
  }
  else
  { I2CONSET = 0x04; // AA=1,接收到数据后产生应答
  I2CONCLR = 0x28;
  } break; case 0x58: *I2C_buf++ = I2DAT; // 读取最后一字节数据
  I2CONSET = 0x10; // 结束总线
  I2CONCLR = 0x28;
  I2C_end = 1;
  break;
  case 0x48:
  I2CONCLR = 0x28; // 总线进入不可寻址从模式
  I2C_end = 0xFF;
  break;
  default:
  break;
  }
  VICVectAddr = 0x00; // 中断处理结束
  }
  /************************************************* ***************************
  * 名称:ISendStr()
  * 功能:使用硬件I2C发送数据。
  * 入口参数:无
  * 出口参数:返回值为0时表示出错,为1时表示操作正确。
  * 说明:使用前设置好参数
  ************************************************** **************************/
  uint8 ISendStr(uint8 sla, uint8 suba, uint8 *s, uint8 no)
  { /* 参数设置 */
  I2C_sla = sla;
  I2C_suba = suba;
  I2C_buf = s;
  I2C_num = no;
  I2C_suba_en = 2;
  I2C_end = 0;
  I2CONCLR = 0x2C;
  I2CONSET = 0x60; // 设置为主机,并启动总线
  while(0==I2C_end);
  if(1==I2C_end) return(1);
  else return(0);
  }
  /************************************************* ***************************
  * 名称:IRcvStr()
  * 功能:使用硬件I2C读取数据。
  * 入口参数:无
  * 出口参数:返回值为0时表示出错,为1时表示操作正确。
  * 说明:使用前设置好参数
  ************************************************** **************************/
  uint8 IRcvStr(uint8 sla,uint8 suba,uint8 *s,uint8 no)
  { if(0==no) return(0);
  /* 参数设置 */
  I2C_sla = sla+1;
  I2C_suba = suba;
  I2C_buf = s;
  I2C_num = no; I2C_suba_en = 1; I2C_end = 0; I2CONCLR = 0x2C; I2CONSET = 0x60; // 设置为主机,并启动总线
  while(0==I2C_end);
  if(1==I2C_end) return(1);
  else return(0);
  }
  /************************************************* ***************************
  * 文件名:I2CTEST.C
  * 功能:使用硬件I2C对E2PROM进行操作,利用中断方式操作。
  * 说明:将跳线器JP4_LED1、JP9短接。
  ************************************************** **************************/
  #include "config.h"
  #define CSI24WC02 0xA0 /* 定义器件地址 */
  #define LED1CON (10; dly--)
  for(i=0; i
  
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值