查看: 10432|回复: 5

[求助] K60 I2C使用疑问····求助啊·····快哭了

[复制链接]

该用户从未签到

1

主题

3

帖子

0

新手上路

Rank: 1

积分
7
最后登录
1970-1-1
发表于 2013-12-23 23:45:35 | 显示全部楼层 |阅读模式
 想用LPLD的库函数用硬件I2C写L3G4200陀螺仪,但是怎么配置也读不出数来,读寄存器的值一直都不对········
一个星期了···快哭了····求助啊
 
这是相关的寄存器和引脚的一些设置,在。h文件里面,是用MMA7660修改的,所以里面函数的名字是MMA7660
 
 
 
 
 
/**
 * @file DEV_MMA7660.h
 * @version 0.1[By LPLD]
 * @date 2013-09-24
 * @brief MMA7660三轴加速度传感器设备驱动程序
 *
 * 更改建议:可根据实际硬件修改
 *
 * 版权所有:北京拉普兰德电子技术有限公司
 * http://www.lpld.cn
 * mail:support@lpld.cn
 *
 * @par
 * 本代码由拉普兰德[LPLD]开发并维护,并向所有使用者开放源代码。
 * 开发者可以随意修使用或改源代码。但本段及以上注释应予以保留。
 * 不得更改或删除原版权所有者姓名,二次开发者可以加注二次版权所有者。
 * 但应在遵守此协议的基础上,开放源代码、不得出售代码本身。
 * 拉普兰德不负责由于使用本代码所带来的任何事故、法律责任或相关不良影响。
 * 拉普兰德无义务解释、说明本代码的具体原理、功能、实现方法。
 * 除非拉普兰德[LPLD]授权,开发者不得将本代码用于商业产品。
 */
#ifndef __DEV_MMA7660_H__
#define __DEV_MMA7660_H__
 
#include "common.h"
#include "HW_I2C.h"
 
/********用户可修改值 开始***********/
//连接MMA7660用到的I2C通道
#define MMA7660_I2CX    (I2C0)
 
//连接MMA7660用到的SCL引脚
#define MMA7660_SCLPIN  (PTB2)
 
//连接MMA7660用到的SDA引脚
#define MMA7660_SDAPIN  (PTB3)
/********用户可修改值 结束***********/
 
//==========MMA7660 寄存器地址==================//
#define WHO_AM_I 0x0F
#define CTRL_REG1 0x20
#define CTRL_REG2 0x21
#define CTRL_REG3 0x22
#define CTRL_REG4 0x23
#define CTRL_REG5 0x24
#define REFERENCE 0x25
#define OUT_TEMP 0x26
#define STATUS_REG 0x27
#define OUT_X_L 0x28
#define OUT_X_H 0x29
#define OUT_Y_L 0x2A
#define OUT_Y_H 0x2B
#define OUT_Z_L 0x2C
#define OUT_Z_H 0x2D
#define FIFO_CTRL_REG 0x2E
#define FIFO_SRC_REG 0x2F
#define INT1_CFG 0x30
#define INT1_SRC 0x31
#define INT1_TSH_XH 0x32
#define INT1_TSH_XL 0x33
#define INT1_TSH_YH 0x34
#define INT1_TSH_YL 0x35
#define INT1_TSH_ZH 0x36
#define INT1_TSH_ZL 0x37
#define INT1_DURATION 0x38
//=========MMA7660 功能参数==================//
#define MMA7660_DEV_ADDR   0x69 //Normally,can range 0x08 to 0xEF
#define MMA7660_DEV_WRITE  MMA7660_DEV_ADDRPCR[9] = PORT_PCR_MUX(2) | ode_mask;
    }
    else if(sda_pin == PTB1) 
    {
      PORTB-&gtCR[1] = PORT_PCR_MUX(2) | ode_mask;
    }
    else //sda_pin = PTB3
    {
      PORTB-&gtCR[3] = PORT_PCR_MUX(2) | ode_mask; 
    }
  }
  else if(i2cx == I2C1)
  { 
    SIM->SCGC4 |= SIM_SCGC4_I2C1_MASK; //开启I2C1时钟
 
    if(scl_pin == PTE1)
    {
      PORTE-&gtCR[1] = PORT_PCR_MUX(6) | ode_mask;         
    }
    else //scl_pin = PTC10
    {
      PORTC-&gtCR[10] = PORT_PCR_MUX(2) | ode_mask;  
    }
 
    if(sda_pin == PTE0)
    {
      PORTE-&gtCR[0] = PORT_PCR_MUX(6) | ode_mask;
    }
    else //sda_pin = PTC11
    {
      PORTC-&gtCR[11] = PORT_PCR_MUX(2) | ode_mask; 
    }
  }
  else
    return 0;
  
  if(i2c_init_structure.I2C_IntEnable == TRUE && isr_func != NULL)
  {
    //产生I2C中断的中断源:
    //1,完成1个字节传输时,IICIF置位产生中断;
    //2,当Calling Address匹配成功时产生中断,参考K60文档1456页I2Cx_S寄存器IAAS位;
    //3,从机模式下当总线仲裁丢失时,IICIF置位产生中断;
    //  需要同时写1清除II2Cx_S的ARBL标志位和 I2Cx_S的 IICIF的标志位;
    //4,如果SMB寄存器的SHTF2 interrupt使能,当SHTF2 timeout时IICIF置位产生中断;
    //  需要同时写1清除I2Cx_SMB的SLTF标志位和 I2Cx_S的 IICIF的标志位;
    //5,当SLT寄存器不为0时,SMBus的SCL low timer计数等于SLT的值时IICIF置位产生中断;
    //  需要同时写1清除I2Cx_SMB的SHTF2标志位和 I2Cx_S的 IICIF的标志位;
    //6,当Wakeup 使能,I2C在停止模式下接收到Wakeup信号,将产生中断.
 
    i2cx->C1 |= I2C_C1_IICIE_MASK;
 
    if(i2cx == I2C0)
    {
      I2C_ISR[0] = isr_func;
    }
    else if(i2cx == I2C0)
    {
      I2C_ISR[1] = isr_func;
    }
    else 
      return 0;
  }
 
  //i2cx->C2 |= I2C_C2_HDRS_MASK;      //提高I2C驱动能力
  i2cx->F  = I2C_F_ICR(bus_speed)|I2C_F_MULT(0);   //配置I2Cx SCL BusSpeed
  i2cx->C1 |= I2C_C1_IICEN_MASK;      //使能I2Cx
  
  return 1;
}
 
