MMA690xKQ

 /*****************************************************************************
*
* (c) 2009 Freescale Inc.
* ALL RIGHTS RESERVED.
*
**************************************************************************//*!
*
* @file      mma6900.c
* @version   1.0.1.0
* @date      Jul-11-2011
* @author    B20253
*
* @brief     The device driver for accelerometer MMA6900
*  
*****************************************************************************/
#include "mma6900.h"
#include "spi.h"
#include "main.h"

static Byte MMA6900_enabled = FALSE;  //static 静态局部变量使用static修饰符定义,即使在声明时未赋初值,编译器也会把它初始化为0。
                                      //且静态局部变量存储于进程的全局数据区,即使函数返回,它的值也会保持不变。
                                      //其作用域为局部作用域,当定义它的函数结束时,其作用域随之结束

MMA6900_MAIN_STR mmaValues;
MMA6900_READ_REG_STR MMA6900_read;  
MMA6900_REG_STR regs_mma6900;

word cntResetDevres = 0;
static SPI_regs* actual_spi;

//  internal functions
void MMA6900_SetUp(byte reg_DEVCTL);
word MMA6900_RegAccessWordPrtcl2(byte);
word MMA6900_RegReadWordPrtcl2(void); //word 16位字节
word MMA6900_RegWriteWordPrtcl2(byte);
void MMA6900_Reset_DEVRES(void); //前面的void是说明函数是void类型即无返回值类型!后面的void是修饰符即说明main无参数传递
void MMA6900_ReadAllReg(void);

/***************************************************************************//*!
* @brief 
*
* @param   参数
*
* @return 
****************************************************************************/
void CopyToStructure6900(void)
{
 byte* ptr_tmp = (byte*)&MMA6900_read.Regtest;
 byte ix;

  for(ix=0; ix<REGISTERS; ix++)  //MMAD900H registers=26
  {
    if(ix != 0)
    {
      regs_mma6900.all_regs[ix] =*ptr_tmp;
      ptr_tmp += 2;
    }
  }
}

/***************************************************************************//*!
*
* @brief MMA6900 initialization  初始化
*
* @param  input  参数输入
*
* @return (nothing)
*
* @remarks call in main.c in initialization section  调用c初始化部分
*
****************************************************************************/
void MMA6900_Init(MODULES mod)
{
     (void)mod;

     if(mod == MODULE_A) 
     {
          SPI_Init((SPI_regs*)p_SPI1C1);
          actual_spi = (SPI_regs*)p_SPI1C1; 
     }
     else if(mod == MODULE_B) 
     {
          SPI_Init((SPI_regs*)p_SPI2C1);
          actual_spi = (SPI_regs*)p_SPI2C1; 
     }
 MMA6900_Reset_DEVRES();//重置
 MMA6900_ReadAllReg();  //读取寄存器
 MMA6900_SetUp(0x90);     
 MMA6900_enabled = TRUE;//启用
}

void MMA6900_DeInit(void)
{
  MMA6900_enabled = FALSE;
}

word MMA6900_DisplayRegister(word tmp) //使用寄存器
{
  MMA6900_READ_REG temp;
          
  temp.MergedBits.Status=tmp>>8;
  temp.MergedBits.Data=tmp&0x00FF;
         
  return (temp.word); 
}
           
           

/***************************************************************************//*!
* @brief 重置
*
* @param   
*
* @return 
****************************************************************************/
void MMA6900_Reset_DEVRES(void) 
{
  byte temp5L;
  word temp1,temp2,temp3,temp4,temp5,temp6,temp7,temp8,temp9;

  temp1=MMA6900_RegAccessWordPrtcl2(MMA6900_DEVSTAT);
  temp2=MMA6900_RegReadWordPrtcl2();   //16
  MMA6900_read.RegDEVSTAT.word = MMA6900_DisplayRegister(temp2);

  if(MMA6900_read.RegDEVSTAT.Bits.DEVRES==1) 
  {
    cntResetDevres++;
    temp3=MMA6900_RegAccessWordPrtcl2(MMA6900_DEVCTL);
    temp4=MMA6900_RegReadWordPrtcl2();   //16
    MMA6900_read.RegDEVCTL.word = MMA6900_DisplayRegister(temp4);
    temp5=(word)(temp4|0x0020);   //Set CE
    temp5L=(byte)(temp5&0x00FF);
    temp6=MMA6900_RegAccessWordPrtcl2(MMA6900_DEVCTL);
    temp7=MMA6900_RegWriteWordPrtcl2(temp5L);
    temp8=MMA6900_RegAccessWordPrtcl2(MMA6900_DEVSTAT);
    temp9=MMA6900_RegReadWordPrtcl2(); 
    MMA6900_read.RegDEVSTAT.word = MMA6900_DisplayRegister(temp9);           
  } 
}

