打印
[技术问题解答]

KL15的iic问题(已解决)

[复制链接]
2119|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wxb18k|  楼主 | 2014-9-4 14:01 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
iic, I2c, TE, TI, IO
本帖最后由 FSL_TICS_A 于 2014-10-8 09:17 编辑

我用的是FRDM-K25Z_demo例程,但是一直无法调通AT24c256的使用,AT24C256与1MHz I2C总线兼容,以下是我的主要配置(PTE18和19为SCL和SDA):
/*********************************************************************************************************
** 全局变量
*********************************************************************************************************/
const INT16U GusSCLDivider[64] = {
    20, 22, 24, 26, 28, 30, 34, 40, 28, 32, 36, 40, 44, 48, 56, 68, 48, 56, 64, 72, 80, 88, 104, 128,
    80, 96, 112, 128, 144, 160, 192, 240, 160, 192, 224, 256, 288, 320, 384, 480, 320, 384, 448, 512,
    576, 640, 768, 960, 640, 768, 896, 1024, 1152, 1280, 1536, 1920, 1280, 1536, 1792, 2048, 2304,
    2560, 3072, 3840};

/*
* 用于进行I2C通讯的全局变量   
*/
volatile INT8U     I2C_sla;                                             /* I2C器件从地址                */
volatile INT32U    I2C_suba;                                            /* I2C器件内子地址              */
volatile INT8U     I2C_suba_num;                                        /* I2C子地址长度                */
volatile INT8U     *I2C_buf;                                            /* 数据缓冲区指针               */
volatile INT32U    I2C_num;                                             /* 要读取/写入的数据个数        */
volatile INT8U     I2C_end;                                             /* I2C总线结束标志              */
volatile INT8U     I2C_restart;                                         /* I2C总线结重复起始标?         */

static   INT8U     I2C_irq_status;                                      /* I2C中断读写操作控制          */
                                                                        /* 1--读模式                    */
                                                                        /* 0--写模式                    */
volatile INT8U     I2C_sla_dir;         /*  从机控制
                                         *  1--读取操作
                                         *  0--写操作
                                         */



/*********************************************************************************************************
** Function name:           i2c0Init
** Descriptions:            I2C初始化
** input parameters:        none
** output parameters:       none
** Returned value:          none
** Created by:              Li Xiang
** Created Date:            2012-12-14
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
*********************************************************************************************************/
void i2c0Init(void)
{
    INT32U ulBaudRate = 0;
    INT32U i = 0;
    INT32U j = 0;
#if 1
    PORT_ENABLE_CLK(MKL_PORTE);
    IO_FUN_SEL(MKL_PORTE,18,4);                                         /* SCL初始化                    */
    IO_FUN_SEL(MKL_PORTE,19,4);                                         /* SDA初始化                    */
#endif
#if 0
    PORT_ENABLE_CLK(MKL_PORTB);
    IO_FUN_SEL(MKL_PORTB,0,2);                                          /* SCL初始化                    */
    IO_FUN_SEL(MKL_PORTB,1,2);                                          /* SDA初始化                    */
#endif   
#if 0
    PORT_ENABLE_CLK(MKL_PORTB);
    IO_FUN_SEL(MKL_PORTB,2,2);                                          /* SCL初始化                    */
    IO_FUN_SEL(MKL_PORTB,3,2);                                          /* SDA初始化                    */
#endif   
#if 0
    PORT_ENABLE_CLK(MKL_PORTC);
    IO_FUN_SEL(MKL_PORTC,8,2);                                          /* SCL初始化                    */
    IO_FUN_SEL(MKL_PORTC,9,2);                                          /* SDA初始化                    */
#endif   
    i2c0ClkEnable();                                                    /* 打开I2C0时钟                 */

#if (I2C0_MODE == I2C_MASTER)
    ulBaudRate = SystemBusClock / (I2C0_BAUD_RATE << I2C0_MUL);         /* 计算SCL divider              */
    for(j = 0; j < I2C0_BT_ERROR; j++) {
        for(i = 0; i < 64; i++) {
            if(((ulBaudRate - GusSCLDivider) <= j) || ((GusSCLDivider - ulBaudRate) <= j) ){
                break;
            }   
        }
        if (i != 64) {
            break;
        }   
    }

    if (j == I2C0_BT_ERROR) {
        printf("I2C0 BT SET ERROR\r\n");        
        while(1);
    }  
    I2C0_F = (I2C0_MUL << 6) | i;                                       /* 配置波特率                   */
     I2C0_C1 |=  (1 << 5);                                            /* 选择主机模式                 */

#endif
#if (I2C0_MODE == I2C_SLAVER)
    I2C0_C1 |=  (1 << 7)|                                               /* 响应地址                     */
                (I2C0_SLAVER_ADDRESS_MODE << 6)|                        /* 从机地址类型定义             */
                (I2C0_SLAVER_ADR_MATCH << 3)|                           /* 地址匹配设置                 */                 
                ((I2C0_SLAVER_ADR >> 8) & 7UL);                         /* 高位地址设置                 */
    I2C0_A1 = I2C0_SLAVER_ADR;                                          /* 从机地址定义                 */
    I2C0_RA = I2C0_RANGE_SLAVER_ADR;

//     I2C0_C1 &=  ~(1 << 5);                                           /* 选择从机模式                 */

#endif

//     I2C0_C1 |=  (1 << 5);                                            /* 发送起始位与停止位           */               
//     I2C0_C1 &=  ~(1 << 5);                                           /* 初始化总线                   */                                          

    I2C0_S |= (1 << 1)|                                                 /* 清除标志                     */
              (1 << 4);
    I2C0_FLT    |= 1 << 6;         

    I2C0_C1 |=  (1 << 7)|                                               /* 使能I2C0                     */
                (1 << 6);                                               /* 使能IRQ                      */
    I2C0_FLT  |= 1 << 5;                                                /* 使能停止中断                 */

    NVIC_EnableIRQ(I2C0_IRQn);
    NVIC_SetPriority(I2C0_IRQn,3);                                      /* 用户自己定义                 */        

}

