Linux學習筆記7-IIC的應用和AP3216C

接下來進入其他兩種串行通信方式:SPII2C的學習,因為以后的項目中會用到這些通信方式,而且正點原子的開發板里面也有用I2C和SPI通信的傳感器來做實例,分別是一個距離傳感器和六軸陀螺儀,這樣就可以很好的通過實例來學習了。這兩個通信方式最大的區別就是速度,I2C的最高通信速度是400KHz,而SPI最高可以到幾百MHz,所以在低速應用時I2C即可,到了高速的場合就必須用SPI了。
先學習I2C的應用,這里還是和以前一樣,重點放在應用上,然后研究距離傳感器的datasheet來嘗試編寫傳感芯片的驅動!
I.MX6UL有4路I2C,正點原子寫的I2C驅動包含了一系列的函數,這些函數其實就是對I2C相關的寄存器做一些置1或者0的操作,所以我們可以學習下常用的對寄存器按位邏輯操作的方法:

  1. 使某一位置0,其他位不變
base->I2CR &= ~(1 << 7);  //第7位置0,使用按位與
base->I2CR &= ~((1 << 5) | (1 << 4) | (1 << 3));   //[5:3]位同時清零
  1. 使某一位置1,其他位不變
base->I2CR |= ( 1 << 7);  //第7位置1,按位或
base->I2CR |=  (1 << 4) | (1 << 2);  //同時把第4位和第1位置1
  1. 檢測某一位是否為0或者1
if(base->I2SR & (1 << 5)) == 1  //即I2SR的第五位是否為1,如果為1則邏輯與的結果是1
if((base->I2CR) & (1 << 5)) == 0)  即I2SR的第五位是否為0

這里不會深入研究正點原子的I2C驅動,只需要知道如何調用函數進行I2C數據的讀寫即可,把重點放在開發板上的傳感器芯片AP3216C上。研究它的datasheet先。

The AP3216C is an integrated ALS & PS module that includes a digital ambient light sensor [ALS], a proximity sensor [PS], and an IR LED in a single package.
所以它包含了3個模塊,光傳感器ALS、距離傳感器PS和紅外線LEDIR,最常用在手機和平板上用來檢測耳朵是否接觸聽筒,或者光傳感器來檢測光照強度調節屏幕亮度。

在datasheet里查到這個芯片的地址是0x1E,再研究datasheet第12頁的表格,傳感器的設置、數據讀取和寫入都是從不同的寄存器地址,所以我們先用一些宏來把寄存器地址在頭文件中定義好,方便后面調用。宏的名字一定要一眼就看出意思來

#define AP3216C_ADDR    	0X1E	/* AP3216C器件地址 */#define AP3216C_SYSTEMCONG	0x00	/* 配置寄存器 			*/
#define AP3216C_INTSTATUS	0X01	/* 中斷狀態寄存器 		*/
#define AP3216C_INTCLEAR	0X02	/* 中斷清除寄存器 		*/
#define AP3216C_IRDATALOW	0x0A	/* IR數據低字節 */
#define AP3216C_IRDATAHIGH	0x0B	/* IR數據高字節 		*/
#define AP3216C_ALSDATALOW	0x0C	/* ALS數據低字節 		*/
#define AP3216C_ALSDATAHIGH	0X0D	/* ALS數據高字節			*/
#define AP3216C_PSDATALOW	0X0E	/* PS數據低字節 			*/
#define AP3216C_PSDATAHIGH	0X0F	/* PS數據高字節 			*/

先編寫讀寫數據的函數ap3216c_write(...),其實就是配置i2c_transfer結構體的各個參數,這個函數的參數是設備地址、要寫入的寄存器、寫入的數據,返回值可以擴展,可以是0-4,對應未寫入(0),I2C14寫入(返回值14)

unsigned char ap3216c_write(unsigned char addr, unsigned char reg, unsigned char data)  
{unsigned char status = 0;   unsigned char writedata = data;struct i2c_transfer masterXfer;  			/* 定義masterXfer結構體并配置 */masterXfer.slaveAddress = addr; 			/* 設備地址 */masterXfer.direction = kI2C_Write;			/* 方向為寫入 */masterXfer.subaddress = reg;				/* 要寫入的寄存器地址 */masterXfer.subaddressSize = 1;				/* 地址長度一個字節  */masterXfer.data = &writedata;				/* 要寫入的數據 */masterXfer.dataSize = 1;  					/* 寫入數據長度1個字節 */if(i2c_master_transfer(I2C1, &masterXfer))status=1;return status;}

同樣的可以編寫讀函數ap3216c_read(...),參數是設備地址、要讀的寄存器、返回值就是讀取的數據。

unsigned char ap3216c_read(unsigned char addr,unsigned char reg)
{unsigned char val=0;struct i2c_transfer masterXfer;	masterXfer.slaveAddress = addr;				/* 設備地址 */masterXfer.direction = kI2C_Read;			/* 讀取數據 */masterXfer.subaddress = reg;				/* 要讀取的寄存器地址 */masterXfer.subaddressSize = 1;				/* 地址長度一個字節	*/masterXfer.data = &val;						/* 接收數據緩沖區 */masterXfer.dataSize = 1;					/* 讀取數據長度1個字節 */i2c_master_transfer(I2C1, &masterXfer);return val;
}

