码迷,mamicode.com
首页 > 其他好文 > 详细

I2c

时间:2015-09-22 20:27:50      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:

  在学习单片机的时候就听说过I2c,不过那时候听的一团糟,什么都不会,而且51上面没有集成真正的I2c,只能用IO口模拟它的时序来实现。I2c总线是一种用于Ic器件之间连接的双向二进制总线。所谓总线,就是它上面可以挂多个器件,并且通过两根线连接,占用空间非常小。  其中SDA是数据线,SCL是时钟线。

  I2c的几种信号状态:

  空闲状态:SCL 高      SDA  高

  开始条件: SCL    高                       SDA   高-->低

  结束条件: SCL    高                        SDA  低-->高

  数据有效: SCL    高                        SDA 稳定

  

  I2c最重要的是时序的掌握,这点和Nandflash有点像,就是要严格按照手册上面的时序图操作。

#include"stdio.h"
#define u8 unsigned char
//IO口的配置
#define GPD1CON (*(volatile unsigned long *)0xE02000C0)
#define GPD1PUD (*(volatile unsigned long *) 0xE02000C8)

#define IICCON (*(volatile unsigned long *)0xE1800000)
#define IICSTAT (*(volatile unsigned long *)0xE1800004)
#define IICDS (*(volatile unsigned long *)0xE180000C)
//i2c 的中断源控制器,VIC1 的14 号中断
#define VIC1INTENCLEAR (*(volatile unsigned long *)0xF2100014)

 

int init_i2c(void)
{
  //端口配置
  //GPD1PUD &= 0xfff0; //Pull-up/ down disabled
  //端口配置成i2c的SDA 和SCL
  GPD1CON &= 0xffffff00;
  GPD1CON |=0x22;

  //关闭i2c0 的中断源   读取的过程中会不断产生中断,只要关闭总的中断,就不会上报给CPU了
  VIC1INTENCLEAR |= (1<<14);

  // 产生应答 使能中断控制位
  IICCON = (1<<7) |(0<<6) |(1<<5) |0xf;
  //使能传输端口
  IICSTAT = (1<<4);
  return 0;
}

 

int write_i2c(u8 data, u8 addr) //地址和数据都是八位的
{
  int num;
  int i;

  //发送设备的地址 和写命令(最后一位是0)
  IICSTAT = 0xf0; //产生start 信号
  IICDS = 0xa0;
  //wait_i2c_finish();
  WaitOprFinish();


  //发送写的地址
  IICDS = addr;
  //for(i=0; i<20; i++);
  IICCON &= ~(1<<4);
  //wait_i2c_finish();
  WaitOprFinish();


  //发送数据
  IICDS = data;
  //for(i=0; i<20; i++);
  IICCON &= ~(1<<4);
  //wait_i2c_finish();
  WaitOprFinish();


  IICSTAT &= ~(1<<5); //产生stop 信号
  IICCON &= ~(1<<4);

  for(num=0; num<10000; num++); //加延时
  return 0;
}

 

int read_i2c(u8 addr,u8 *data)
{
  u8 buf =0;
  int num;

  IICDS =0xa0;//设备地址发送给移位寄存器
  IICSTAT =0xf0;//产生start信号 主发送模式
  //wait_i2c_finish();
  WaitOprFinish();
  IICDS =addr; //写的数据的地址
  IICCON =0xaf;
  //wait_i2c_finish();
  WaitOprFinish();
  IICDS = 0xa0; // 设备地址发送给移位寄存器
  IICSTAT = 0xb0; // 产生start信号, 主接收模式
  IICCON = 0xaf; // resume IIC Operation
  //wait_i2c_finish();
  WaitOprFinish();
  IICCON = 0x2f; //无应答
  //wait_i2c_finish();
  WaitOprFinish();
  buf = IICDS;

  IICSTAT = 0x90;//产生停止信号
  IICCON = 0xaf;

  for(num=0; num<10000; num++);

  *data=buf;
}

 

void WaitOprFinish(void)
{
  unsigned int uIICConReg = 0;
  unsigned int uRes = 0;

  do
  {
    uIICConReg = IICCON;
    //取出第四位,当传输结束时会产生中断信号1
    uRes = uIICConReg & 0x10;

  }while(uRes == 0); //祍却钡酱渫瓿?
  return ;
}

 

//最后是测试函数,先写后读
int test_i2c(void)
{
  int i;
  volatile int j;
  u8 buf = 0;
  int num;

  init_i2c();
  printf("write...:\r\n");

  for(i = 0; i<20; i++)
  {
    write_i2c(i*2, i);

    for(j = 0;j < 10000;j++);
  }

  for(num=0; num<10000; num++);

  printf("read.....:\r\n");

  for(i = 0; i<20; i++)
  {
    read_i2c(i,&buf);
    printf("%d\r\n", buf);
  }
}

I2c

标签:

原文地址:http://www.cnblogs.com/ygy1784717631/p/4830197.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!