KL25Z128开发板例程中的iic问题

2019-03-26 07:58发布

我使用例程中的IIC程序,直接不改动例程,能在开发板上正常跑起来,但是,我现在要把数据写到EEPROM中去,如果使用例程中的读写函数:
i2c0WriteNByte(0xA0, ONE_BYTE_SUBA, 0x00, ucData, 10);              /* 写数据操作                   */
i2c0ReadNByte(0xA0, ONE_BYTE_SUBA, 0x00, ucData, 10);               /* 读数据操作                   */
那么,我该如何往EEPROM中的固定地址写数据呢?如果使用上面这两个函数,应该都是从0地址开始读写吧?
要怎样改才能使我能从EEPROM中的任意地址读取数据呢?
如下是实例代码中,关于IIC的部分:
/*********************************************************************************************************
** 全局变量
*********************************************************************************************************/
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--写操作
                                         */
void i2cDelay (INT32U ulTime)
{
    INT32U i;
    i = 0;
    while (ulTime--) {
        for (i = 0; i < 5000; i++);
    }
}
/*********************************************************************************************************
** Function name:           Wait_I2c_End
** Descriptions:            软件延时,提供给I2C总线等待超时使用
** input parameters:        dly        延时参数,值越大,延时越久
** Output parameters:       NONE
** Returned value:          NONE
*********************************************************************************************************/
static INT8U  Wait_I2c_End(INT32U  dly)
{  
    INT32U  i = 0;
    if( I2C_end == 1 )     return (1);
    for(; dly > 0; dly--)
    for(i = 0; i<5000; i++)
    {
        if( I2C_end == 1 ) return (1);
    }
    return (0);
}
/*********************************************************************************************************
** Function name:           Wait_I2c_Restart
** Descriptions:            等待I2C发送Restart
** input parameters:        dly        延时参数,值越大,延时越久
** Output parameters:       NONE
** Returned value:          NONE
*********************************************************************************************************/
static INT8U  Wait_I2c_Restart(INT32U  dly)
{  
    INT32U  i = 0;
    for(; dly > 0; dly--) {
        for(i = 0; i< 5000; i++) {
            if( I2C_restart == 1 ) {
                for(i = 0; i< 200; i++) {
                }
                return (1);
            }
        }
    }
    return (0);
}
/*********************************************************************************************************
** Function name:           i2c0ClkEnable
** Descriptions:            I2C时钟使能
** input parameters:        none
** output parameters:       none
** Returned value:          none
** Created by:              Li Xiang
** Created Date:            2012-12-14
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
*********************************************************************************************************/
__INLINE void i2c0ClkEnable(void)
{
    SIM_SCGC4 |= SIM_SCGC4_I2C0_MASK;
}
/*********************************************************************************************************
** Function name:           i2c0ClkDisable
** Descriptions:            I2C时钟禁能
** input parameters:        none
** output parameters:       none
** Returned value:          none
** Created by:              Li Xiang
** Created Date:            2012-12-14
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
*********************************************************************************************************/
__INLINE void i2c0ClkDisable(void)
{
    SIM_SCGC4 &= ~SIM_SCGC4_I2C0_MASK;
}
/*********************************************************************************************************
** Function name:           i2c1ClkEnable
** Descriptions:            I2C时钟使能
** input parameters:        none
** output parameters:       none
** Returned value:          none
** Created by:              Li Xiang
** Created Date:            2012-12-14
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
*********************************************************************************************************/
__INLINE void i2c1ClkEnable(void)
{
    SIM_SCGC4 |= SIM_SCGC4_I2C1_MASK;
}
/*********************************************************************************************************
** Function name:           i2c1ClkDisable
** Descriptions:            I2C时钟禁能
** input parameters:        none
** output parameters:       none
** Returned value:          none
** Created by:              Li Xiang
** Created Date:            2012-12-14
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
*********************************************************************************************************/
__INLINE void i2c1ClkDisable(void)
{
    SIM_SCGC4 &= ~SIM_SCGC4_I2C1_MASK;
}   
/*********************************************************************************************************
** 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 0
    PORT_ENABLE_CLK(MKL_PORTE);
    IO_FUN_SEL(MKL_PORTE,24,5);                                         /* SCL初始化                    */
    IO_FUN_SEL(MKL_PORTE,25,5);                                         /* 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 1
    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 ");        
        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));
}
/*********************************************************************************************************
** Function name:           I2C0_IRQHandler
** 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 I2C0_IRQHandler(void)
{
    if (I2C0_FLT & (1 << 6)) {      
        I2C_end = 1;            
        I2C0_FLT    |= (1 << 6);                                        /* 清零停止中断标志             */  
        I2C0_S      |= (1 << 1);                                        /* 清零中断标志                 */  
        return;                                                         /* 中断返回                     */
    }
    I2C0_S      |= (1 << 1);                                            /* 清零中断标志                 */   
#if (I2C0_MODE == I2C_MASTER)
    switch (I2C_irq_status) {
        case 0:                                                         /* 发送模式                     */
        if (I2C0_S & 0x01) {                                            /* 应答检测                     */
            I2C_end = 1;                                                /* 无应答,传输结束             */
            I2C0_C1 &=  ~(1 << 5);                                      /* 发送STOP                     */
        }  
        if (I2C_suba_num == TWO_BYTE_SUBA) {                            /* 两字节从机子地址处理         */
            I2C0_D = ((I2C_suba >> 8) & 0xff);
            I2C_suba_num --;
        } else if (I2C_suba_num == ONE_BYTE_SUBA) {                     /* 单字节从机子地址处理         */
            I2C0_D = (I2C_suba & 0xff);
            I2C_suba_num --;
        } else if (I2C_suba_num == NONE_SUBA) {                         /* 无从机子地址处理             */
            if (I2C_sla_dir == 1) {                                     /* 主机读操作处理               */                                          
                I2C0_C1 |= 1 << 2;                                      /* 发送Restart                  */
                I2C_suba_num --;
                I2C_restart = 1;                                        /* 重复起始信号标志置位         */
            } else {
                if (I2C_num > 0) {                                      /* 发送数据                     */
                    I2C0_D = *I2C_buf++;
                    I2C_num --;
                } else {
                    I2C0_C1 &=  ~(1 << 5);                              /* 发送STOP                     */                                          
                }
            }
        } else {
            I2C0_C1 &= ~(1 << 4);                                       /* 转为接收模式                 */
            I2C_irq_status = 1;
            *I2C_buf = I2C0_D;  
        }        
        break;
        case 1:                                                         /* 接收模式                     */
        I2C_num--;
        if (I2C_num == 1) {                                             /* 接收最后一个字节,返回NACK   */
            I2C0_C1 |= 1 << 3;
        }   
        if (I2C_num == 0) {                                             /* 接收完成,结束总线           */
            I2C0_C1 &=  ~(1 << 5);                                      /* 发送STOP                     */                                          
        }
        *I2C_buf++ = I2C0_D;         
        break;
        default:
        break;   
    }   
        
#endif
#if (I2C0_MODE == I2C_SLAVER)
#endif   
} 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。