根據讀寫的基礎函數,我們可以編寫讀寫IRPSALS幾個模塊數據的函數ap3216c_readdata(...)

void ap3216c_readdata(unsigned short *ir, unsigned short *ps, unsigned short *als)
{unsigned char buf[6];unsigned char i;/* 循環讀取所有傳感器數據 */for(i = 0; i < 6; i++)	{buf[i] = ap3216c_read(AP3216C_ADDR, AP3216C_IRDATALOW + i);	 /* 從0X0A到0X0F */}if(buf[0] & 0X80) 	/* IR_OF位為1,則數據無效 */*ir = 0;					else 				/* 讀取IR傳感器的數據  */*ir = ((unsigned short)buf[1] << 2) | (buf[0] & 0X03); 	/* 只保留buf[0]即IR低字節,并把高字節左移兩位,獲取IR完整數據 */		*als = ((unsigned short)buf[3] << 8) | buf[2];	/* 讀取ALS傳感器的數據 	*/  if(buf[4] & 0x40)	/* IR_OF位為1,則數據無效 */*ps = 0;    													else 				/* 讀取PS傳感器的數據  */*ps = ((unsigned short)(buf[5] & 0X3F) << 4) | (buf[4] & 0X0F); 	
}

至此AP3216C這個芯片的驅動就基本完成了。開發板的硬件上是通過I.MX6UL的I2C1通道和傳感器連接,所以一開始需要初始化I2C1,這里就不贅述。
在main.c里的while(1)循環中讀取這3個模塊的數據并通過串口打印出來:

while(1)
{ap3216c_readdata(&ir, &ps, &als);printf("\r\n Data of IR, PS, ALS is: %d, %d, %d\r\n\r\n", ir, ps, als);delayms(200);
}

Makefile后燒寫,在測試時用手去靠近開發板上的芯片,觀察輸出結果,也可以用光照,看看輸出結果是否和預想一致。
在這里插入圖片描述

I2C的學習到此結束,接下去進入SPI外設的學習。
未完待續

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/208295.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/208295.shtml
英文地址,請注明出處:http://en.pswp.cn/news/208295.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

GRE與順豐圓通快遞盒子

1. DNS污染 隨想&#xff1a; 在輸入一串網址后&#xff0c;會發生如下變化如果你在系統中配置了 Hosts 文件&#xff0c;那么電腦會先查詢 Hosts 文件如果 Hosts 里面沒有這個別名&#xff0c;就通過域名服務器查詢域名服務器回應了&#xff0c;那么你的電腦就可以根據域名服…

第六屆“強網”擬態防御國際精英挑戰賽——入圍戰隊篇

第六屆“強網”擬態防御國際精英挑戰賽即將于2023年12月6日在南京盛大開賽&#xff01;本屆挑戰賽再次為全球頂尖戰隊提供實戰機會&#xff0c;向多類擬態防御設備系統發起挑戰&#xff0c;在眾測實戰中持續檢驗中國制造內生安全數字產品所具有的中國力量。 本屆挑戰賽參賽戰隊…

【LeetCode:1466. 重新規劃路線 | DFS + 圖 + 樹】

&#x1f680; 算法題 &#x1f680; &#x1f332; 算法刷題專欄 | 面試必備算法 | 面試高頻算法 &#x1f340; &#x1f332; 越難的東西,越要努力堅持&#xff0c;因為它具有很高的價值&#xff0c;算法就是這樣? &#x1f332; 作者簡介&#xff1a;碩風和煒&#xff0c;…

Vue 子路由頁面發消息給主路由頁面 ,實現主頁面顯示子頁面的信息

需求 子頁面進入后&#xff0c;能在主頁面顯示子頁的相關信息&#xff0c;比如說主頁面的菜單激活的是哪個子頁面的菜單項 如上圖&#xff0c;當刷新瀏覽器頁面時&#xff0c;讓菜單的激活項仍保持在【最近瀏覽】。 實現方式&#xff1a; 在子頁面的create事件中增加&#xff…

Java File類詳解(下)練習一

練習 第一題 需求&#xff1a;在當前模塊下的aaa文件夾中創建一個a.txt文件 import java.io.File; import java.io.IOException;public class FileExer01 {public static void main(String[] args) throws IOException {File f1 new File("AllInOne\\aaa");f1.mk…

docker-compose腳本編寫關鍵詞詳解

docker-compose腳本編寫高頻關鍵詞&#xff08;一&#xff09; 此處關鍵詞應該必須能靈活運用 關鍵詞 解釋 例子 version 定義使用的docker-compose文件版本。較新的版本支持更豐富的功能和選項。 version: 3.8 services 定義應用程序的各個服務及其配置。每個服務通常…

Vue:繪制圖例

本文記錄使用Vue框架繪制圖例的代碼片段。 可以嵌入到cesium視圖中,也可以直接繪制到自己的原生系統中。 一、繪制圖例Vue組件 <div v-for="(color, index) in colors" :key="index" class="legend-item"><div class="color-…

