CC2530采集重力加速度MMA7455的值

作者:卢老师,华清远见教育科技集团讲师。

在cc2530中没有IIC总线控制器,只能使用模拟的方式采集,在下面原理图中,重力加速度传感器是飞思卡尔的MMA7455L。

IIC的时钟接cc2530 的P0_5 ;数据线接 P0-7,在使用模拟方式时,数据线要随输入输出改变自己的IO方向。

原理图:

#define I2C_SCL P0_5// I2C Serial Clock
        #define I2C_SDA P0_7 // I2C Serial Data
        #define ADDR_MMA7455L_WR (0x1D << 1)
        #define ADDR_MMA7455L_RD (0x1D << 1)

首先对IO初始化,P0DIR=0XA0;//P0_5 out;p0_7 out

IIC启动:
        void I2C_start(void)
        {
                P0DIR|=0X80;//data out ;
                I2C_SDA=1;
                I2C_SCL=1;
                delay_us(6);
                I2C_SDA=0;
                delay_us(6);
                I2C_SCL=0;
                delay_us(6);
        }

IIc停止
        void I2C_stop(void)
        {
                P0DIR|=0X80;//data out ;
                I2C_SCL=0;
                I2C_SDA=0;
                delay_us(6);
                I2C_SCL=1;
                delay_us(6);
                I2C_SDA=1;
                delay_us(6);
                EA = 1 ;
        }

IIC等待应答
        unsigned char WaitAck(void)
        {
                unsigned interrtime =60000; //大值不就65536
                P0DIR |=0X80;//data out ;
                I2C_SDA=1;
                P0DIR |=(~0X80);// data int ;
                delay_us(60);
                I2C_SCL=1;delay_us(6);

                while(I2C_SDA)
                {
                        errtime--;
                        if(!errtime)
                        {
                                I2C_stop();
                                return(1);
                        }
                }
                delay_us(6);
                I2C_SCL = 0;
                return(1);
        }

IIC发送应答
        void I2C_sendAck(void) // ACK
        {
                P0DIR |=0X80;//data out ;
                I2C_SDA=0;delay_us(6);
                I2C_SCL=1;delay_us(6);
                I2C_SCL=0;delay_us(6);
                I2C_SDA=1;
        }

IIC发送一个字节
        void I2C_sendByte(unsigned char sdata) //发送数据字节格式
                {
                        unsigned char i = 8;
                        P0DIR |=0X80;//data out ;
                        while(i--)
                        {
                                I2C_SCL=0;
                                delay_us(60);
                                if((sdata& 0x80)==1)
                                {I2C_SDA =1;}
                                else
                                {I2C_SDA =0;}
                                sdata=sdata<<1;
                                delay_us(6);
                                I2C_SCL=1;
                                delay_us(6);
                        }
                I2C_SCL=0;
        }

IIC接受一个字节
        unsigned char I2C_receiveByte(void) //接受数据
        {
                unsigned char i = 8;
                unsigned char rdata = 0;
                P0DIR |=(~0X80);// data int ;
                while(i--)
                {
                        rdata=rdata<<1;

                        I2C_SCL=0; delay_us(6);

                        I2C_SCL=1; delay_us(6);

                        rdata |= I2C_SDA;
                        delay_us(6);
                }
                I2C_SCL=0;
                delay_us(6);
                return(rdata);
        }

IIC发送数据包
        voidwrite_block(unsigned char address,unsigned char wdata)
        {
                I2C_start();
                I2C_sendByte(ADDR_MMA7455L_WR);
                while(!WaitAck());
                I2C_sendByte(address);
                while(!WaitAck());
                I2C_stop();
        }

//读外部数据//
        signed char read_block(unsigned char address)
        {
                signed char j;
                I2C_start();
                I2C_sendByte(ADDR_MMA7455L_WR);
                while(!WaitAck());
                I2C_sendByte(address);
                while(!WaitAck());
                I2C_start();
                I2C_sendByte(ADDR_MMA7455L_RD|0x01);
                while(!WaitAck());
                j= I2C_receiveByte();

                delay_us(5);
                I2C_stop();
                return j;
        }

读取MMA7455L x轴,y轴,z轴的值;
        voidacc_read (int8_t *x, int8_t *y, int8_t *z)
        {
                charbuf[1];
                while ((getStatus() & ACC_STATUS_DRDY) == 0);
                buf[0] = read_block(ACC_ADDR_XOUT8);
                *x = (char)buf[0];
                buf[0] = read_block(ACC_ADDR_YOUT8);
                *y = (char)buf[0];
                buf[0] = read_block(ACC_ADDR_ZOUT8);
                *z = (char)buf[0];
        }

MMA7455L测试程序;
        void Axis3_Test(void)
        {
                I2CInit();
                acc_init();
                // Assume base board in zero-g position when reading first value.
                acc_read(&x, &y, &z);
                xoff = 0-x;
                yoff = 0-y;
                zoff = 0-z;
                {
                        acc_read(&x, &y, &z);
                        x = x+xoff;
                        y = y+yoff;
                        z = z+zoff;
                }
        }

主程序将采集的值通过串口打印出来
        void main(void) {
                CLKCONCMD &= ~0x40; //设置系统时钟源为32MHZ晶振
                while(CLKCONSTA & 0x40); //等待晶振稳定为32M
                CLKCONCMD &= ~0x47; //设置系统主时钟频率为32MHZ
                IO_Init();
                InitUART();
                I2CInit();
                write_block(0x16,0x05);
                while(1)
                {
                        Axis3_Test();
                        Txdata[0]=x;
                        Txdata[1]=0;
                        Txdata[2]=y;
                        Txdata[3]=0;
                        Txdata[4]=z;
                        Txdata[5]=0;
                        UartSend_String(Txdata,7); //串口发送数
                        Delay_ms(500); //延时
                        LED1=!LED1; //标志发送状态
                }
        }

旋转重力加速模块,,打印结果如下图: