OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 9643|回复: 11

基于STM32的MMA7660驱动程序

[复制链接]

2

主题

10

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2013-7-25
在线时间
0 小时
发表于 2013-7-25 17:02:45 | 显示全部楼层 |阅读模式

    那位大侠有这个得驱动程序啊,麻烦发一下,非常感谢!xie__chong@126.com
可以参考这个程序。
   
#ifndef _MMA7660_H_
#define _MMA7660_H_
// LCD 硬件定义
#define MM_INT   GPIO_Pin_14  // A14
#define MM_SCL   GPIO_Pin_15  // A15
#define MM_SDA   GPIO_Pin_10  // C10

/*
 **********************************************************
 *
 * 相关宏定义
 *
 **********************************************************
 */
//==========模拟IIC==================//
#define MMA_ERROR   0
#define MMA_OK    1
#define I2C_NOACK   0
#define I2C_ACK    1
#define MMA7660_SDA   GPIO_Pin_10  // C10 //IIC数据线接口
#define MMA7660_SCL   GPIO_Pin_15  // A15 //IIC时钟线接口
#define MMA7660_INT   GPIO_Pin_14  // A14

#define MMA7660_INT_D GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_14) //PC14读数据

#define MMA7660_SDA_D GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_10) //PC10读数据
#define MMA7660_SDA_H   GPIO_SetBits(GPIOC, GPIO_Pin_10)  // PC10 高电平
#define MMA7660_SDA_L   GPIO_ResetBits(GPIOC, GPIO_Pin_10)  // PC10 低电平
      
#define MMA7660_SCL_H   GPIO_SetBits(GPIOA, GPIO_Pin_15)  // PC8 高电平
#define MMA7660_SCL_L   GPIO_ResetBits(GPIOA, GPIO_Pin_15)  // PC8 低电平

//==========MMA7660 寄存器地址==================//
#define MMA7660_XOUT  0x00   // 6-bit output value X
#define MMA7660_YOUT  0x01   // 6-bit output value Y
#define MMA7660_ZOUT  0x02   // 6-bit output value Z
#define MMA7660_TILT  0x03   // Tilt Status
#define MMA7660_SRST  0x04   // Sampling Rate Status
#define MMA7660_SPCNT 0x05   // Sleep Count
#define MMA7660_INTSU 0x06   // Interrupt Setup
#define MMA7660_MODE  0x07   // Mode
#define MMA7660_SR    0x08   // Auto-Wake/Sleep and
                         // Portrait/Landscape samples
                         // per seconds and Debounce Filter
#define MMA7660_PDET  0x09   // Tap Detection
#define MMA7660_PD    0x0A   // Tap Debounce Count
//=========MMA7660 功能参数==================//
#define MMA7660_DEV_ADDR   0x4C //Normally,can range 0x08 to 0xEF
#define MMA7660_DEV_WRITE  MMA7660_DEV_ADDR<<1 | 0x00
#define MMA7660_DEV_READ   MMA7660_DEV_ADDR<<1 | 0x01

/*
 **********************************************************
 *
 * 全局函数声明
 *
 **********************************************************
 */
void MMA7660_Init(void);        //SCL,INT端口输出配置
void MMA_SDA_IOOUT(void);        //SDA端口配置为输出
void MMA_SDA_IOIN(void);        //SDA端口配置为输入
void I2C_Start(void);         //开始信号
void I2C_Stop(void);         //结束信号
unsigned char I2C_SlaveAck(void);      //应答信号
void I2C_WriteByte(unsigned char a);     //写一字节
unsigned char I2C_ReadByte(void);      //读一字节
void MMA7660_WriteReg(unsigned char Regs_Addr,unsigned char Regs_Data); //写寄存器
unsigned char MMA7660_ReadReg(unsigned char Regs_Addr); //读寄存器
unsigned char MMA7660_GetResult(unsigned char Regs_Addr); //读加速度
void MMA7660_Begin(void);          //开始传送前的寄存器值设置
/*
 **********************************************************
 *
 * 全局定义
 *
 **********************************************************
 */

#endif



#include "stm32f10x.h"
#include "mma7660.h"
#include "delay.h"

/*
 **********************************************************
 *
 * IIC总线模拟程序
 *
 **********************************************************
 */

/*
 *=========================================================
 * 函数功能:MMA7660端口状态配置
 * 参数:  无
 *      
 * 函数返回值:无  
 *=========================================================  
 */
