zoukankan      html  css  js  c++  java
  • I.MX6ULL的裸机I2C驱动transfer函数(原作者:左钟凯)

    i2c_master_transfer函数,原作者左钟凯。可以借鉴一下。

     1 /*
     2  * @description    : I2C数据传输,包括读和写
     3  * @param - base: 要使用的IIC
     4  * @param - xfer: 传输结构体
     5  * @return         : 传输结果,0 成功,其他值 失败;
     6  */
     7 unsigned char i2c_master_transfer(I2C_Type *base, struct i2c_transfer *xfer)
     8 {
     9     unsigned char ret = 0;
    10     enum i2c_direction direction = xfer->direction;    
    11     base->I2SR &= ~((1 << 1) | (1 << 4));    /* 清除标志位 */
    12     while(!((base->I2SR >> 7) & 0X1)){};     //等待传输完成
    13     if ((xfer->subaddressSize > 0) && (xfer->direction == kI2C_Read))    //如果是读的话,要先发送寄存器地址,所以要先将方向改为写
    14     {
    15         direction = kI2C_Write;
    16     }
    17     ret = i2c_master_start(base, xfer->slaveAddress, direction); //发送开始信号
    18     if(ret){    
    19         return ret;
    20     }
    21     while(!(base->I2SR & (1 << 1))){};            /* 等待传输完成 */
    22     ret = i2c_check_and_clear_error(base, base->I2SR);    /* 检查是否出现传输错误 */
    23     if(ret){
    24         i2c_master_stop(base);    /* 发送出错,发送停止信号 */
    25         return ret;
    26     }
    27     if(xfer->subaddressSize)    //发送寄存器地址
    28     {
    29         do
    30         {
    31             base->I2SR &= ~(1 << 1);            /* 清除标志位 */
    32             xfer->subaddressSize--;                /* 地址长度减一 */
    33             base->I2DR =  ((xfer->subaddress) >> (8 * xfer->subaddressSize)); //向I2DR寄存器写入子地址
    34             while(!(base->I2SR & (1 << 1)));      /* 等待传输完成 */
    35             ret = i2c_check_and_clear_error(base, base->I2SR);/* 检查是否有错误发生 */
    36             if(ret){
    37                  i2c_master_stop(base);    //发送停止信号
    38                  return ret;
    39             }  
    40         } while ((xfer->subaddressSize > 0) && (ret == I2C_STATUS_OK));
    41 
    42         if(xfer->direction == kI2C_Read)         /* 读取数据 */
    43         {
    44             base->I2SR &= ~(1 << 1);            /* 清除中断挂起位 */
    45             i2c_master_repeated_start(base, xfer->slaveAddress, kI2C_Read); /* 发送重复开始信号和从机地址 */
    46             while(!(base->I2SR & (1 << 1))){};/* 等待传输完成 */
    47             ret = i2c_check_and_clear_error(base, base->I2SR);/* 检查是否有错误发生 */
    48             if(ret){
    49                 ret = I2C_STATUS_ADDRNAK;
    50                 i2c_master_stop(base);         /* 发送停止信号 */
    51                 return ret;  
    52             }          
    53         }
    54     }
    55     if ((xfer->direction == kI2C_Write) && (xfer->dataSize > 0)){    /* 发送数据 */
    56         i2c_master_write(base, xfer->data, xfer->dataSize);
    57     }
    58     if ((xfer->direction == kI2C_Read) && (xfer->dataSize > 0)){   /* 读取数据 */
    59         i2c_master_read(base, xfer->data, xfer->dataSize);
    60     }
    61     return 0;    
    62 }

     

    个人总结,有如下两点需要注意。

    1.改变传输方向(读过程)

    transfer包含了读写两个方向。读和写两个过程在transfer函数中的代码差异如下:

    从中可得到,读过程多了3个步骤,分别为:“将数据传输方向先改为写”,“发送重复开始信号”,“发送从机地址”。

    2.等待传输完成和错误检查。

    发送寄存器地址前,需要确认总线不忙(即步骤b)。依据可在I.MX6ULL手册的P1453找到:

    Depending on the relative frequencies of the system clock and the SCL period, it may be necessary to wait until the I2C is not busy after writing the calling address to the data register(I2C_I2DR),before proceeding to load data into the data register(I2C_I2DR).

  • 相关阅读:
    常见26个jquery使用技巧详解(比如禁止右键点击、隐藏文本框文字等)
    禁用页面及页面所有frame内的右键菜单
    JS模态窗口返回值兼容问题解决方案
    winform登录时,在密码框按下回车,直接登陆
    C#中实现邮件发送功能
    CTFHub-彩蛋(持续更新~)
    CTFHub技能树-目录遍历
    免密钥方式登陆配置
    Ansible_Day1
    Python_Day2_共享你的代码
  • 原文地址:https://www.cnblogs.com/kunshanpipixia/p/14289236.html
Copyright © 2011-2022 走看看