LPC1768有三路IIC,其中IIC0支持高速模式和plus模式,另外两路是普通IIC,使用IIC的过程如下

首先依然是打开IIC时钟,同时打开GPIO时钟

然后配置引脚为IIC功能

另外,因为iic0支持plus结构,所以gpio控制的时候还有这个寄存器需要设置

接下来设置IIC的高低电平占空比

最后使能接口就可以使用了

初始化示例代码如下

void IIC0Init(u32 baud)

{

u32 t = (SystemCoreClock/4)/baud;

//打开IIC时钟

LPC_SC->PCONP |= (1 << 7);

LPC_SC->PCONP |= (1<<15);//gpio 时钟

//配置IIC引脚 sda

LPC_PINCON->PINSEL1 &= ~(0x03<<22);

LPC_PINCON->PINSEL1 |= (0x01<<22);

LPC_PINCON->PINMODE1 &= ~(0x03<<22);

LPC_PINCON->PINMODE1 |= (0x01<<22);

LPC_PINCON->PINMODE_OD0 |= 0x01<<27;

//scl

LPC_PINCON->PINSEL1 &= ~(0x03<<24);

LPC_PINCON->PINSEL1 |= (0x01<<24);

LPC_PINCON->PINMODE1 &= ~(0x03<<24);

LPC_PINCON->PINMODE1 |= (0x01<<24);

LPC_PINCON->PINMODE_OD0 |= 0x01<<28;

LPC_PINCON->I2CPADCFG = 0x0;

LPC_I2C0->I2SCLL = t/2;

LPC_I2C0->I2SCLH = t/2;

LPC_I2C0->I2CONSET = (1<<I2EN);//接口使能

}

LPC的IIC使用起来是依靠状态组合来判定传输状态的,而不是像其他单片机依靠标志位识别,

每次控制设备执行一个动作之后检测返回的状态位对不对,就可以判定传输是否成功,相应的传送代码如下

//等待指定的状态

//失败返回1 成功返回0

u8 WaitResponse(u8 response)

{

u8 retry = 200;

while(--retry)

{

DelayUs(1);

if(STATE == response)break;

}

if(retry)return 0;

else return 1;

}

u8 IIC0Start(void)

{

LPC_I2C0->I2CONCLR = (1<<SIC)|(1<<STAC)|(1<<AAC);

//Start

LPC_I2C0->I2CONSET = (1<<STA);

return WaitResponse(STATUS_SENDSTART);

}

u8 IIC0RepeatStart(void)

{

//repeat start

LPC_I2C0->I2CONCLR = (1<<SIC);

LPC_I2C0->I2CONSET = (1<<STA);

return WaitResponse(STATUS_REPEATSTART);

}

u8 IIC0SendWriteAddr(u8 addr)

{

//dev_addr

LPC_I2C0->I2DAT = addr;

LPC_I2C0->I2CONSET = (1<<AA);

LPC_I2C0->I2CONCLR = (1<<SIC)|(1<<STAC);

return WaitResponse(STATUS_SENDSLAVE_ACK);

}

u8 IIC0SendData(u8 data)

{

LPC_I2C0->I2DAT = data;

LPC_I2C0->I2CONSET = (1<<AA);

LPC_I2C0->I2CONCLR = (1<<SIC);

return WaitResponse(STATUS_SENDDATA_ACK);

}

u8 IIC0SendStop(void)

{

LPC_I2C0->I2CONCLR = (1<<SIC)|(1<<STAC)|(1<<AAC);

LPC_I2C0->I2CONSET = (1<<STO);

LPC_I2C0->I2CONCLR = (1<<SIC);

return 0;

}

u8 IIC0SendReadAddr(u8 addr)

{

LPC_I2C0->I2DAT = addr;

LPC_I2C0->I2CONSET = (1<<AA);

LPC_I2C0->I2CONCLR = (1<<SIC)|(1<<STAC);

return WaitResponse(STATUS_READADDR_ACK);

}

u8 IIC0ReadData(u8* value,u8 ack)

{

if(ack)

{

LPC_I2C0->I2CONSET = (1<<AA);

LPC_I2C0->I2CONCLR = (1<<SIC);

if( WaitResponse(STATUS_RECV_ACK))return 1;

}

else

{

LPC_I2C0->I2CONCLR = (1<<AAC)|(1<<SIC);

if(WaitResponse(STATUS_RECV_NACK))return 1;

}

*value = LPC_I2C0->I2DAT;

return 0;

}