/*
 * LPLD_I2C_Deinit
 * I2C模块反初始化函数,在该函数中关闭I2Cx的外设总线时钟,关闭I2C模块的
 * 时钟,禁止外设中断。
 *
 * 参数:
 *    I2C_InitTypeDef--i2c_init_structure
 *                     具体定义见I2C_InitTypeDef
 *
 * 输出:
 *    无
 *
 */  
uint8 LPLD_I2C_Deinit(I2C_InitTypeDef i2c_init_structure)
{
  I2C_Type *i2cx = i2c_init_structure.I2C_I2Cx;
 
  i2cx->C1 &= ~I2C_C1_IICEN_MASK;      //I2Cx
  if(i2cx == I2C0)
  {
    SIM->SCGC4 &= ~SIM_SCGC4_I2C0_MASK; //关闭I2C0时钟
    disable_irq((IRQn_Type)I2C0_IRQn);
  }
  else if (i2cx == I2C1)
  {
    SIM->SCGC4 &= ~SIM_SCGC4_I2C1_MASK; //关闭I2C1时钟
    disable_irq((IRQn_Type)I2C1_IRQn);
  }
  else
  {
    return 0;
  }
  return 1;
}
 
/*
 * LPLD_I2C_EnableIrq
 * I2C外设中断使能
 *
 * 参数:
 *    I2C_InitTypeDef--i2c_init_structure
 *                     具体定义见I2C_InitTypeDef
 *
 * 输出:
 *    无
 *
 */  
void LPLD_I2C_EnableIrq(I2C_InitTypeDef i2c_init_structure)
{
  I2C_Type *i2cx = i2c_init_structure.I2C_I2Cx; 
 
  if(i2cx == I2C0)
  {
    enable_irq((IRQn_Type)I2C0_IRQn);
  }
  else if (i2cx == I2C1)
  {
    enable_irq((IRQn_Type)I2C1_IRQn);
  }
  else
  {
    return;
  }
}
 
/*
 * LPLD_I2C_DisableIrq
 * 禁止I2C外设中断
 *
 * 参数:
 *    I2C_InitTypeDef--i2c_init_structure
 *                     具体定义见I2C_InitTypeDef
 *
 * 输出:
 *    无
 *
 */  
void LPLD_I2C_DisableIrq(I2C_InitTypeDef i2c_init_structure)
{
  I2C_Type *i2cx = i2c_init_structure.I2C_I2Cx;
  i2cx->C1 &= ~I2C_C1_IICIE_MASK;
 
  if(i2cx == I2C0)
  {
    disable_irq((IRQn_Type)I2C0_IRQn);
  }
  else if (i2cx == I2C1)
  {
    disable_irq((IRQn_Type)I2C1_IRQn);
  }
  else
  {
    return;
  }
}
 
