STM32中使用MMA7660重力加速度传感器
来源:互联网 发布:unity3d点击播放动画 编辑:程序博客网 时间:2024/04/29 01:09
最近在项目中要用到飞思卡尔的MMA7660这一款传感器,我在STM32中使用的是模拟I2C来读写它的寄存器,闲话不多说,代码如下:
1、IO引脚配置和模拟I2C的方法
/******************** (C) COPYRIGHT 2015 ASTO ************************** @* 文件名 :mma7660.c @* 描述 :飞思卡尔的MMA7660系列重力加速度传感器 @* 开发平台:STM32F103CBT6系列处理器 @* 通信方式:I2C @* 硬件连接: ------------------------------ * | PB1 : 中断引脚| * | PB10 : SCL数据线| * | PB11 : SDA数据线| * ------------------------------ @* 库版本 :ST3.5.0 @* 开发者 :POWER************************************************************************/#include "stm32f10x.h"#include "mma7660.h"#include "delay.h"/* *========================================================= * 函数功能:MMA7660中断向量表配置 * 参数: 无 * * 函数返回值:无 *========================================================= */static void MMA7660_NVIC_Config(void){NVIC_InitTypeDef NVIC_InitStructure;/* Enable the EXTI1 Interrupt */NVIC_InitStructure.NVIC_IRQChannel = MMA7660_INT_IRQ; //中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;//次优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //通道中断使能NVIC_Init(&NVIC_InitStructure);//初始化中断}/* *========================================================= * 函数功能:MMA7660中断线配置 * 参数: 无 * * 函数返回值:无 *========================================================= */static void MMA7660_ExtiInit(void){EXTI_InitTypeDef EXTI_InitStructure;MMA7660_NVIC_Config();RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //配置MMA7660模块发生相应的事件后中断配置GPIO_EXTILineConfig(MMA7660_INT_PORT_SRC, MMA7660_INT_SOURCE);EXTI_InitStructure.EXTI_Line = MMA7660_INT_LINE;//中断线EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//使用中断方式触发模式(另外还有事件方式触发模式)EXTI_InitStructure.EXTI_Trigger = MMA7660_INT_MODE; //中断信号触发边沿EXTI_InitStructure.EXTI_LineCmd = ENABLE; //中断线使能EXTI_Init(&EXTI_InitStructure); //初始化中断 }/* ********************************************************** * * IIC总线模拟程序 * ********************************************************** *//* *========================================================= * 函数功能:MMA7660端口状态配置 * 参数: 无 * * 函数返回值:无 *========================================================= */void MMA7660_Init(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//中断引脚配置GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输入GPIO_Init(GPIOB, &GPIO_InitStructure); // 选择B端口//SCL数据线配置GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 ;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 普通推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 最高输出速率50MHzGPIO_Init(GPIOB, &GPIO_InitStructure); // 选择B端口//SDA数据线配置GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 ;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; // 开漏输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 最高输出速率50MHzGPIO_Init(GPIOB, &GPIO_InitStructure); // 选择B端口MMA7660_ExtiInit(); //中断配置MMA7660_Begin(); //MMA7660寄存器配置}/* *========================================================= * 函数功能:MMA7660的SDA数据线配置,这里作为输出用 * 参数: 无 * * 函数返回值:无 *========================================================= */void MMA_SDA_IOOUT(void){ GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 ;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; // 开漏输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 最高输出速率50MHzGPIO_Init(GPIOB, &GPIO_InitStructure); // 选择B端口}/* *========================================================= * 函数功能:MMA7660的SDA数据线配置,这里作为输入用 * 参数: 无 * * 函数返回值:无 *========================================================= */void MMA_SDA_IOIN(void){ GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 ;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输入GPIO_Init(GPIOB, &GPIO_InitStructure); // 选择B端口}/* *========================================================= * 函数功能: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 *========================================================= */uint8_t I2C_SlaveAck(void){uint8_t 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(uint8_t a) {uint8_t 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读一个字节数据 * 参数:无 * 函数返回值:返回读出的一个字节数据 *========================================================= */uint8_t I2C_ReadByte(void){uint8_t a =0;uint8_t 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;}
2、MMA相关的代码
/* ********************************************************** * * MMA7660相关函数 * ********************************************************** *//* *========================================================= * 函数功能:写MAA7660寄存器 * 参数: * Regs_Addr - 寄存器地址 * Regs_Data - 寄存器值 * 函数返回值: *========================================================= */void MMA7660_WriteReg(uint8_t Regs_Addr,uint8_t Regs_Data) { I2C_Start();I2C_WriteByte(MMA7660_DEV_WRITE); //先写Slave地址,并配置成写模式I2C_WriteByte(Regs_Addr); //写寄存器地址I2C_WriteByte(Regs_Data); //写寄存器内容I2C_Stop(); //结束本段IIC进程}/* *========================================================= * 函数功能:读MAA7660单字节 * 参数 * Regs_Addr - 寄存器地址 * 函数返回值:寄存器值 *========================================================= */uint8_t MMA7660_ReadReg(uint8_t Regs_Addr) {uint8_t 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 - 加速度寄存器地址 * 函数返回值:加速度值 *========================================================= */uint8_t MMA7660_GetResult(uint8_t Regs_Addr) { uint8_t ret; // 等待转换完成并取出值 ret=MMA7660_ReadReg(Regs_Addr); while(ret&0x40) { ret=MMA7660_ReadReg(Regs_Addr);//数据更新,重新读 } return ret;}/* *========================================================= * 函数功能:MAA7660寄存器配置,决定MMA7660工作方式 * 参数 : * * 函数返回值:无 *========================================================= */void MMA7660_Begin(void){MMA7660_WriteReg(MMA7660_MODE,0x00);//standby mode//首先必须进入standby模式才能更改寄存器MMA7660_WriteReg(MMA7660_SPCNT,0x00);//No Sleep CountMMA7660_WriteReg(MMA7660_INTSU,0xE3);//0xE0 will be OK //original value: 0x03//Configure GINT InterruptMMA7660_WriteReg(MMA7660_PDET,0xE0); //orginal value: 0xE0//No tap detection enabledMMA7660_WriteReg(MMA7660_SR,0x02); //orginal value: 0x34//8 samples/s,TILT debounce filter=2MMA7660_WriteReg(MMA7660_PD,0x00);//original value: 0x00//No tap detection debounce count enabledMMA7660_WriteReg(MMA7660_MODE,0x41);//original value: 0x41//Active Mode,INT= push-pull and active low}
3、头文件定义
#ifndef _MMA7660_H_#define _MMA7660_H_//硬件定义#define MM_INT GPIO_Pin_1//PB1#define MM_SCL GPIO_Pin_10//PB10#define MM_SDA GPIO_Pin_11//PB11/* ********************************************************** * * 中断线配置,低电平触发 * ********************************************************** */#defineMMA7660_INT_GPIO_SRCGPIOB//外设组#defineMMA7660_INT_PORT_SRC GPIO_PortSourceGPIOB//中断引脚组#defineMMA7660_INT_IRQ EXTI1_IRQn//中断号#defineMMA7660_INT_SOURCE GPIO_PinSource1//中断源 #defineMMA7660_INT_LINE EXTI_Line1//中断线#defineMMA7660_INT_MODE EXTI_Trigger_Falling//中断触发方式/* ********************************************************** * * 相关宏定义 * ********************************************************** *///==========模拟IIC==================//#define MMA_ERROR0#define MMA_OK1#define I2C_NOACK0#define I2C_ACK1#define MMA7660_SDAGPIO_Pin_10//PB10 //IIC数据线接口#define MMA7660_SCLGPIO_Pin_11//PB11 //IIC时钟线接口#define MMA7660_INTGPIO_Pin_1//PB1 //中断线接口 #defineMMA7660_INT_DGPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1)//PB1读数据#defineMMA7660_SDA_DGPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11)//PB11读数据#defineMMA7660_SDA_H GPIO_SetBits(GPIOB, GPIO_Pin_11) // PB11 高电平#defineMMA7660_SDA_L GPIO_ResetBits(GPIOB, GPIO_Pin_11) // PB11 低电平#defineMMA7660_SCL_H GPIO_SetBits(GPIOB, GPIO_Pin_10) // PB10 高电平#defineMMA7660_SCL_L GPIO_ResetBits(GPIOB, GPIO_Pin_10) // PB10 低电平//==========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);//结束信号uint8_t I2C_SlaveAck(void);//应答信号void I2C_WriteByte(uint8_t a);//写一字节uint8_t I2C_ReadByte(void);//读一字节void MMA7660_WriteReg(uint8_t Regs_Addr,uint8_t Regs_Data); //写寄存器uint8_t MMA7660_ReadReg(uint8_t Regs_Addr);//读寄存器uint8_t MMA7660_GetResult(uint8_t Regs_Addr); //读加速度void MMA7660_Begin(void); //开始传送前的寄存器值设置/* ********************************************************** * * 全局定义 * ********************************************************** */#endif /* _MMA7660_H_ */
4、中断处理函数
#if MMA7660_EN > 0u#include "mma7660.h"
/******************************************************************************** Function Name : EXTI1_IRQHandler* Description : This function handles External lines 1 interrupt request.* Input : None* Output : None* Return : None*******************************************************************************/void EXTI1_IRQHandler(void){OSIntEnter(); //用于统计中断的嵌套层数,对嵌套层数+1,请注意:这适用于有内核参与的中断if(EXTI_GetITStatus(MMA7660_INT_LINE) != RESET) //如果检测到状态位置位{EXTI_ClearITPendingBit(MMA7660_INT_LINE); //清除中断标志位//发送信号量给相应的MMA7660任务控制块if (!GPIO_ReadInputDataBit(MMA7660_INT_GPIO_SRC, GPIO_Pin_1)) {//如果读取到的是低电平,则表明产生了重力传感器事件OS_ERR err;MMA7660_ReadReg(MMA7660_TILT);//读取TILT寄存器,清除中断,以便下次再进入中断//使用发送信号量的方式//第二个参数:1. OS_OPT_POST_NONE表明在发布任务信号量之后调用任务调度程序// 2. OS_OPT_POST_NO_SCHED则OSTaskSemPost后不会调用调度程序OSTaskSemPost(&MMA7660_TCB, OS_OPT_POST_NONE, &err);}}OSIntExit();//对嵌套层数减1,在退出中断前启动任务调度(适用于有u/COS-III内核参与的中断)}#endif
5、主函数调用
在main函数中调用如下代码即可:
#if MMA7660_EN > 0u/* MMA7660重力传感器初始化 */MMA7660_Init();#endif
0 0
- STM32中使用MMA7660重力加速度传感器
- MMA7660传感器使用心得
- 重力加速传感器 mma7660
- 重力加速传感器 mma7660
- 重力加速度传感器的启示
- 重力加速度传感器角度输出
- mma7660(重力感应传感器)
- 重力加速度陀螺仪传感器MPU-6050
- unity3d 重力加速度传感器控制摄像头
- 重力加速度陀螺仪传感器MPU-…
- MMA7660使用教程
- Android重力加速度传感器数据去噪方法
- 重力加速度陀螺仪传感器MPU-6050(一)
- MEMS 之重力加速传感器mma7660,与陀螺仪
- Android"重力加速度传感器"从驱动到应用层全程分析
- Android"重力加速度传感器"从驱动到应用层全程分析
- 关于安卓智能设备重力传感器检测重力加速度
- Android"重力加速度传感器"从驱动到应用层全程分析
- 你好fedora,再见Ubuntu
- Linux进程间通信——使用消息队列
- Java 进行 RSA 加解密时不得不考虑到的那些事儿
- CoreData Object 变成 data: <fault> 的另一种方式
- Hashtable 类
- STM32中使用MMA7660重力加速度传感器
- Android实现获取验证码效果
- 浅谈利用ASP.NET多线程执行长时间的任务
- vs快捷键
- Hello Lucid Fusion
- PHP JSON 操作总结
- Leetcode - Next Permutation
- Android用GridView排列相册,实现微信选择图片效果
- Handler,Thread和Runnable这三个类之间的关系