返回的状态代码在系统中的定义为

#define STATUS_SENDSTART        0X08

#define STATUS_REPEATSTART      0X10

#define STATUS_SENDSLAVE_ACK    0X18

#define STATUS_SENDSLAVE_NACK   0X20

#define STATUS_SENDDATA_ACK     0X28

#define STATUS_SENDDATA_NACK    0X30

#define STATUS_LOSS             0X38

#define STATUS_READADDR_NACK    0X48

#define STATUS_READADDR_ACK     0X40

#define STATUS_RECV_ACK         0X50

#define STATUS_RECV_NACK        0X58

通过这一套api就可以完成iic通讯,以下是eeprom的例子

u8 At24cxxWriteBuffer(u16 writeAddr,u8* bufferStart,u8 len)

{

u8 ret = 0;

u8 i = 0;

ret = HwIIC1Start();    //  发送开始条件

if(ret)return 1;

if(EE_TYPE > AT24C16)

{

ret = HwIIC1SendWriteAddr(AT_DEVICE_ADDR);  //发送器件地址

if(ret)return 1;

ret = HwIIC1SendData((u8)writeAddr>>8); //发送高八位地址

if(ret)return 1;

}

else

{

ret = HwIIC1SendWriteAddr(AT_DEVICE_ADDR+((writeAddr/256)<<1));   //发送器件地址0XA0,写数据

if(ret)return 1;

}

ret = HwIIC1SendData((u8)writeAddr);    //发送低八位地址

if(ret)return 1;

for(i = 0; i < len; i++)

{

ret = HwIIC1SendData(*(bufferStart+i)); //发送数据

if(ret)return 1;

}

HwIIC1SendStop();   //发送停止位

DelayMs(5); //5ms等待写入完成

return 0;

}

u8 At24cxxReadBuffer(u16 readAddr,u8* bufferStart,u8 len)

{

u8 ret = 0;

u8 i = 0;

ret = HwIIC1Start();    //  发送开始条件

if(ret)return 1;

if(EE_TYPE > AT24C16)

{

ret = HwIIC1SendWriteAddr(AT_DEVICE_ADDR);  //发送器件地址

if(ret)return 1;

ret = HwIIC1SendData((u8)readAddr>>8);  //发送高八位地址

if(ret)return 1;

}

else

{

ret = HwIIC1SendWriteAddr(AT_DEVICE_ADDR+((readAddr/256)<<1));   //发送器件地址0XA0,写数据

if(ret)return 1;

}

ret = HwIIC1SendData((u8)readAddr); //发送低八位地址

if(ret)return 1;

ret = HwIIC1RepeatStart();  //重发start

if(ret)return ret;

ret = HwIIC1SendReadAddr(AT_DEVICE_ADDR+1);           //进入接收模式

if(ret)return ret;

for(i = 0; i < len-1; i++)

{

ret = HwIIC1ReadData(bufferStart+i,1);  //发送ACK

if(ret)return ret;

}

ret = HwIIC1ReadData(bufferStart+len-1,0);//读取不发送ACK

if(ret)return ret;

HwIIC1SendStop();//产生一个停止条件

return 0;

}