/*
 * LPLD_I2C_Start
 * 产生I2C开始信号
 * 
 * 参数:
 *    i2cx--选择I2C模块的通道
 *      |__I2C0           --I2C通道0
 *      |__I2C1           --I2C通道1
 * 输出:
 *    无
 */
void LPLD_I2C_Start(I2C_Type *i2cx)
{
  i2cx->C1 |= I2C_C1_TX_MASK ;
  i2cx->C1 |= I2C_C1_MST_MASK ;
}
 
/*
 * LPLD_ReStart
 * I2C再次产生开始信号
 * 
 * 参数:
 *    i2cx--选择I2C模块的通道
 *      |__I2C0           --I2C通道0
 *      |__I2C1           --I2C通道1
 * 输出:
 *    无
*/
void LPLD_I2C_ReStart(I2C_Type *i2cx)
{
  i2cx->C1 |= I2C_C1_RSTA_MASK ;
}
 
/*
 * LPLD_I2C_Stop
 * 产生I2C停止信号
 * 
 * 参数:
 *    i2cx--选择I2C模块的通道
 *      |__I2C0           --I2C通道0
 *      |__I2C1           --I2C通道1
 * 输出:
 *    无
 */
void LPLD_I2C_Stop(I2C_Type *i2cx)
{
  i2cx->C1 &=(~I2C_C1_MST_MASK);
  i2cx->C1 &=(~I2C_C1_TX_MASK); 
}
 
/*
 * LPLD_I2C_WaitAck
 * I2C设置等待应答信号,开启则等待,关闭则不等待
 * 
 * 参数:
 *    i2cx--选择I2C模块的通道
 *      |__I2C0           --I2C通道0
 *      |__I2C1           --I2C通道1
 *    is_wait--选择是否等待应答
 *      |__I2C_ACK_OFF    --关闭等待Ack
 *      |__I2C_ACK_ON     --开启等待Ack,并等待ACK信号
 * 输出:
 *    无
 */
void LPLD_I2C_WaitAck(I2C_Type *i2cx, uint8 is_wait)
{
  uint16 time_out;
  if(is_wait == I2C_ACK_ON)
  {
    while(!(i2cx->S & I2C_S_IICIF_MASK))
    {
      if(time_out>60000) //如果等待超时,强行退出
        break;
      else time_out++;
    }
    i2cx->S |= I2C_S_IICIF_MASK;
  }
  else
  {
    //关闭I2C的ACK
    i2cx->C1 |= I2C_C1_TXAK_MASK; 
  }
}
 
/*
 * LPLD_I2C_Write
 * I2C发送一个字节给目的地址设备
 * 
 * 参数:
 *    i2cx--选择I2C模块的通道
 *      |__I2C0           --I2C通道0
 *      |__I2C1           --I2C通道1
 *    data8--要发送的字节数据
 * 输出:
 *    无
 *
 */
void LPLD_I2C_WriteByte(I2C_Type *i2cx, uint8 data8)
{
  i2cx->D = data8; 
}
 
/*
 * LPLD_I2C_Read
 * I2C从外部设备读一个字节
 * 
 * 参数:
 *    i2cx--选择I2C模块的通道
 *      |__I2C0           --I2C通道0
 *      |__I2C1           --I2C通道1
 * 输出:
 *    I2C读取的字节 
 */
 
uint8 LPLD_I2C_ReadByte(I2C_Type *i2cx)
{
  uint8 temp;
  temp = i2cx->D; 
  return temp;
}
 
/*
 * LPLD_I2C_SetMasterWR
 * I2C主机读写模式配置
 * 
 * 参数:
 *    IICx--选择I2C模块的通道
 *      |__I2C0           --I2C通道0
 *      |__I2C1           --I2C通道1
 *    mode--读写模式选择
 *      |__I2C_MWSR         --主机写
 *      |__I2C_MRSW         --主机读
 * 输出:
 *    无
 */
void LPLD_I2C_SetMasterWR(I2C_Type *i2cx, uint8 mode)
{
  if(mode==I2C_MRSW) 
    i2cx->C1 &= (~I2C_C1_TX_MASK);
  else
    i2cx->C1 |= ( I2C_C1_TX_MASK);
}
 
/*
 * LPLD_I2C_StartTrans
 * I2C开始传输函数,需要设置外围设备地址和读写模式
 * 
 * 参数:
 *    IICx--选择I2C模块的通道
 *      |__I2C0           --I2C通道0
 *      |__I2C1           --I2C通道1
 *    addr--外围设备地址     
 *    mode--读写模式选择
 *      |__I2C_MWSR         --主机写
 *      |__I2C_MRSW         --主机读
 * 输出:
 *    无
 */