深度學習還可以從如下方面進行創新!!

文章目錄 一、我認為可以從如下5個方向進行創新總結 一、我認為可以從如下5個方向進行創新 新的模型結構&#xff1a;盡管現在的深度學習模型已經非常強大&#xff0c;但是還有很多未被探索的模型結構。探索新的模型結構可以帶來更好的性能和更低的計算成本。 新的優化算法&a…

JavaScript數組面試題

JavaScript數組面試題 創建一個包含多個元素的數組&#xff0c;并打印輸出數組的內容。 const array ["apple", "banana", "orange"]; console.log(array);如何訪問數組中的特定元素&#xff1f; const array ["apple", "banan…

JS判斷數組中是否包含某個值

方法一&#xff1a;array.indexOf 此方法判斷數組中是否存在某個值&#xff0c;如果存在&#xff0c;則返回數組元素的下標&#xff0c;否則返回-1。 var arr[1,2,3,4]; var indexarr.indexOf(3); console.log(index);方法二&#xff1a;array.includes(searcElement[,fromIn…

一個簡單的postman設置斷言,為何會難住一個工作5年的測試?

postman設置斷言 作為一款接口測試工 具&#xff0c;postman需要對發送請求后返回的結果是否正確做驗證&#xff0c;在postman中通過 tests頁簽做請求的驗證&#xff0c;也稱為斷言。 postman設置斷言的流程 1、在tests頁簽截取要對比的實際響應信息&#xff08;響應頭、響應…

眼花繚亂的ADN/ADX/DSP/DMP/SSP和他們的關系鏈

做過互聯網廣告尤其是程序化廣告的同學都遇到過以下這些名詞&#xff0c;或許正被他們折磨的焦頭爛額&#xff0c;這篇文章&#xff0c;我們就來說說這些概念的含義及他們之間的關系鏈。 ADN&#xff1a;AD Network——廣告網絡或廣告聯盟。連接廣告主和媒體的中間商。 ADX&…

stm32串口編程實例-實現數據的收發功能

大家好&#xff0c;今天給大家介紹stm32串口編程實例&#xff0c;文章末尾附有分享大家一個資料包&#xff0c;差不多150多G。里面學習內容、面經、項目都比較新也比較全&#xff01;可進群免費領取。 串口是USART(通用同步/異步收發器)的俗稱。 實際上&#xff0c;串行總線并不…

2023年8月8日 Go生態洞察:Go 1.21 版本發布探索

&#x1f337;&#x1f341; 博主貓頭虎&#xff08;&#x1f405;&#x1f43e;&#xff09;帶您 Go to New World?&#x1f341; &#x1f984; 博客首頁——&#x1f405;&#x1f43e;貓頭虎的博客&#x1f390; &#x1f433; 《面試題大全專欄》 &#x1f995; 文章圖文…

中小企業都在用哪些開源項目管理工具?分享15款

推薦15個優秀的開源項目管理工具&#xff0c;比如&#xff1a;ProjectLibre、OpenProject、ERPNext、Redmine、禪道、Tuleap、Restyaboard等。 項目經理面臨各種復雜任務&#xff0c;包括追蹤任務的進度、評估交付風險和管理整體工作量。為了順利達成目標&#xff0c;一款靠譜的…

ALLEGRO PCB 如何設置增加的過孔

Allegro添加過孔 1、首先建立焊盤&#xff08;熱風焊盤&#xff09; Via20x10mil(tr30x45x12mil_45) 2、設置過孔的焊盤 Setup-->Constraints&#xff08;約束&#xff09;-->Physical 彈出以下對話框Allegro Constraint Manager 可以通過右鍵點擊PC S&#xff08;…

ArchLinux下載鏈接

LINUX花樣太多&#xff0c;不得不跟著別人要求。 Arch Linux - Downloads Index of /archlinux/iso/2023.12.01/

學習IO的第四天

作業 : 使用兩個子進程完成兩個文件的拷貝&#xff0c;子進程1拷貝前一半內容&#xff0c;子進程2拷貝后一般內容&#xff0c;父進程用于回收兩個子進程的資源 #include <head.h>int main(int argc, const char *argv[]) {int rd -1;if((rdopen("./01_test.c&quo…

零基礎如何入門HarmonyOS開發?

HarmonyOS鴻蒙應用開發是當前非常熱門的一個領域&#xff0c;許多人都想入門學習這個技術。但是&#xff0c;對于零基礎的人來說&#xff0c;如何入門確實是一個問題。下面&#xff0c;我將從以下幾個方面來介紹如何零基礎入門HarmonyOS鴻蒙應用開發學習。 一、了解HarmonyOS鴻…

[JSMSA_CTF] 2023年12月練習題 pwn

一開始沒給附件&#xff0c;還以為是3個盲pwn結果&#xff0c;pwn了一晚上沒出來&#xff0c;今天看已經有附件了。 pwn1 在init_0里使用mallopt(1,0) 設置global_max_fast0 任何塊釋放都會進入unsort在free函數里沒有清理指針&#xff0c;有UAF將v6:0x100清0&#xff0c;便于…