void MMA7660_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  //RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC, ENABLE);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14 ;   
  GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_IN_FLOATING;   // 浮空输入
  //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    // 最高输出速率50MHz
  GPIO_Init(GPIOA, &GPIO_InitStructure);      // 选择A端口

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15 ;   
  GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_Out_PP;     // 推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    // 最高输出速率50MHz
  GPIO_Init(GPIOA, &GPIO_InitStructure);      // 选择A端口

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 ;   
  GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_Out_OD;     // 开漏输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    // 最高输出速率50MHz
  GPIO_Init(GPIOC, &GPIO_InitStructure);      // 选择C端口
}
void MMA_SDA_IOOUT(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  //RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 ;   
  GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_Out_OD;     // 开漏输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    // 最高输出速率50MHz
  GPIO_Init(GPIOC, &GPIO_InitStructure);      // 选择C端口

}

void MMA_SDA_IOIN(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  //RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 ;   
  GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_IN_FLOATING;   // 浮空输入
  //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    // 最高输出速率50MHz
  GPIO_Init(GPIOC, &GPIO_InitStructure);      // 选择C端口

}
/*
 *=========================================================
 * 函数功能:IIC总线初始化信号
 * 参数:无
 * 函数返回值:无
 * SDA    ---
 *           |________
 * SCL ----------
 *               |____ 
 *=========================================================  
 */
void I2C_Start(void)
{
  MMA7660_SCL_H;
  MMA7660_SDA_H;
  Delayus(1);
  MMA7660_SDA_L;
  Delayus(1); 
}

/*
 *=========================================================
 * 函数功能:IIC总线停止信号
 * 参数:无
 * 函数返回值:无
 * SDA        ---------
 *      ______|
 * SCL   ---------
 *                |___
 *=========================================================  
 */
void I2C_Stop(void)
{
  MMA7660_SCL_H;
  MMA7660_SDA_L;
  Delayus(1);
  MMA7660_SDA_H;
  Delayus(1);
}
/*
 *=========================================================
 * 函数功能:接收由从机向主机发起的ACK信号。
 * 参数:  ACKBIT
 *         
 * 函数返回值:MMA_ERROR/MMA_OK  
 *=========================================================  
 */
unsigned char I2C_SlaveAck(void)
{
  unsigned char ts=0;
  MMA7660_SCL_L;
  MMA7660_SDA_H;
 
  MMA_SDA_IOIN();     //SDA设为输入
  Delayus(1);
  MMA7660_SCL_H;
 
  while(MMA7660_SDA_D!=0)
  {
   ts++;
 if(ts>200)
 {
  MMA_SDA_IOOUT();   //SDA设为输出
  MMA7660_SCL_L;
  return MMA_ERROR;   //返回错误 
 }
  }
  MMA7660_SCL_L;
  MMA_SDA_IOOUT();     //SDA设为输出
  //MMA7660_SDA_H;
  Delayus(1);
  return MMA_OK;     //返回错误  
}

/*
 *=========================================================
 * 函数功能:IIC写一个字节数据
 * 参数:   a:需要写入的一个字节数据
 * 函数返回值:无
 *=========================================================  
 */
void I2C_WriteByte(unsigned char a)
{
 unsigned char i;
 for(i=0; i<8; i++)
 {    
     MMA7660_SCL_L;
  if((a&0x80)!=0) MMA7660_SDA_H;
     else MMA7660_SDA_L;
     a <<= 1;
  Delayus(1);
  MMA7660_SCL_H;
     Delayus(1);
 }  
   MMA7660_SCL_L; 
   if(I2C_SlaveAck()==MMA_ERROR)  //等待从机的ACK信号。
   {
   return ;
   }
}

/*
 *=========================================================
 * 函数功能:IIC读一个字节数据
 * 参数:无
 * 函数返回值:返回读出的一个字节数据
 *=========================================================  
 */
unsigned char I2C_ReadByte(void)
{
 unsigned char a =0;
 unsigned char i;
 MMA_SDA_IOIN();     //SDA设为输入 
 for(i=0; i<8; i++)
 {
   a <<= 1; 
  MMA7660_SCL_H;
  Delayus(1);
  if(MMA7660_SDA_D==1) a |= 0x01;
  Delayus(1);
  MMA7660_SCL_L;
    Delayus(2);   
 }
 return a;
}

/*
 **********************************************************
 *
 * MMA7660相关函数
 *
 **********************************************************
 */
