社区导航

 
查看: 2479|回复: 2

[求助] MMA7455校正问题?

[复制链接]

5

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2017-1-13 23:19:10 | 显示全部楼层 |阅读模式
写了个关于MMA7455的程序,看资料说第一次使用前要校正,校正之前要先测量原始数据,于是就去测量06、07、08三个寄存器的值,但是一直是255,而且把mma7455模块拔掉还是打印255,不知道是什么原因,求指导,求指导,求指导!!!

下面是测量原始数据的程序,求帮看,开发板是友善之臂的tiny4412


#define DEV_ADDR  0x3A
#define ACC_Gravity                         9.8   /*重力加速度的值*/

#include <iic.h>
#include <common.h>
#include <irq.h>
#include <mma7455.h>

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 <vectors.h>
#include <mma7455.h>


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;
}


此帖出自ARM技术论坛


回复

使用道具 举报

5

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

 楼主| 发表于 2017-1-14 11:11:02 | 显示全部楼层
顶啊,别沉啊,大神在哪里啊


回复

使用道具 举报

5

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

 楼主| 发表于 2017-1-14 13:37:52 | 显示全部楼层
为啥没人啊


回复

使用道具 举报

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

本版积分规则

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

Archiver|手机版|小黑屋|电子工程世界 ( 京ICP证 060456 )

GMT+8, 2018-12-18 23:02 , Processed in 0.121669 second(s), 16 queries , Gzip On, MemCache On.

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