/***************************************************************************//*!
* @brief 
*
* @param   
*
* @return 
****************************************************************************/
void MMA6900_ReadAllReg(void)
{
  REG_STR read_reg;
  word* ptr_reg = &read_reg.reg_SN0.reg_check;
  MMA6900_READ_REG* ptr_read = (MMA6900_READ_REG*)&MMA6900_read.Regtest;
  const byte reg_addres[REGISTERS] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27};
  byte index;        
  
  for(index=0; index<=REGISTERS; index++)
  {
    ptr_reg[index] = MMA6900_RegAccessWordPrtcl2(reg_addres[index]);
    ptr_reg[index+1] = MMA6900_RegReadWordPrtcl2();
    ptr_read[index].word = MMA6900_DisplayRegister(ptr_reg[index+1]);
  }
}

void MMA6900_WriteToRegister(byte tmp)
{
  MMA6900_SetUp(tmp);     
}



/***************************************************************************//*!
* @brief  读取原始数据
*
* @param   
*
* @return 
****************************************************************************/
Byte MMA6900_ReadRawData(TWR_MMA6900* mma6900)
{
  static byte last_write;
  Byte ix;

  if(MMA6900_enabled == FALSE)
  {
    mma6900->x = 0; 
    mma6900->y = 0;  

    for(ix=0; ix<MMA6900_REGS; ix++)
      mma6900->all_regs[ix] = 0;
     
    return 0;
  }

  MMA6900_ReadAllReg();
  CopyToStructure6900();   

  (void)MMA6900_RegAccessWordPrtcl2(MMA6900_ACC_X11L);
  MMA6900_read.RegACC_X11L.word = MMA6900_DisplayRegister(MMA6900_RegReadWordPrtcl2());
  mmaValues.x.bytes.Dgt11RegL = MMA6900_read.RegACC_X11L.MergedBits.Data;
         
  (void)MMA6900_RegAccessWordPrtcl2(MMA6900_ACC_X11H);
  MMA6900_read.RegACC_X11H.word = MMA6900_DisplayRegister(MMA6900_RegReadWordPrtcl2());
  mmaValues.x.bytes.Dgt11RegH = (MMA6900_read.RegACC_X11H.MergedBits.Data)&0x07; 

  (void)MMA6900_RegAccessWordPrtcl2(MMA6900_ACC_Y11L);     
  MMA6900_read.RegACC_Y11L.word = MMA6900_DisplayRegister(MMA6900_RegReadWordPrtcl2());
  mmaValues.y.bytes.Dgt11RegL = MMA6900_read.RegACC_Y11L.MergedBits.Data; 
          
  (void)MMA6900_RegAccessWordPrtcl2(MMA6900_ACC_Y11H);     
  MMA6900_read.RegACC_Y11H.word = MMA6900_DisplayRegister(MMA6900_RegReadWordPrtcl2());
  mmaValues.y.bytes.Dgt11RegH = (MMA6900_read.RegACC_Y11H.MergedBits.Data)&0x07;

  mma6900->x = mmaValues.x.words.Dgt11Reg; 
  mma6900->y = mmaValues.y.words.Dgt11Reg;  

  for(ix=0; ix<MMA6900_REGS; ix++)
    mma6900->all_regs[ix] = regs_mma6900.all_regs[ix];

  if(mma6900->w_regs != last_write)
    MMA6900_WriteToRegister(mma6900->w_regs);

  last_write = mma6900->w_regs;
}

/***************************************************************************//*!
* @brief   奇偶校验
*
* @param   
*
* @return 
****************************************************************************/
byte MMA6900_Parity(word data) 
{
  byte x = 0;

  do
  {
    if (data & 0x01) 
      x++;
  }while(data >>= 1);//它先执行循环体中的语句,然后再判断条件是否为真。
                     //如果为真则继续循环,如果为假,则终止循环。
                     //因此,do-while循环至少要执行一次循环语句。
  
  return (x&0x01 == 1) ? 0 : 1;   
}

/***************************************************************************//*!
* @brief  设置
*
* @param   
*
* @return 
****************************************************************************/
void MMA6900_SetUp(byte reg_DEVCTL) 
{
  (void)MMA6900_RegAccessWordPrtcl2(MMA6900_DEVCTL);
  (void)MMA6900_RegWriteWordPrtcl2(reg_DEVCTL);

  (void)MMA6900_RegAccessWordPrtcl2(MMA6900_DEVCTL);
  MMA6900_read.RegDEVCTL.word = MMA6900_DisplayRegister(MMA6900_RegReadWordPrtcl2());
}