/*
 *=========================================================
 * 函数功能:写MAA7660寄存器
 * 参数:    
 *       Regs_Addr - 寄存器地址
 *       Regs_Data - 寄存器值
 * 函数返回值:
 *=========================================================  
 */
void MMA7660_WriteReg(unsigned char Regs_Addr,unsigned char Regs_Data)

   I2C_Start();
   I2C_WriteByte(MMA7660_DEV_WRITE);  //先写Slave地址,并配置成写模式
   I2C_WriteByte(Regs_Addr);      //写寄存器地址
   I2C_WriteByte(Regs_Data);      //写寄存器内容
   I2C_Stop();                    //结束本段IIC进程
}

/*
 *=========================================================
 * 函数功能:读MAA7660单字节
 * 参数?
 *       Regs_Addr - 寄存器地址
 * 函数返回值:寄存器值
 *=========================================================  
 */
unsigned char MMA7660_ReadReg(unsigned char Regs_Addr)
{
   unsigned char ret;
  
   I2C_Start();
  
   I2C_WriteByte(MMA7660_DEV_WRITE);  //先写Slave地址,并配置成写模式
   I2C_WriteByte(Regs_Addr);      //写寄存器地址
  
   I2C_Start();
   I2C_WriteByte(MMA7660_DEV_READ);   //写Slave地址,并配置成读模式
   ret=I2C_ReadByte();     //从传感器中读出数据
   I2C_SlaveAck();
   I2C_Stop();                    //结束本段IIC进程
  
   return ret;

}

/*
 *=========================================================
 * 函数功能:读MAA7660加速度输出
 * 参数?  :
 *       Regs_Addr - 加速度寄存器地址
 * 函数返回值:加速度值
 *=========================================================  
 */
unsigned char MMA7660_GetResult(unsigned char Regs_Addr)
{
   unsigned char ret;
   // 等待转换完成并取出值  
   ret=MMA7660_ReadReg(Regs_Addr);
   while(ret&0x40)
   {
     ret=MMA7660_ReadReg(Regs_Addr);      //数据更新,重新读
   }
 
   return ret;

}
/*
 *=========================================================
 * 函数功能:MAA7660开始前的设置
 * 参数?  :
 *      
 * 函数返回值:无
 *=========================================================  
 */
void MMA7660_Begin(void)
{
 MMA7660_WriteReg(MMA7660_MODE,0X00);   //standby mode
 MMA7660_WriteReg(MMA7660_SPCNT,0X00);   //No Sleep Count
 MMA7660_WriteReg(MMA7660_INTSU,0X03);   //Configure GINT Interrupt
 MMA7660_WriteReg(MMA7660_PDET,0XE0);   //No tap detection enabled
 MMA7660_WriteReg(MMA7660_SR,0X34);    //8 samples/s,TILT debounce filter=2
 MMA7660_WriteReg(MMA7660_PD,0X00);    //No tap detection debounce count enabled
 MMA7660_WriteReg(MMA7660_MODE,0X41);   //Active Mode,INT= push-pull and active low 
}

 

 




 

mma7660.c

7.31 KB, 下载次数: 81

mma7660.h

2.98 KB, 下载次数: 75

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

27

主题

774

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1473
金钱
1473
注册时间
2013-4-12
在线时间
77 小时
发表于 2013-7-25 18:41:03 | 显示全部楼层
简单是多么的快乐,而快乐就因你而简单!微芯动力LTKKS
回复 支持 反对

使用道具 举报

2

主题

10

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2013-7-25
在线时间
0 小时
 楼主| 发表于 2013-7-25 19:42:52 | 显示全部楼层
回复【2楼】LTKKS:
---------------------------------
就是写一个STM32的程序,可以让MMA7660三轴加速传感器工作,上面的程序有问题,需要帮忙啊!
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165352
金钱
165352
注册时间
2010-12-1
在线时间
2108 小时
发表于 2013-7-25 20:37:48 | 显示全部楼层
以前写过,不过代码不见了.呵呵.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

27

主题

774

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1473
金钱
1473
注册时间
2013-4-12
在线时间
77 小时
发表于 2013-7-25 21:18:03 | 显示全部楼层
回复【3楼】xiechong:
---------------------------------
读数不对吗?
简单是多么的快乐,而快乐就因你而简单!微芯动力LTKKS
回复 支持 反对

使用道具 举报

2