LPC1768的iic通讯的更多相关文章

  1. 用Verilog实现IIC通讯

    注意,此代码是错误代码,并不能实现想要的结果. 之所以留着,因为里面的enable 是独立开来的思想值得借鉴.就是控制单元和运算单元分开(我也是借鉴别人的实现思想).具体用verilogHDL实现II ...

  2. STM32作为主设备,Arduino作为从设备进行IIC通讯的注意要点

    近日公司的项目重心要往米思齐的Arduino图形化编程上转移了,需要我将STM32和Arduino的IIC通讯调通.之前Arduino并没怎么使用过,仅仅是将超声波的代码移植成TOF激光测距而已.网上 ...

  3. 基于esp32的IIC通讯

    本文源码地址在:http://download.csdn.net/download/noticeable/9962029 IIC 通讯应该是当代比较常用的几种通讯方式之一,其无需特殊的IO接口,连线方 ...

  4. Verilog实现IIC通讯第二版

    HMC5883三轴磁力传感器IIC通讯模块的VerilogHDL的实现 上一版并没有实现我想要的功能 0.0.1版   正在修订中   2013/9/2 //date :2013/7/7 //desi ...

  5. iic通讯 FPGA实现 mpu6050为例

    IIC最常用的通讯协议,但普遍用于单片机.arm这些,用FPGA实现大材小用,但对于菜鸡水平练练手很不错,考验串并转换和时序的控制.今天我就以mpu6050陀螺仪为例,实现FPGA的iic通信. 1. ...

  6. 「STM32 」IIC通讯原理及其实验

    I2C两线式串行总线通讯协议,它是由飞利浦开发的,主要用于连接微控制器及其外围设备之间,它是由数据线SDA和信号线SCL构成的,可发送和接收数据即在MUC和I2C设备之间,I2C和I2C之间进行全双工 ...

  7. LPC1768的IIS通讯

    IIS是飞利浦公司定义的一种用于音频传输的数字总线,LPC1768支持该总线, I2S接口为一条3线串行总线,含有1根数据线.1根时钟线和1根字选择信号线.基本的I2S连接具有一个主机(其总是为主机) ...

  8. IIC通讯协议(非原创,转载他人,用于学习)

    I2C协议:1.空闲状态 2.开始信号 3.停止信号 4.应答信号 5.数据的有效性 6.数据传输 IIC详解 1.I2C总线具有两根双向信号线,一根是数据线SDA,另一根是时钟线SCL 2.IIC总 ...

  9. IIC通讯程序

    IIC程序 IIC起始信号 void IIC_Start(void) { SDA_OUT();//sda设为输出 IIC_SDA=; IIC_SCL=; delay_us();//延时一段时间,具体时 ...

随机推荐

  1. HDU2199,HDU2899,HDU1969,HDU2141--(简单二分)

    二分是一种很有效的减少时间开销的策略, 我觉得单列出二分专题有些不太合理, 二分应该作为一中优化方法来考虑 这几道题都是简单的使用了二分方法优化, 二分虽然看似很简单, 但一不注意就会犯错. 在写二分 ...

  2. 利用未文档化API:RtlGetNtVersionNumbers 获取系统版本号

    问题一:Windows SDK 8.1版本中的VersionHelper.h文件当中没有IsWindows10ORGreater,所以当你用IsWindows8Point1ORGreater判断出版本 ...

  3. L9,a cold welcome

    expression: a large crowd of 一大群 in twenty minutes’time 20分钟之后 一些时间使用的介词 in two year‘s time on Satur ...

  4. 困扰你的private static final long serialVersionUID

    很多时候一个新手在写代码的时候,往往你的IDE就会告诉你一个警告 然后你点击处理这个警告之后,它就会默认给你的类生成一个 private static final long serialVersion ...

  5. SVN分支的创建,合并,与销毁和相关操作

    test是分支和主干所在的文件夹,SVNTest是主干,所有的分支都放在branch里面,192.168.1.101是服务器的地址 创建分支: 把服务器中的主干复制出来到自己的分支上: svn cop ...

  6. ThinkPHP使用方法

    1.下载ThinkPHP模板,整个导入到项目根目录下. 2.修改index.php文件,内容如下: <?php /***临时配置,项目完成开发后,这些配置会取消*******/define('A ...

  7. Php和httpd.conf的配置

    http://www.cnblogs.com/homezzm/archive/2012/08/01/2618062.html http://book.51cto.com/art/201309/4096 ...

  8. HDU 5875 st+二分区间

    题目大意:给你n个数,q次询问,每次询问区间[l, r],问a[i]%a[i + 1] % a[i + 2]...%a[j](j <= r)的值 思路:st预处理维护,再二分区间,复杂度n*(l ...

  9. activemq学习

    一.特性及优势 1.实现JMS1.1规范,支持J2EE1.4以上2.可运行于任何jvm和大部分web容器(ActiveMQ works great in any JVM)3.支持多种语言客户端(jav ...

  10. easyui tree使用方法

    加载数据 $('#treeul').tree({ checkbox:true, url:'initTree.aspx', onLoadSuccess:function(){ //绑定权限 $.ajax ...