在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Linux驅動開發-編寫MMA7660三軸加速度傳感器

DS小龍哥-嵌入式技術 ? 2022-09-17 15:22 ? 次閱讀

【摘要】 通過MMA7660可以做出很多項目: 比如: 老人防跌倒手環、自行車自動剎車燈,智能鬧鐘,烤火爐跌倒自動斷電、運動手環等等。 這篇文章就介紹如何在Linux下編寫MMA7660三軸加速度芯片的驅動,讀取當前芯片的方向姿態,得到X,Y,Z三個軸的數據。MMA7660是IIC接口的,當前驅動就采用標準的IIC子系統編寫驅動,使用字符設備框架將得到的數據上傳遞給應用層。

1. MMA7660芯片介紹

MMA7660FC 是 ± 1.5 克的三軸數字輸出、超低功率、緊湊型電容式微電機的三軸加速度計,是非常低功耗,小型容性 MEMS傳感器。具有低通濾波器,用于偏移和增益誤差補償, 以及用戶可配置的轉換成 6 位分辨率,用戶可配置輸出速率等功能。MMA7660芯片可以通過中斷引腳(INT)向外通知傳感器數據變化、方向、姿態識別等信息。模擬工作電壓范圍是 2.4V 至 3.6V,數字工作電壓范圍是 1.71V 到 3.6V 。常用在手機、掌上電腦、車載導航,便攜式電腦的防盜,自動自行車剎車燈、運動檢測手環、數碼機、自動叫醒鬧鐘里等等。

特別是計步的功能是現在最常見,不管是智能手環、還是手機都帶有三軸加速度計,可以記錄每天的步數,計算運動量等?,F在很多的不倒翁,無人機、相機云臺,很多常見的產品里都能看到三軸加速計的身影。

通過MMA7660可以做出很多項目: 比如: 老人防跌倒手環、自行車自動剎車燈,智能鬧鐘,烤火爐跌倒自動斷電、運動手環等等。

這篇文章就介紹如何在Linux下編寫MMA7660三軸加速度芯片的驅動,讀取當前芯片的方向姿態,得到X,Y,Z三個軸的數據。MMA7660是IIC接口的,當前驅動就采用標準的IIC子系統編寫驅動,使用字符設備框架將得到的數據上傳遞給應用層。

image-20220108211859294image-20220108211941645

2. 硬件連線

當前使用的開發板是友善之臂Tiny4412開發板,使用三星EXYNOS4412芯片,板子本身自帶了一顆MMA7660芯片,芯片的原理圖如下:

image-20220108211848037image-20220108211911111

內核本身有MMA7660的驅動,下面是源碼的路徑:

image-20220108212008898image-20220108212025997image-20220108212036925

如果加載自己編寫的驅動,還需要去掉原來內核自帶的驅動,不然無法匹配。

Device Drivers  --->
	<*> Hardware Monitoring support  --->  
        <*>   Freescale MMA7660 Accelerometer   (將*號去掉,編譯內核、燒寫內核即可)
image-20220108212133903

3. 源代碼

3.1 mma7660設備端代碼: IIC子系統

#include 
#include 
#include 
#include 
#include 
#include 
#include 

static struct i2c_client *i2cClient = NULL;

static unsigned short  i2c_addr_list[]= {0x4c, I2C_CLIENT_END};/*地址隊列*/

/*
1. 獲取控制器(總線)
2. 探測設備是否存在
3. 定義一個名字用于找到驅動端
 */
