|
写了个关于MMA7455的程序,看资料说第一次使用前要校正,校正之前要先测量原始数据,于是就去测量06、07、08三个寄存器的值,但是一直是255,而且把mma7455模块拔掉还是打印255,不知道是什么原因,求指导,求指导,求指导!!!
下面是测量原始数据的程序,求帮看,开发板是友善之臂的tiny4412
#define DEV_ADDR 0x3A
#define ACC_Gravity 9.8 /*重力加速度的值*/
#include
#include
#include
#include
int wait_until_iic_irq(I2C_REG_T *i2c);
void resume_iic_scl(I2C_REG_T *i2c);
void delay(int val);
int iic_write(unsigned char reg_addr, unsigned char data);
int __iic_write(unsigned char reg_addr, unsigned char data);
unsigned char read_data(unsigned char reg_addr);
//1st: i2c初始化
static inline void i2c0_init(void)
{
// mma7455 : i2csda0/i2cscl0(GPD1_0/ GPD1_1) eint18(GPX1_0)
GPD1CON &= ~0xff;
GPD1CON |= 0x22;
IIC0_reg->I2CCONn = (1<<7)|(1<<6)|(1<<5); //enable ack, 100MHz/512, enable T/R irq, 196KHz
IIC0_reg->I2CSTATn = 1<<4; //Enable Tx/Rx
}
void i2c_mma_test(MMA_Dat* MMA_Value)
{
// u8 temp;
/*设置mma为2g量程、测量模式*/
iic_write(MMA_MCTL_Addr,0x05);
printf("MMA_MCTL_ADDR = %X \n",MMA_MCTL_Addr);
/*DRDY标置位,等待测试完毕*/
while(!(read_data(MMA_STATUS_Addr)&0x01));
/*读取测得的数据*/
MMA_Value->Out = read_data(MMA_Value->Addr);
printf("%cOUT8 = %d \r\n",MMA_Value->Name,MMA_Value->Out);
delay(10000);
}
/*开始下次操作前,将状态位清0*/
void resume_iic_scl(I2C_REG_T *i2c)
{
i2c->I2CCONn &= ~(1<<4);
}
/*若在限定时间内发送完成,则I2CCONn的第5位置1*/
int wait_until_iic_irq(I2C_REG_T *i2c)
{
int i;
#define MAX_WAIT 0x3fff
for (i = 0; i < MAX_WAIT; i++)
{
if (i2c->I2CCONn & (1<<4))
return 0;
}
return -1;
}
int iic_write(unsigned char reg_addr, unsigned char data)
{
int ret;
ret = __iic_write(reg_addr, data);
if (ret < 0)
return __iic_write(reg_addr, data);
return 0;
}
/*主设备发,从设备收。写操作*/
int __iic_write(unsigned char reg_addr, unsigned char data)
{
int ret = -1;
/*写设备地址*/
IIC0_reg->I2CDSn = (DEV_ADDR<<1)|0; //master tx
IIC0_reg->I2CSTATn = 0xf0;
resume_iic_scl(IIC0_reg);
if (wait_until_iic_irq(IIC0_reg) < 0)//是否发送成功
goto END;
if (IIC0_reg->I2CSTATn & 1)//主机是否收到ACK应答
goto END;
/*写从机寄存器地址*/
IIC0_reg->I2CDSn = reg_addr;
resume_iic_scl(IIC0_reg);
if (wait_until_iic_irq(IIC0_reg) < 0)
goto END;
if (IIC0_reg->I2CSTATn & 1)//确认主机收到ACK
goto END;
/*写数据*/
IIC0_reg->I2CDSn = data;
resume_iic_scl(IIC0_reg);
if (wait_until_iic_irq(IIC0_reg) < 0)
goto END;
if (IIC0_reg->I2CSTATn & 1)
goto END;
ret = 0;
END: // stop signal
IIC0_reg->I2CSTATn = 0xd0;
resume_iic_scl(IIC0_reg);
delay(1000);
return ret;
}
/*读书据,主机发送模式,后接受模式*/
unsigned char read_data(unsigned char reg_addr)
{
unsigned char ret = -1;
/*写设备地址*/
IIC0_reg->I2CDSn = (DEV_ADDR<<1)|0; //master tx
IIC0_reg->I2CSTATn = 0xf0;
resume_iic_scl(IIC0_reg);
if (wait_until_iic_irq(IIC0_reg) < 0)
goto END;
if (IIC0_reg->I2CSTATn & 1)
goto END;
/*写从机寄存器地址(即准备从那个寄存器读数据)*/
IIC0_reg->I2CDSn = reg_addr;
resume_iic_scl(IIC0_reg);
if (wait_until_iic_irq(IIC0_reg) < 0)
goto END;
if (IIC0_reg->I2CSTATn & 1)
goto END;
/*读设备地址,读操作,*/
IIC0_reg->I2CDSn = (DEV_ADDR<<1)|1; //master rx
IIC0_reg->I2CSTATn = 0xb0;//主接受模式,占有总线,使能
resume_iic_scl(IIC0_reg);
if (wait_until_iic_irq(IIC0_reg) < 0)
goto END;
if (IIC0_reg->I2CSTATn & 1)
goto END;
/*读数据*/
resume_iic_scl(IIC0_reg);
if (wait_until_iic_irq(IIC0_reg) < 0)
goto END;
ret = IIC0_reg->I2CDSn;
END:
IIC0_reg->I2CSTATn = 0x90; // stop signal
resume_iic_scl(IIC0_reg);
delay(1000);
return ret;
}
void delay(int val)
{
val *= 66;
while (val--)
;
}
下面是主函数
#include
#include
MMA_Dat X_Value={MMA_XOUT8_Addr,'X'};
MMA_Dat Y_Value={MMA_YOUT8_Addr,'Y'};
MMA_Dat Z_Value={MMA_ZOUT8_Addr,'Z'};
int main(void)
{
build_vectors();
i2c0_init();
printf("start shake mma7455 ba!\n");
while(1)
{
i2c_mma_test(&X_Value);
i2c_mma_test(&Y_Value);
i2c_mma_test(&Z_Value);
}
return 0;
}
|
|