void LPLD_I2C_StartTrans(I2C_Type *i2cx, uint8 addr, uint8 mode)
{
  //I2C产生start信号
  LPLD_I2C_Start(i2cx);
  //将从机地址和主机读写位合成一个字节写入
  LPLD_I2C_WriteByte(i2cx, (addrS & I2C_S_IICIF_MASK)
  {
    I2C_ISR[0]();
    if(I2C0->SMB & I2C_SMB_SLTF_MASK)
    {
      I2C0->SMB |= I2C_SMB_SLTF_MASK;
    }
    if(I2C0->SMB & I2C_SMB_SHTF2_MASK)
    {
      I2C0->SMB |= I2C_SMB_SHTF2_MASK;
    }
    if(I2C0->S & I2C_S_ARBL_MASK)
    {
      I2C0->S |= I2C_S_ARBL_MASK;
    }
    I2C0->S |= I2C_S_IICIF_MASK;
  }
#if (UCOS_II > 0u)
  OSIntExit();          //告知系统此时即将离开中断服务子函数
#endif
}
//HW层中断函数,用户无需调用
void I2C1_IRQHandler(void)
{
 
#if (UCOS_II > 0u)
  OS_CPU_SR  cpu_sr = 0u;
  OS_ENTER_CRITICAL(); //告知系统此时已经进入了中断服务子函数
  OSIntEnter();
  OS_EXIT_CRITICAL();
#endif
 
  if(I2C1->S & I2C_S_IICIF_MASK)
  {
    I2C_ISR[1]();
    if(I2C1->SMB & I2C_SMB_SLTF_MASK)
    {
      I2C1->SMB |= I2C_SMB_SLTF_MASK;
    }
    if(I2C1->SMB & I2C_SMB_SHTF2_MASK)
    {
      I2C1->SMB |= I2C_SMB_SHTF2_MASK;
    }
    if(I2C1->S & I2C_S_ARBL_MASK)
    {
      I2C1->S |= I2C_S_ARBL_MASK;
    }
    I2C1->S |= I2C_S_IICIF_MASK;
  }
  
#if (UCOS_II > 0u)
  OSIntExit();          //告知系统此时即将离开中断服务子函数
#endif
}
 
 
 
 
 
 
 
我知道答案 目前已有4人回答
回复

使用道具 举报

  • TA的每日心情
    开心
    2018-7-2 06:04
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    59

    主题

    2888

    帖子

    10

    金牌会员

    Rank: 6Rank: 6

    积分
    6020
    最后登录
    2020-9-28
    发表于 2013-12-30 17:02:56 | 显示全部楼层

    RE:K60 I2C使用疑问····求助啊·····快哭了

    没有用过这个库呢
    楼主你有试过飞思卡尔官网的例程吗?
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    0

    主题

    16

    帖子

    0

    新手上路

    Rank: 1

    积分
    16
    最后登录
    1970-1-1
    发表于 2014-1-3 19:11:39 | 显示全部楼层

    回复:K60 I2C使用疑问····求助啊·····快哭了

     楼主解决了吗 我也没读出来 8451可以 但是就是4200不行 
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    0

    主题

    16

    帖子

    0

    新手上路

    Rank: 1

    积分
    16
    最后登录
    1970-1-1
    发表于 2014-1-3 19:12:15 | 显示全部楼层

    回复:K60 I2C使用疑问····求助啊·····快哭了

    回复第 2 楼 于2013-12-30 17:02:56发表:
    没有用过这个库呢
    楼主你有试过飞思卡尔官网的例程吗?
    我也没读出来 8451可以 但是就是4200不行 


     
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    4

    主题

    92

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    285
    最后登录
    2022-4-14
    发表于 2014-1-8 15:27:46 | 显示全部楼层

    RE:K60 I2C使用疑问····求助啊·····快哭了

    请将SDA管脚配置为open drain输出试试看看。
    PortxPCR寄存器中ODE位。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2018-7-2 06:04
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    59

    主题

    2888

    帖子

    10

    金牌会员

    Rank: 6Rank: 6

    积分
    6020
    最后登录
    2020-9-28
    发表于 2014-1-10 15:40:24 | 显示全部楼层

    回复:K60 I2C使用疑问····求助啊·····快哭了

    回复第 4 楼 于2014-01-03 19:12:15发表:
    回复第 2 楼 于2013-12-30 17:02:56发表:
    没有用过这个库呢
    楼主你有试过飞思卡尔官网的例程吗?
    我也没读出来 8451可以 但是就是4200不行 


     

     

    有看过I2C波形吗?
    是哪位出错
     
    用官方例程也会出错?
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-7-18 18:30 , Processed in 0.096797 second(s), 26 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表