static int __init mma7660_dev_init(void)
{
	/*mach-tiny4412.c*/
	struct i2c_adapter *i2c_adap=NULL;  /*獲取到的總線存放在這個結構體*/
	struct i2c_board_info i2c_info;     /*設備描述結構體,里面存放著設備的名字還有地址*/

	/*1. 獲取IIC控制器*/
	i2c_adap = i2c_get_adapter(3);     /*要使用IIC_3號總線*/
	if(!i2c_adap)
	{
		printk("獲取IIC控制器信息失敗!\n");
		return -1;
	}
	
	memset(&i2c_info,0,sizeof(struct i2c_board_info));      	/*清空結構體*/
	strlcpy(i2c_info.type,"mma7660_drv",I2C_NAME_SIZE);    /*名稱的賦值*/
	i2c_info.irq=EXYNOS4_GPX3(1); /*中斷IO口*/

	/*2. 創建IIC設備客戶端*/
	i2cClient = i2c_new_probed_device(i2c_adap,&i2c_info,i2c_addr_list,NULL);
	if(!i2cClient)
	{
		printk("mma7660_探測地址出現錯誤!!\n");
		return -1;
	}

	i2c_put_adapter(i2c_adap);/*設置模塊使用計數*/
	
	printk("mma7660_dev_init!!\n");
	return 0;
}
static void __exit mma7660_dev_exit(void)//平臺設備端的出口函數
{
	printk(" mma7660_dev_exit ok!!\n");

	/*注銷設備*/
	i2c_unregister_device(i2cClient);

	/*釋放*/
	i2c_release_client(i2cClient);
}
module_init(mma7660_dev_init);
module_exit(mma7660_dev_exit);
MODULE_LICENSE("GPL");

3.2 mma7660驅動端代碼: IIC子系統

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

/* MMA7760 Registers */
#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 Debounce Filter
#define MMA7660_PDET			0x09	// Tap Detection
#define MMA7660_PD				0x0a	// Tap Debounce Count

static const struct i2c_device_id mma7660_id[] =
{
	{"mma7660_drv",0}, /*設備端的名字,0表示不需要私有數據*/
	{}
};
static u32 mma7660_irq; /*觸摸屏的中斷編號*/
static struct i2c_client *mma7660_client=NULL;
static int	last_tilt = 0;

#define __need_retry(__v)	(__v & (1 << 6))
#define __is_negative(__v)	(__v & (1 << 5))

static const char *mma7660_bafro[] = {
	"未知", "前面", "背面"
};

static const char *mma7660_pola[] = {
	"未知",
	"左面", "向右",
	"保留", "保留",
	"向下", "向上",
	"保留",
};