/***************************************************************************//*!
* @brief 
*
* @param   
*
* @return 
****************************************************************************/
word MMA6900_RegAccessWordPrtcl2(byte RegAdd)                     
{
  byte tx_byte1,tx_byte2;
  byte rx_byte1,rx_byte2;
  word temp,rx_word;

  temp = 0x1000;    //Word created to compute parity  用来计算奇偶校验的
  temp|=RegAdd;               //Example: TEMP 0x0F

  if(MMA6900_Parity(temp)) temp|=0x0400;         //Parity added if required 如果需要奇偶校验
                                                  
  tx_byte1= (byte)(temp>>8);
  tx_byte2= (byte)(temp&0x00FF);

  SPI_Reset_SS(actual_spi); //SS2 = 0;

  SPI_SendByte(tx_byte1, actual_spi);
  rx_byte1=SPI_ReadByte(actual_spi);
  SPI_SendByte(tx_byte2, actual_spi);
  rx_byte2=SPI_ReadByte(actual_spi);

  SPI_Set_SS(actual_spi); // SS2 = 1;

  rx_word=rx_byte1<<8;
  rx_word|=rx_byte2;

  return(rx_word);
}

/***************************************************************************//*!
* @brief 
*
* @param   
*
* @return 
****************************************************************************/
word MMA6900_RegReadWordPrtcl2(void)                              
{
  byte tx_byte1,tx_byte2;
  byte rx_byte1,rx_byte2;
  word temp,rx_word;

  temp = 0x2000;  //Din   0x2000   (checked on scope  在检查范围)
                           
  tx_byte1= (byte)(temp>>8);
  tx_byte2= (byte)(temp&0x00FF);

  SPI_Reset_SS(actual_spi); //SS1=0;
  SPI_SendByte(tx_byte1, actual_spi);
  rx_byte1=SPI_ReadByte(actual_spi);
  SPI_SendByte(tx_byte2, actual_spi);
  rx_byte2=SPI_ReadByte(actual_spi);
  SPI_Set_SS(actual_spi);//SS1=1;

  rx_word = rx_byte1<<8;
  rx_word |= rx_byte2;

  return(rx_word);
}

/***************************************************************************//*!
* @brief 
*
* @param   
*
* @return 
****************************************************************************/
word MMA6900_RegWriteWordPrtcl2(byte val)                         
{
  byte p;
  byte tx_byte1,tx_byte2;
  byte rx_byte1,rx_byte2;
  word temp,rx_word;

  temp = 0x3000;   //Word created to compute parity
  temp|=val;
  p=MMA6900_Parity(temp);
  if(p) temp|=0x0400;        //Parity added if required

  tx_byte1= (byte)(temp>>8);
  tx_byte2= (byte)(temp&0x00FF);

  SPI_Reset_SS(actual_spi); // SS1=0;
  SPI_SendByte(tx_byte1, actual_spi);
  rx_byte1=SPI_ReadByte(actual_spi);
  SPI_SendByte(tx_byte2, actual_spi);
  rx_byte2=SPI_ReadByte(actual_spi);
  SPI_Set_SS(actual_spi);// SS1=1;

  rx_word=rx_byte1<<8;
  rx_word|=rx_byte2;

  return(rx_word);
}

/***************************************************************************//*!
* @brief  读取加速度数据X,Y
*
* @param   
*
* @return 
****************************************************************************/
word MMA6900_Read_AccPrtcl2(byte axis) 
{
  byte rx_byte1,rx_byte2;
  byte tx_byte1,tx_byte2;
  word temp,rx_word;

  if(axis==0x00) temp = 0x4000;    //Din  0x4000 seen on scope OK
  if(axis==0x01) temp = 0x8000;    //Din  0x8000 seen on scope OK 
  tx_byte1= (byte)(temp>>8);
  tx_byte2= (byte)(temp&0x00FF);

  SPI_Reset_SS(actual_spi);// SS1=0;
  SPI_SendByte(tx_byte1, actual_spi);
  rx_byte1=SPI_ReadByte(actual_spi);
  SPI_SendByte(tx_byte2, actual_spi);
  rx_byte2=SPI_ReadByte(actual_spi);
  SPI_Set_SS(actual_spi);// SS1=1;

  rx_word=rx_byte1<<8;
  rx_word|=rx_byte2;

  return(rx_word);
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值