在线时间0 小时
UID2056948
注册时间2013-11-14
NXP金币0
该用户从未签到
新手上路

- 积分
- 7
- 最后登录
- 1970-1-1
|
想用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-> CR[1] = PORT_PCR_MUX(2) | ode_mask;
}
else //sda_pin = PTB3
{
PORTB-> CR[3] = PORT_PCR_MUX(2) | ode_mask;
}
}
else if(i2cx == I2C1)
{
SIM->SCGC4 |= SIM_SCGC4_I2C1_MASK; //开启I2C1时钟
if(scl_pin == PTE1)
{
PORTE-> CR[1] = PORT_PCR_MUX(6) | ode_mask;
}
else //scl_pin = PTC10
{
PORTC-> CR[10] = PORT_PCR_MUX(2) | ode_mask;
}
if(sda_pin == PTE0)
{
PORTE-> CR[0] = PORT_PCR_MUX(6) | ode_mask;
}
else //sda_pin = PTC11
{
PORTC-> CR[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
}
|
|