zoukankan      html  css  js  c++  java
  • 智能车学习(十)——MMA8451加速度计的使用

    一、驱动说明:

         就是使用I2C的通信方式驱动这款加速度计就行了,代码的话选择使用51单片机的代码进行移植。

    二、代码分享:

    1、头文件:

    #ifndef MMA8451_H
    #define MMA8451_H
    
    
    /***********函数声明***********/
    
    void MMA8451_Init(void);
    void Read_Gray(void);
    
    /*****************************/
    
    
    /***********全局变量声明***********/
    extern int delay_time;
    
    extern double Gray_X ;
    extern double Gray_Y ;
    extern double Gray_Z ;
    
    /*****************************/
    
    
    #endif

    2、源文件:

    #include "include.h"
    #include "common.h"
    #include "i2c.h"
    #include "MMA8451.h"
    #include "port.h"
    #include "gpio.h"
    #include "lptmr.h"
    
    double Gray_X ;
    double Gray_Y ;
    double Gray_Z ;
    
    //管脚定义
    #define MMA_S_I2C_SDA       (PTA16)//(PTB3)//(PTE0) //(PTE22)//(PTC1)//                     
    #define MMA_S_I2C_SCL       (PTA14)//(PTB2)//(PTE1)//(PTE20)//(PTC0)//    
    
    //IO方向设置
    #define MMA_I2C_SDA_IN()   DDRA16 = 0//输入模式
    #define MMA_I2C_SDA_OUT()  DDRA16 = 1//输出模式
    
    
    //IO操作函数     
    #define MMA_I2C_SCL        PTA14_OUT //SCL
    #define MMA_I2C_SDA        PTA16_OUT //SDA     
    #define MMA_I2C_READ_SDA   PTA16_IN  //输入SDA 
    
    //**********MMA8451内部寄存器地址*********
    #define WHO_AM_I    0x0D
    #define CTRL_REG1   0x2A
    #define CTRL_REG2   0x2B
    #define CTRL_REG3   0x2C
    #define CTRL_REG4   0x2D
    #define CTRL_REG5   0x2E
    //#define REFERENCE 0x25
    //#define OUT_TEMP 0x26
    #define STATUS_REG 0x00
    #define OUT_X_H      0x01
    #define OUT_X_L      0x02
    #define OUT_Y_H      0x03
    #define OUT_Y_L      0x04
    #define OUT_Z_H      0x05
    #define OUT_Z_L      0x06
    #define XYZ_DATA_CFG 0x0E
    
    #define    SlaveAddress   0x38      //定义器件在I2C总线中的从地址,根据ALT  ADDRESS地址引脚不同修改
    #define    SlaveAddfire   0x69      //定义器件在I2C总线中的从地址,根据ALT  ADDRESS地址引脚不同修改
    
    
    //============================================================================
    //函数名称:void MMA_I2C_Config(__RAMFUNC  void)
    //函数返回:无
    //参数说明:无
    //功能概要:初始化I2C
    //============================================================================
    void MMA_I2C_Config(void)
    {
      //MMA_I2C_SDA_OUT();
      gpio_init(MMA_S_I2C_SDA,GPO,1);
      gpio_init(MMA_S_I2C_SCL,GPO,1);
      
      MMA_I2C_SCL=1;
      MMA_I2C_SDA=1;
    }
    
    
    //============================================================================
    //函数名称:void MMA_I2C_Start(__RAMFUNC  void)
    //函数返回:无
    //参数说明:无
    //功能概要:I2C通信开始
    //============================================================================
    void MMA_I2C_Start(void)
    {
      MMA_I2C_SDA_OUT();
      
      MMA_I2C_SDA = 1;
      MMA_I2C_SCL = 1;
      lptmr_delay_us(1);
      
      MMA_I2C_SDA = 0;      
      lptmr_delay_us(1);
      MMA_I2C_SCL = 0;   
    }
    
    //============================================================================
    //函数名称:void MMA_I2C_Stop(void)
    //函数返回:无
    //参数说明:无
    //功能概要:I2C通信结束
    //============================================================================
    void MMA_I2C_Stop(void)
    {
      MMA_I2C_SDA_OUT();
      MMA_I2C_SDA = 0;
      MMA_I2C_SCL = 1;
      
      lptmr_delay_us(1);                       
      MMA_I2C_SDA = 1;
      lptmr_delay_us(1);                                           
      MMA_I2C_SCL = 0;
    }
    
    
    
    void MMA_I2C_Mack(void)
    { 
      MMA_I2C_SDA_OUT();
      
      MMA_I2C_SDA=0;
      MMA_I2C_SCL=1;
      
      lptmr_delay_us(1); 
      
      MMA_I2C_SCL=0;
      MMA_I2C_SDA=1;
    }
    
    void MMA_I2C_Mnack(void)
    {
      MMA_I2C_SDA_OUT();
      MMA_I2C_SDA=1;    
      lptmr_delay_us(1); 
      MMA_I2C_SCL=1;
      lptmr_delay_us(1); 
      MMA_I2C_SCL=0;
      lptmr_delay_us(1); 
      //MMA_I2C_SDA=0;
    }
    
    uint8_t MMA_I2C_Cack(void)
    {  
      MMA_I2C_SDA_IN();;
      MMA_I2C_SCL=0;
      lptmr_delay_us(1); 
      MMA_I2C_SCL=1;
      lptmr_delay_us(1); 
      
      if(MMA_I2C_READ_SDA)
      {
        //MMA_I2C_Stop();
        //return 0xff;
      }
      
      MMA_I2C_SCL=0;              
      MMA_I2C_SDA_OUT();  
      return 0;  
    }
    
    void MMA_I2C_WriteByte(unsigned char data)
    {
      unsigned char i=8;
      MMA_I2C_SDA_OUT();
      
      while(i--)
      {
        lptmr_delay_us(1); 
        if(data & 0x80)  
          MMA_I2C_SDA=1;
        else
          MMA_I2C_SDA=0;
        
        lptmr_delay_us(1); 
        MMA_I2C_SCL=1; 
        lptmr_delay_us(1);  
        MMA_I2C_SCL=0;         
        data<<=1;            
      }
    }
    
    uint8_t MMA_I2C_ReadByte(void)
    {
      unsigned char i;
      unsigned char data=0;
      char temp;         
      
      MMA_I2C_SDA_IN();      
      
      for(i=0;i<8;i++)            
      {  
        data<<=1;
        lptmr_delay_us(1); 
        MMA_I2C_SCL = 1; 
        temp = MMA_I2C_READ_SDA;
        if(temp)
          data++;
        lptmr_delay_us(1);   
        MMA_I2C_SCL = 0;            
      }
      return data;
    }
    
    uint8_t MMA_I2C_WR_REG(uint8_t dev_addr, uint8_t reg_addr, uint8_t writeData)
    {
      MMA_I2C_Start(); 
      MMA_I2C_WriteByte(dev_addr); 
      MMA_I2C_Cack();
      MMA_I2C_WriteByte(reg_addr);
      MMA_I2C_Cack();
      MMA_I2C_WriteByte(writeData);
      
      MMA_I2C_Cack();
      MMA_I2C_Stop();
      
      return 0;
    }
    
    uint8_t MMA_I2C_RD_REG(uint8_t dev_addr, uint8_t reg_addr)
    {
      uint8_t read_reg = 0;
      MMA_I2C_Start();
      MMA_I2C_WriteByte(dev_addr);
      MMA_I2C_Cack();
      MMA_I2C_WriteByte(reg_addr);
      MMA_I2C_Cack();
      MMA_I2C_Start();
      MMA_I2C_WriteByte(dev_addr + 1);
      MMA_I2C_Cack();
      read_reg=MMA_I2C_ReadByte();
      MMA_I2C_Mnack();
      MMA_I2C_Stop();
      
      return read_reg;
    }
    
    uint8_t MMA_I2C_RD_Buffer(uint8_t dev_addr, uint8_t reg_addr, uint8_t data_num, uint8_t *readBuffer)
    {
      uint8_t i = 0;
      MMA_I2C_Start();
      MMA_I2C_WriteByte(dev_addr);
      MMA_I2C_Cack();
      MMA_I2C_WriteByte(reg_addr);
      MMA_I2C_Cack();
      MMA_I2C_Start();
      MMA_I2C_WriteByte(dev_addr + 1);
      MMA_I2C_Cack();
      
      for(i = 0; i < data_num; i++){
        *(readBuffer+i) = MMA_I2C_ReadByte();
        if(i == data_num - 1)
          MMA_I2C_Mnack();
        else
          MMA_I2C_Mack();
      }
      MMA_I2C_Stop();
      
      return 0;
    }
    
    
    
    
    
    /*----------------*加速度传感器初始化*----------------*/
    void MMA8451_Init(void)//初始化为指定模式 
    {    
      MMA_I2C_Config();
      MMA_I2C_WR_REG(SlaveAddress,CTRL_REG1,0x05);           //数据手册30  0xbf 400hz 20~110截止频率
      MMA_I2C_WR_REG(SlaveAddress,CTRL_REG2,0x02);        //前两位00,后两位高通滤波器模式选择,后四位截止频率  0x29
      MMA_I2C_WR_REG(SlaveAddress,XYZ_DATA_CFG,0x10);      
    }
    
    
    /*-------------*加速度传感器测量值读取接口*------------*/
    uint8_t MMA_tmpBuffer[6] = {0};
    
    
    void Read_Gray(void)
    {
      MMA_I2C_RD_Buffer(SlaveAddress,0x81,6,MMA_tmpBuffer);
      
      int temp;
      
      temp = ((short)((MMA_tmpBuffer[0]<<8)|MMA_tmpBuffer[1]))>>4;//2;// 14位精度  1g数值为1024(原本为4096,但是右移了(无效位2位)(有效位14位)两位)
      Gray_X = (double)Gray_X*0.5+(double)temp*0.5;
      
      temp = ((short)((MMA_tmpBuffer[2]<<8)|MMA_tmpBuffer[3]))>>4;//2;// 14位精度
      Gray_Y = (double)Gray_Y*0.5+(double)temp*0.5;
      
      temp = ((short)((MMA_tmpBuffer[4]<<8)|MMA_tmpBuffer[5]))>>4;//2;// 14位精度   
      Gray_Z = (double)Gray_Z*0.5+(double)temp*0.5;
    }
    
    /*--------------------------------------------------------------------------------------
    1.如何确定加速度计或者陀螺仪的IIC通信控制字,理解握手原理,掌握寻址的方法
    2.软件调试,结合管脚图
    3.数据通信速度匹配问题---如何确定延时的大小
    ----------------------------------------------------------------------------------------*/

    三、使用方法:

    #include "include.h"
    #include "OLED.h"
    #include "init.h"
    #include "KeySquare.h"
    #include "lptmr.h"
    #include "Menu.h"
    #include "flash.h"
    #include "MMA8451.h"
    
    void main()
    {
        DISABLE_INTERRUPTS;                          //MPU上电,各模块功能初始化前需要关中断
        system_init();                               //各模块功能初始化
        ENABLE_INTERRUPTS;                           //开中断使能
    
        
        //加速度计初始化
        MMA8451_Init();
        
        //初始化
        OLED_Init();  
        flash_init();
        
        //屏幕刷屏
        OLED_Clear();
        
    
        
       
        
        while(1)
        {
           Read_Gray();
           OLED_Clear();
           OLED_Write_Float(0,0,Gray_X);
           OLED_Write_Float(2,0,Gray_Y);
           OLED_Write_Float(4,0,Gray_Z);
           lptmr_delay_ms(100);
           
           
          //Menu_Key_Detect();
        }
    }
  • 相关阅读:
    .Net 第三方控件(转)
    DevExpress控件之GridControl控件
    sql语句linq语言lambda表达式对照
    匿名方法和Lambda表达式
    LINQ To ADO.Net中几个方法(1)
    const与readonly的区别
    InvokeRequired 属性 与Invoke方法
    DevExpress控件使用
    VC菜单操作
    VC获取各类指针
  • 原文地址:https://www.cnblogs.com/BlueMountain-HaggenDazs/p/4918453.html
Copyright © 2011-2022 走看看