/*********************************************************************************************************
** Function name:           i2c0SendByte
** Descriptions:            I2C0发送单字节函数
** input parameters:        sla:从机地址 dat:数据缓冲区指针
** output parameters:       none
** Returned value:          none
** Created by:              Li Xiang
** Created Date:            2012-12-14
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
*********************************************************************************************************/
INT8U i2c0SendByte(INT8U sla, INT8U *dat)
{
    I2C_sla         = sla;                                              /* 写操作的器件地址             */
    I2C_buf         = dat;                                              /* 待发送的数据缓冲区指针       */
    I2C_num         = 1;                                                /* 发送1字节数据                */
    I2C_suba_num    = 0;                                                /* 无子地址                     */
    I2C_sla_dir     = 0;                                                /* 写操作                       */
    I2C_irq_status  = 0;                                                /* 写模式                       */
    I2C_end         = 0;   

    I2C0_C1 |=  (1 << 5);                                               /* 发送起始位,主模式           */               
    I2C0_D   = I2C_sla & 0xFE;                                          /* 将写地址写入数据寄存器       */
    I2C0_C1 |=  (1 << 4);                                               /* 发送模式                     */               

    return( Wait_I2c_End(20));
}

/*********************************************************************************************************
** Function name:           i2c0WriteNByte
** Descriptions:            I2C0发送多字节函数
** input parameters:        sla:从机地址 suba_type: 子地址类型
**                          suba:子地址 s:数据缓冲区指针 num:数据长度
** output parameters:       none
** Returned value:          none
** Created by:              Li Xiang
** Created Date:            2012-12-14
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
*********************************************************************************************************/
INT8U i2c0WriteNByte(INT8U sla, INT8U suba_type, INT32U suba, INT8U *s, INT32U num)
{
    I2C_sla         = sla;                                              /* 写操作的器件地址             */
    I2C_suba        = suba;                                             /* 子地址类型                   */
    I2C_num         = num;                                              /* 发送n字节数据                */
    I2C_suba_num    = suba_type;                                        /* 子地址类型                   */

    I2C_buf         = s;                                                /* 待发送的数据缓冲区指针       */
    I2C_sla_dir     = 0;                                                /* 写操作                       */
    I2C_irq_status  = 0;                                                /* 写模式                       */
    I2C_end         = 0;   
    I2C_restart     = 0;

    I2C0_C1 |=  (1 << 5);                                               /* 发送起始位,主模式           */  
    I2C0_C1 |=  (1 << 4);                                               /* 发送模式                     */      
    I2C0_D   = I2C_sla & 0xFE;                                          /* 将写地址写入数据寄存器       */

    return( Wait_I2c_End(20));
}

