LPC804开发(9.IIC通信)

1.前言

早上正点原子的逻辑分析仪到了,那正好分析IIC过程会比较舒服,SPI的协议我也更新了,最后把完整的波形已经放到了最后,大家有兴趣也可以看看。

2.初始化

IIC的初始化非常简单,程序如下

void init_i2c0(void)
{
	i2c_master_config_t masterConfig;

    /* Enables clock for switch matrix.: enable */
    CLOCK_EnableClock(kCLOCK_Swm);

    /* I2C0_SDA connect to P0_7 */
    SWM_SetMovablePinSelect(SWM0, kSWM_I2C0_SDA, kSWM_PortPin_P0_7);

    /* I2C0_SCL connect to P0_14 */
    SWM_SetMovablePinSelect(SWM0, kSWM_I2C0_SCL, kSWM_PortPin_P0_14);

    /* Disable clock for switch matrix. */
    CLOCK_DisableClock(kCLOCK_Swm);

    CLOCK_Select(kI2C0_Clk_From_MainClk);

    /*
     * masterConfig.debugEnable = false;
     * masterConfig.ignoreAck = false;
     * masterConfig.pinConfig = kI2C_2PinOpenDrain;
     * masterConfig.baudRate_Bps = 100000U;
     * masterConfig.busIdleTimeout_ns = 0;
     * masterConfig.pinLowTimeout_ns = 0;
     * masterConfig.sdaGlitchFilterWidth_ns = 0;
     * masterConfig.sclGlitchFilterWidth_ns = 0;
     */
    I2C_MasterGetDefaultConfig(&masterConfig);

    /* Change the default baudrate configuration */
    masterConfig.baudRate_Bps = 100000U;

    /* Initialize the I2C master peripheral */
    I2C_MasterInit(I2C0, &masterConfig, CLOCK_GetFreq(kCLOCK_MainClk));
}

分配一个结构体用以设置

fda3eb75ab0847fcb2d2186c6a159e3c.png

映射管脚

ba866fb4aa794387aea96c6d97f0e01d.png

开启IIC时钟,还是mainclk,15Mhz那条

59a7becb063348a9abc8bb5bc332b7d6.png

 获取默认配置,并修改通信速率。这里默认配置也放在这里了,一般不用怎么更改,如果大家需要可以看一下详细配置,根据实际情况修改。

612ebf540e2548639e5d9d0c00637424.png

将配置信息初始化

89b9ac16f0b549d8be9b1fbe8c4c12bb.png

整个过程没有什么难度,都是非常常见的简单。

额外说一句官方的例程又又又有问题了,在这个最简单的例程里,i2c的时钟频率是15Mhz,而非12Mhz,我当初第一次测试的时候发现SCL的时钟频率不是设置的100K,而是125K,然后一查程序发现是时钟不对,但是我又查了时钟发现实际是15Mhz,难怪

64202887b524451681ae1ead0f839ef2.png

真是不知道当初开发这个工程的工程师是不是996太多了,竟然出现这样的问题,以前的程序都是读取主时钟的,包括这次我的程序里也是,真是怪了。

3.发送

程序如下

void i2c0_senddata(unsigned char *senddata,unsigned char datalength,unsigned char address)
{
	unsigned char reVal=kStatus_Fail;
    /* Send master blocking data to slave */
    if (kStatus_Success == I2C_MasterStart(I2C0, address, kI2C_Write))
    {

        reVal = I2C_MasterWriteBlocking(I2C0, senddata, datalength, kI2C_TransferDefaultFlag);
        I2CCHECKACK;

        reVal = I2C_MasterStop(I2C0);
        I2CCHECKACK;
    }
}

首先是发送起始信号,当得到应答才继续

6ae633da3b2b4dbd93183f2ac0d98eba.png 然后主机发送

eebc9a7505f84a49bb81fa4e5b4e822c.png

这个函数的原型如下,第一个参数是指定IIC(I2C0/I2C1)第二个参数是需要传输信息的基地址,第三个参数是传输长度,最后是标志位。

e47e8f95089e42bca273f7146c3a54f1.png 这里的标志位是可以指定是否开启应答,有如下这些可选

8399e573c3284b108c4ea752e458ebc6.png

发送完毕后我们可以进行检测,看看是否有应答,我这里用宏定义进行了封装

0bc56b3fc0fc42a5963ba0a4e147a8a6.png

之后是发送停止信号

cee0df09d1914395b0624ca54d9f4d97.png

这就是整个发送过程了

4.接收

这里我借鉴eeprom的通信过程进行介绍,因为eeprom里面包含了重发开始信号,过程会复杂一点,程序如下

void i2c0_recivedata(void)
{
	unsigned char reVal=kStatus_Fail;
	unsigned char deviceAddress[2]={0,0};
    if (kStatus_Success == I2C_MasterStart(I2C0, 0x50, kI2C_Write))
    {
        reVal = I2C_MasterWriteBlocking(I2C0, &deviceAddress, 2, kI2C_TransferNoStopFlag);
        I2CCHECKACK;

        reVal = I2C_MasterRepeatedStart(I2C0, 0x50, kI2C_Read);
        I2CCHECKACK;

        reVal =
            I2C_MasterReadBlocking(I2C0, g_master_rxBuff, 3, kI2C_TransferDefaultFlag);
        I2CCHECKACK;

        reVal = I2C_MasterStop(I2C0);
        I2CCHECKACK;
    }
}

首先申请的标志位,和发送地址

8fff99d6ff134714b68b429cf0721b97.png

之后是发送开始信号,从机地址0x50,主机写

b1c5159195e64a60b4479d8e6723a31b.png

然后是先发送两个数据,注意这里无需停止信号

98503db53dd34031abbe0c14e04e5393.png 然后是发送重新起始信号,这里50是从机地址,主机读

2200883707f64b94b5490872aa1ff2cb.png

之后是读取过程,与写入类似,第一个参数指定iic,第二个参数是主机接受数据地址,第三个参数是数据长度,最后一个参数是开启标准位

3ce40692e12641e4b52b71f9aced345f.png 然后是发送停止信号

af6354a0b1ee428692dc6e6cfe9f7596.png

5.测试

5.1发送

这里我一共发送五个数据,数据如下,从机地址是0x50

1721ee5405844f3c84dc8156de4e4d56.png

8cd3b4fd799d4522b2271ee610de1227.png

0c7013ca56134cabbdc38c2bb09df80e.png可以看到能够顺利接收到,其中的频率也是正确的

01892b00c4a149d3b03fadce2665effc.png

5.2接收

我这里从机发送3个数据,00 11 22

ecceb32759ed41088f8a66c656deb7c7.png

结果如下,可以看到从机顺利接收和发送数据了

2120b8f0cfbe4c729309aa7dd09f174a.png

c7a4cd2b8c794f4285a1d61c50857c09.png

波形也非常漂亮,最后看一下主机,三个数据也读进来了

f940e991496d4fb5bb98a999a80883ef.png

6.结语

至此三大主要通信协议我们都已经说过了,可以感觉到NXP的通信协议做的是非常流畅的,数据等等都能顺利读取到,程序也很简单。LPC804还有最后AD/DA两章没有讲,年前应该是能做完的了。好了,还是那句话,有问题欢迎评论区讨论,那么我们下一篇文章见。

  • 19
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值