主题

10

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2013-7-25
在线时间
0 小时
 楼主| 发表于 2013-7-26 10:04:08 | 显示全部楼层
回复【5楼】LTKKS:
---------------------------------
它根本就读不出来数,下面是主函数,到底哪错了,跪求解决啊!
void Adxl_Show_Num(u16 x,u16 y,short num,u8 mode)
{
if(mode==0)
{
if(num<0)
{
LCD_ShowChar(x,y,'-',16,0);
num=-num;
}else LCD_ShowChar(x,y,' ',16,0);
LCD_ShowNum(x+8,y,num,4,16);     
  }else 
{
if(num<0)
{
LCD_ShowChar(x,y,'-',16,0);
num=-num;


}else LCD_ShowChar(x,y,' ',16,0);
  LCD_ShowNum(x+8,y,num/10,2,16);     
LCD_ShowChar(x+24,y,'.',16,0);
LCD_ShowNum(x+32,y,num%10,1,16);      
}
}


int main(void)
{
unsigned char x,y,z;
             delay_init();  
NVIC_Configuration(); 
uart_init(9600);       
LCD_Init();
POINT_COLOR=RED;
LCD_Init();
             MMA7660_Init();
             MMA7660_Begin();
while(1)
{
 x=MMA7660_GetResult(MMA7660_XOUT);
 y=MMA7660_GetResult(MMA7660_YOUT);
 z=MMA7660_GetResult(MMA7660_ZOUT);
   LCD_ShowString(60,170,200,16,16,"X VAL:");
 LCD_ShowString(60,190,200,16,16,"Y VAL:");
 LCD_ShowString(60,210,200,16,16,"Z VAL:");
 Adxl_Show_Num(60+48,170,x,0);
 Adxl_Show_Num(60+48,190,y,0);
 Adxl_Show_Num(60+48,210,z,0);
}
}
回复 支持 反对

使用道具 举报

2

主题

10

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2013-7-25
在线时间
0 小时
 楼主| 发表于 2013-7-26 10:07:56 | 显示全部楼层
回复【4楼】正点原子:
---------------------------------
原子哥,你得帮我啊,我是看着你战舰板子上adxl345写的程序,我都郁闷死了
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165352
金钱
165352
注册时间
2010-12-1
在线时间
2108 小时
发表于 2013-7-26 10:22:36 | 显示全部楼层
先读ID之类的寄存器吧.
其他的什么都放后考虑.IIC通信得正常先.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

2

主题

10

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2013-7-25
在线时间
0 小时
 楼主| 发表于 2013-7-26 11:34:21 | 显示全部楼层
回复【8楼】正点原子:
---------------------------------
原子哥,我把你写的adxl345的程序里的初始化函数改成了

void ADXL345_Init(void)
{   
  IIC_Init();  
ADXL345_WR_Reg(MMA7660_MODE,0X00);
ADXL345_WR_Reg(MMA7660_SPCNT,0X00);
ADXL345_WR_Reg(MMA7660_INTSU,0X03);    
ADXL345_WR_Reg(MMA7660_PDET,0XE0);  
  ADXL345_WR_Reg(MMA7660_SR,0X34);
ADXL345_WR_Reg(MMA7660_PD,0X00);
ADXL345_WR_Reg(MMA7660_MODE,0X41);       

 对三轴急速器的读指令和写指令改为了
#define ADXL_READ    0X4C
#define ADXL_WRITE   0X4C
其他的都没有变,能读出MMA7660的数据了,但是只读出一个数据,而且永远不变,
那个读MMA7660 ID的指令我没找到,读不出来ID.
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165352
金钱
165352
注册时间
2010-12-1
在线时间
2108 小时
发表于 2013-7-26 17:20:16 | 显示全部楼层
回复【9楼】xiechong:
---------------------------------
MMA的初始化和ADXL不一样吧???
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

2

主题

10

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2013-7-25
在线时间
0 小时
 楼主| 发表于 2013-7-26 20:57:01 | 显示全部楼层
回复【10楼】正点原子:
---------------------------------
模式是一样的嘛,都是对相应寄存器写相关指令,对传感器进行配置,让它处于工作状态,为从它里面读数据做好准备。
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
3
金钱
3
注册时间
2023-4-17
在线时间
1 小时
发表于 2023-4-17 18:44:30 | 显示全部楼层
我也碰到同样的问题,,怎么解决?
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-24 10:45

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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