/*
函數功能:讀取一個字節的數據
*/
static int mma7660_read_tilt(struct i2c_client *client, int *tilt)
{
	int val;
	do {
		val = i2c_smbus_read_byte_data(client, MMA7660_TILT);
	} while (__need_retry(val));
	*tilt = (val & 0xff);
	return 0;
}
/*
函數功能: 讀取XYZ坐標數據
*/
static int mma7660_read_xyz(struct i2c_client *client, int idx, int *xyz)
{
	int val;
	do {
		val = i2c_smbus_read_byte_data(client, idx + MMA7660_XOUT);
	} while (__need_retry(val));
	*xyz = __is_negative(val) ? (val | ~0x3f) : (val & 0x3f);
	return 0;
}
/*
工作隊列處理函數
*/
static void mma7660_worker(struct work_struct *work)
{
	int bafro, pola, shake, tap;
	int val = 0;

	mma7660_read_tilt(mma7660_client,&val);

	/* TODO: report it ? */
	bafro = val & 0x03;
	if (bafro != (last_tilt & 0x03)) {
		printk("%s\n", mma7660_bafro[bafro]);
	}

	pola = (val >> 2) & 0x07;
	if (pola != ((last_tilt >> 2) & 0x07)) {
		printk("%s\n", mma7660_pola[pola]);
	}

	shake = (val >> 5) & 0x01;
	if (shake && shake != ((last_tilt >> 5) & 0x01)) {
		printk("Shake\n");
	}

	tap = (val >> 7) & 0x01;
	if (tap && tap != ((last_tilt >> 7) & 0x01)) {
		printk("Tap\n");
	}

	/* Save current status */
	last_tilt = val;
	
	int axis[3];
	int i;
	for (i = 0; i < 3; i++)
	{
		mma7660_read_xyz(mma7660_client, i, &axis[i]);
	}
	printk("ABS_X=%d\n",axis[0]);
	printk("ABS_Y=%d\n",axis[1]);
	printk("ABS_Z=%d\n",axis[2]);
}
/*
函數功能: mma7660初始化
*/
static int mma7660_initialize(struct i2c_client *client)
{
	int val;

	/* Using test mode to probe chip */
	i2c_smbus_write_byte_data(client, MMA7660_MODE, 0x00);
	mdelay(10);
	i2c_smbus_write_byte_data(client, MMA7660_MODE, 0x04);
	mdelay(10);
	i2c_smbus_write_byte_data(client, MMA7660_XOUT, 0x3f);
	i2c_smbus_write_byte_data(client, MMA7660_YOUT, 0x01);
	i2c_smbus_write_byte_data(client, MMA7660_ZOUT, 0x15);
	val = i2c_smbus_read_byte_data(client, MMA7660_ZOUT);
	if (val != 0x15) {
		dev_err(&client->dev, "no device\n");
		return -ENODEV;
	}

	/* Goto standby mode for configuration */
	i2c_smbus_write_byte_data(client, MMA7660_MODE, 0x00);
	mdelay(10);

	/* Sample rate: 64Hz / 16Hz; Filt: 3 samples  */
	i2c_smbus_write_byte_data(client, MMA7660_SR, ((2<<5) | (1<<3) | 1));

	/* Sleep count */
	i2c_smbus_write_byte_data(client, MMA7660_SPCNT, 0xA0);

	/* Tap detect and debounce ~4ms */
	i2c_smbus_write_byte_data(client, MMA7660_PDET, 4);
	i2c_smbus_write_byte_data(client, MMA7660_PD, 15);

	/* Enable interrupt except exiting Auto-Sleep */
	i2c_smbus_write_byte_data(client, MMA7660_INTSU, 0xe7);

	/* IPP, Auto-wake, auto-sleep and standby */
	i2c_smbus_write_byte_data(client, MMA7660_MODE, 0x59);
	mdelay(10);

	/* Save current tilt status */
	mma7660_read_tilt(client, &last_tilt);

	mma7660_client = client;
	return 0;
}
/*
靜態方式初始化工作隊列
*/
DECLARE_WORK(mma7660_work,mma7660_worker);
static irqreturn_t mma7660_interrupt(int irq, void *dev_id)
{
	/*調度共享工作隊列*/
	schedule_work(&mma7660_work);
	return IRQ_HANDLED;
}
/*
匹配成功時調用
*/
static int mma7660_probe(struct i2c_client *client, const struct i2c_device_id *device_id)
{
	printk("mma7660_probe!!!\n");
	printk("驅動端IIC匹配的地址=0x%x\n",client->addr);
	
	mma7660_client=client;
	
	/*1. 注冊中斷*/
	mma7660_irq=gpio_to_irq(client->irq);/*獲取中斷編號*/
    if(request_irq(mma7660_irq,mma7660_interrupt,IRQF_TRIGGER_FALLING,"mma7660_irq",NULL)!=0)
    {
		printk("mma7660_中斷注冊失敗!\n");
	}
	
	/*2. 初始化mma7660*/
	if(mma7660_initialize(client) < 0)
	{
		printk(" 初始化mma7660失敗!\n");
	}
    return 0;
}
static int mma7660_remove(struct i2c_client *client)
{
	free_irq(mma7660_irq,NULL);
	printk("mma7660_remove!!!\n");
	return 0;
}
struct i2c_driver i2c_drv =
{
	.driver =
	{
		.name = "mma7660",
		.owner = THIS_MODULE,
	},	
	.probe = mma7660_probe,   //探測函數
	.remove = mma7660_remove, //資源卸載
	.id_table = mma7660_id,   //里面有一個名字的參數用來匹配設備端名字
};
static int __init mma7660_drv_init(void)
{
	/*向iic總線注冊一個驅動*/
	i2c_add_driver(&i2c_drv);
	return 0;
}

static void __exit mma7660_drv_exit(void)
{
	/*從iic總線注銷一個驅動*/
	i2c_del_driver(&i2c_drv);
}