/*********************************************************************************************************
** Function name:           i2c0ReadNByte
** Descriptions:            I2C0接收多字节函数
** input parameters:        sla:从机地址 suba_type: 子地址类型
**                          suba:子地址 s:接收数据缓冲区指针 num:数据长度
** output parameters:       none
** Returned value:          none
** Created by:              Li Xiang
** Created Date:            2012-12-14
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
*********************************************************************************************************/
INT8U i2c0ReadNByte(INT8U sla, INT8U suba_type, INT32U suba, INT8U *s, INT32U num)
{
    I2C_sla         = sla;                                              /* 写操作的器件地址             */
    I2C_suba        = suba;                                             /* 子地址类型                   */
    I2C_num         = num;                                              /* 发送n字节数据                */
    I2C_suba_num    = suba_type;                                        /* 子地址类型                   */

    I2C_buf         = s;                                                /* 接收数据缓冲区指针           */
    I2C_sla_dir     = 1;                                                /* 写操作                       */
    I2C_irq_status  = 0;                                                /* 写模式                       */
    I2C_end         = 0;   
    I2C_restart     = 0;

    I2C0_C1 |=  (1 << 5);                                               /* 发送起始位,主模式           */               
    I2C0_C1 |=  (1 << 4);                                               /* 发送模式                     */
    I2C0_D   = I2C_sla & 0xFE;                                          /* 将写地址写入数据寄存器       */   
    Wait_I2c_Restart(20);
    I2C0_D   = (I2C_sla & 0xFE) + 1;                                    /* 将读地址写入数据寄存器       */

    return( Wait_I2c_End(20));
}

相关帖子

沙发
FSL_TICS_Robin| | 2014-9-5 08:56 | 只看该作者
楼主你好
建议你先用示波器或逻辑分析仪看一下引脚上的波形是否符合时序。

使用特权

评论回复
板凳
jd972594| | 2014-9-5 13:54 | 只看该作者
上拉电阻没?

使用特权

评论回复
地板
FSL_TICS_Robin| | 2014-9-10 10:13 | 只看该作者
请问你的芯片mask编号是多少?
请注意如果你的KL25芯片mask号是KINETIS_L_1N97F和KINETIS_L_2N97F那么对应勘误表里有一条需要注意。
勘误表可以从 KL2x: Kinetis KL2x USB MCU 文档页面下载。

使用特权

评论回复
5
FSL_TICS_Robin| | 2014-9-10 10:15 | 只看该作者
FSL_TICS_Robin 发表于 2014-9-10 10:13
请问你的芯片mask编号是多少?
请注意如果你的KL25芯片mask号是KINETIS_L_1N97F和KINETIS_L_2N97F那么对应 ...

如果你的芯片mask号正好是以上2种,那么你的程序调用
I2C0_F = (I2C0_MUL << 6) | i;                                       /* 配置波特率                   */
这句话是就需要注意了,I2C0_MUL在MKL_i2c.h文件里的定义需修改。

使用特权

评论回复
6
FSL_TICS_A| | 2014-10-8 09:16 | 只看该作者
本帖最后由 FSL_TICS_A 于 2014-10-8 09:17 编辑

请问此问题解决了吗?如果问题尚未解决建议继续在帖子里与大家一起讨论。
由于你长时间未回帖,所以先把你的帖子标示成已解决了。
如果问题解决了能否与大家分享一下相关经验呢?
另外还请配合我们按照论坛置顶帖:
本论坛中结帖方式 描述操作

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

20

主题

140

帖子

1

粉丝