module_init(mma7660_drv_init);
module_exit(mma7660_drv_exit);
MODULE_LICENSE("GPL");
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Linux
    +關注

    關注

    87

    文章

    11423

    瀏覽量

    212377
  • 加速度傳感器

    關注

    12

    文章

    478

    瀏覽量

    55613
  • mma7660
    +關注

    關注

    0

    文章

    3

    瀏覽量

    7398
收藏 人收藏

    評論

    相關推薦
    熱點推薦

    加速度傳感器的應用與選購技巧

    加速度傳感器是一種能夠測量加速力的電子設備,其核心工作原理基于牛頓的第二運動定律。當傳感器感受到外部加速度時,其內部的電子器件會發生變化,進
    的頭像 發表于 03-17 16:47 ?270次閱讀
    <b class='flag-5'>加速度</b><b class='flag-5'>傳感器</b>的應用與選購技巧

    加速度傳感器的選型?主要看這八大參數!

    加速度傳感器作為測量物體運動狀態的重要工具,被廣泛應用于智能手機、可穿戴設備、汽車安全系統、航空航天等多個領域。為了確保所選加速度傳感器能夠滿足特定應用需求,了解其關鍵選型參數至關重要
    的頭像 發表于 01-23 18:02 ?911次閱讀
    <b class='flag-5'>加速度</b><b class='flag-5'>傳感器</b>的選型?主要看這八大參數!

    加速度傳感器的工作原理

    本文的關鍵要點 ?“加速度傳感器”是用來檢測單位時間內的速度(即加速度)的傳感器。 ?從原理方面看,加速
    的頭像 發表于 01-08 16:19 ?830次閱讀
    <b class='flag-5'>加速度</b><b class='flag-5'>傳感器</b>的工作原理

    姿態傳感器模塊 | 集成加速度計、陀螺儀、磁力計,自帶BLE5.0藍牙

    海凌科全新推出HLK-AS2001十姿態傳感器模塊,集成加速度計、陀螺儀和磁力計,自帶BLE5.0藍牙,開發簡單,應用廣泛。什么是十姿態
    的頭像 發表于 01-06 12:47 ?697次閱讀
    十<b class='flag-5'>軸</b>姿態<b class='flag-5'>傳感器</b>模塊 | 集成<b class='flag-5'>加速度</b>計、陀螺儀、磁力計,自帶BLE5.0藍牙

    什么是雙傾角傳感器

    魅力。 一、雙傾角傳感器的工作原理 雙傾角傳感器是一種用于測量物體在兩個不同軸線上傾斜角度的裝置。其工作原理主要基于內部的加速度計和陀螺
    的頭像 發表于 11-26 16:58 ?1130次閱讀
    什么是雙<b class='flag-5'>軸</b>傾角<b class='flag-5'>傳感器</b>

    ZC1202速度傳感器溫度傳感器視覺傳感器加速度傳感器的作用

    速度傳感器、溫度傳感器、視覺傳感器加速度傳感器在各自的應用領域中發揮著不可替代的作用,為現代工
    的頭像 發表于 10-11 15:11 ?591次閱讀

    加速度傳感器的應用

    加速度傳感器是一種能夠測量加速度傳感器。通常由質量塊、阻尼、彈性元件、敏感元件和適調電路等部分組成。
    的頭像 發表于 09-30 08:08 ?1056次閱讀
    <b class='flag-5'>加速度</b><b class='flag-5'>傳感器</b>的應用

    物聯網系統中加速度測試方案的實現_加速度傳感器分析

    特性 測量加速度加速度傳感器能夠測量物體在維空間中的線性加速度以及由地球引力產生的重力加速度
    的頭像 發表于 09-26 14:19 ?953次閱讀
    物聯網系統中<b class='flag-5'>加速度</b>測試方案的實現_<b class='flag-5'>加速度</b><b class='flag-5'>傳感器</b>分析

    聯網行業中的加速度傳感器軟件設計_SSD1315設計詳解

    一 概述 SC7A20 是一款高精度 12bit 數字加速度傳感器芯片,內置功能更豐富,功耗更低,體積更小,測量更精確。芯片通過 I2C/SPI 接口與 MCU 通信,
    的頭像 發表于 09-26 11:01 ?1194次閱讀
    聯網行業中的<b class='flag-5'>三</b><b class='flag-5'>軸</b><b class='flag-5'>加速度</b><b class='flag-5'>傳感器</b>軟件設計_SSD1315設計詳解

    XC1011SD (X2E0000210002) 愛普生汽車用角速度_加速度組合傳感器選型資料

    愛普生XC1011SD是一款為汽車電氣穩定控制系統設計的組合式角速度加速度傳感器,它集成了單陀螺儀傳感器和雙
    發表于 09-19 11:31 ?0次下載

    e2studio開發加速度計LIS2DW12(1)----輪詢獲取加速度數據

    本文將介紹如何驅動和利用LIS2DW12傳感器,實現精確的運動感應功能。 IS2DW12是一款高性能、超低功耗的軸線性加速度計,屬于“femto”系列,利用了成熟的微機械
    的頭像 發表于 08-09 14:54 ?2122次閱讀
    e2studio<b class='flag-5'>開發</b><b class='flag-5'>三</b><b class='flag-5'>軸</b><b class='flag-5'>加速度</b>計LIS2DW12(1)----輪詢獲取<b class='flag-5'>加速度</b>數據

    愛普生加速度傳感器M-A352AD10

    是一個數字信號輸出的加速度傳感器(圖1),具有低噪聲,高穩定,低功耗的技術特點,并采用愛普生的QMEMS工藝技術制成。同時具有高精度和高耐久的特點。全能的M-
    發表于 08-09 14:52 ?0次下載

    國產士蘭微MEMS加速度傳感器的多元應用場景

    國產士蘭微SC7A20H加速度傳感器
    的頭像 發表于 08-08 14:39 ?1798次閱讀

    6傳感器的工作原理及應用領域

    隨著科技的不斷進步,6傳感器在現代機器人技術、航空航天、汽車工程等領域的應用越來越廣泛。它能夠提供維空間中的線性加速度和角速度信息,為各
    的頭像 發表于 06-23 17:10 ?4737次閱讀
    6<b class='flag-5'>軸</b><b class='flag-5'>傳感器</b>的工作原理及應用領域

    加速度計LIS2DW12開發(4)----測量傾斜度

    本文將介紹如何驅動和利用LIS2DW12加速度計的傾斜檢測理論和傾斜角測量方法。一般來說,這里描述的程序也可以應用于
    的頭像 發表于 05-16 17:18 ?1835次閱讀
    <b class='flag-5'>三</b><b class='flag-5'>軸</b><b class='flag-5'>加速度</b>計LIS2DW12<b class='flag-5'>開發</b>(4)----測量傾斜度
    主站蜘蛛池模板: 久久全国免费久久青青小草 | 黄视频在线观看网站 | 国产69久久精品成人看 | 免费国产高清精品一区在线 | 国产精品不卡片视频免费观看 | www.夜夜操 | 国产精品 视频一区 二区三区 | 视频在线观看免费 | 欧美成人午夜精品一区二区 | 免费的黄色毛片 | 成 人 免费 黄 色 视频 | 国产在线视欧美亚综合 | 五月婷婷在线观看 | 免费一级成人毛片 | 浓厚な接吻と肉体の交在线观看 | 免费大片看黄在观看 | 国产伦精品一区二区三区免 | 午夜韩国理论片在线播放 | 国产成人91青青草原精品 | 天天干夜夜噜 | 七月婷婷精品视频在线观看 | 日产国产精品亚洲系列 | 国产日日干 | 天堂网www中文在线 天堂网传媒 | 天天涩综合 | 国产精品久久久久天天影视 | 日本高清不卡视频 | 狠狠做久久深爱婷婷97动漫 | freesexvideo性欧美tv| 视频一区二区免费 | 国产精品不卡片视频免费观看 | 日本一区高清视频 | 六月丁香婷婷天天在线 | 免费黄色大片在线观看 | 日韩精品一级a毛片 | 明星三级国产免费播放 | 日韩三级一区 | 成人在线一区二区三区 | 午夜在线播放视频在线观看视频 | 六月婷婷网视频在线观看 | 色多多黄|