1. I2C介紹
IIC又簡(jiǎn)寫成I2C,是一種串行通信總線,使用多主從架構(gòu)。
最初設(shè)計(jì)目的為了讓主板、嵌入式系統(tǒng)或手機(jī)用來連接低速周邊設(shè)備。多用于小數(shù)據(jù)量的場(chǎng)合,有傳輸距離短,任意時(shí)刻只能有一個(gè)主機(jī)等特性。
在Linux嵌入式應(yīng)用開發(fā)的情景下,完全可以不必理會(huì)IIC協(xié)議的詳細(xì)規(guī)定。只需要按照驅(qū)動(dòng)層提供給我們的操作IIC外設(shè)的操作接口函數(shù)就可以像操作linux中其他普通設(shè)備文件那樣輕松的操作IIC外設(shè)了。
1.1 開發(fā)板上I2C資源介紹
EASY EAI Orin-Nano開發(fā)板預(yù)留引出了2路IIC資源,以供用戶自定義調(diào)用,它們分別是IIC2和IIC8。確切的分部位置,如下圖所示:
1.2 硬件接線示意圖
本示例采用ADS1115電壓檢測(cè)模塊進(jìn)行輔助演示。此模塊功能是把檢測(cè)到的電壓(模擬信號(hào))轉(zhuǎn)化為數(shù)字信號(hào)存入寄存器中,然后以IIC的通信方式對(duì)外提供電壓信息的提取。
ADS1115模塊與EASY EAI Orin-Nano的接線原理圖如下所示:
2. 快速上手
2.1 例程源碼下載
到【百度網(wǎng)盤】上下載相關(guān)的單例程序:
鏈接:https://pan.baidu.com/s/1RXHMGpmGSEfFy0rb1VkXSg?pwd=1234
提取碼: 1234
比如在windows環(huán)境中,就把單例程序下載到:此電腦D:BaiduNetdisk (無規(guī)定,用戶可自主選擇),如下圖所示。
然后把例程【復(fù)制粘貼】到nfs掛載目錄中。(不清楚目錄如何構(gòu)建的,可以參考《入門指南/開發(fā)環(huán)境準(zhǔn)備/nfs服務(wù)搭建與掛載》)
2.2 例程編譯&運(yùn)行
通過adb shell進(jìn)入開發(fā)板環(huán)境(不清楚如何通過adb進(jìn)行調(diào)試,可以參考《入門指南/開發(fā)板調(diào)試方式介紹/adb調(diào)試》),執(zhí)行下方命令定位到demo目錄,并且執(zhí)行編譯操作。
cd /home/orin-nano/Desktop/nfs/08_IIC/ ./build.sh

編譯成功后,會(huì)生成一個(gè)test-ads1115的可執(zhí)行程序在Release目錄中。
執(zhí)行下方命令則可運(yùn)行測(cè)試demo,如下所示。
sudo ./Release/test-ads1115
執(zhí)行效果如下所示,利用探測(cè)分別觸碰3V3,1V8,GND三個(gè)端子,則可在終端測(cè)出對(duì)應(yīng)的電壓值。
3. C語言使用案例
ADS1115的C語言使用案例,代碼地址為08_IIC/test-ads1115/main.c,供用戶編碼參考。以下代碼展示了對(duì)ADS1115操作流程:
int32_t ads1115_config_register(uint32_t fd, uint8_t configH, uint8_t configL) { uint8_t reg_data[3] = {ADS1015_REG_POINTER_CONFIG, configH, configL}; return iic_write(fd, ADS1115_ADDRESS, reg_data, sizeof(reg_data)); } int16_t ads1115_read_data(uint32_t fd) { bool ret = false; /*讀取數(shù)據(jù)*/ uint8_t tx_data[1] = {ADS1015_REG_POINTER_CONVERT}; if(iic_write(fd, ADS1115_ADDRESS, tx_data, sizeof(tx_data)) < sizeof(tx_data)){ printf("iic write faild !n"); return -1; } uint8_t rx_data[3]={0}; if(iic_read(fd, ADS1115_ADDRESS, rx_data, 2) < 0){ printf("iic read faild !n"); return -1; } int16_t data = rx_data[0]*256+rx_data[1]; return data; } double ads1115_get_voltage_val(uint32_t fd, uint8_t configH, uint8_t configL) { /*配置寄存器*/ if(ads1115_config_register(fd, configH, configL) < 0){ printf("ads1115 config register faildn"); return 0.0; } usleep(100 * 1000); int16_t ad_val = ads1115_read_data(fd); if((0x7FFF == ad_val)|(0X8000 == ad_val)) {//是否超量程了 ad_val = 0; printf("ads1115 over PGArn"); } double val = 0.0; switch((0x0E&configH)?>>1)//量程對(duì)應(yīng)的分辨率 { case(0x00): val = (double)ad_val*187.5/1000000.0; break; case(0x01): val = (double)ad_val*125/1000000.0; break; case(0x02): val = (double)ad_val*62.5/1000000.0; break; case(0x03): val = (double)ad_val*31.25/1000000.0; break; case(0x04): val = (double)ad_val*15.625/1000000.0; break; case(0x05): val = (double)ad_val*7.8125/1000000.0; break; default: val = 0.0; break; } return val; } int main(int argc, char const *argv[]) { bool ret = false; double val; int fd = iic_init("/dev/i2c-2"); if(fd < 0){ printf("iic init faild n"); return -1; } if(0 != iic_set_addr_len(fd, 7)){ return -1; } if(0 != iic_set_addr(fd, ADS1115_ADDRESS)){ return -1; } while (1) { val = ads1115_get_voltage_val(fd, CONFIG_REG_H, CONFIG_REG_L); printf("val: %f Vrn",val); sleep(2); } iic_release(fd); return 0; }
其中iic_init(),iic_set_addr_len(),iic_set_addr(),iic_read(),iic_write(),iic_release()是對(duì)系統(tǒng)調(diào)用的易用化封裝。具體實(shí)現(xiàn)于08_IIC/commonApi/iic.c
除了需要有對(duì)IIC硬件資源進(jìn)行操作的接口以外,要需要清楚IIC總線上的IIC從機(jī)設(shè)備的寄存器操作方法。如ADS1115電壓檢測(cè)芯片,與其寄存器相關(guān)的操作定義均在08_IIC/test-ads1115/ads1115.h中實(shí)現(xiàn)。
審核編輯 黃宇
-
I2C
+關(guān)注
關(guān)注
28文章
1533瀏覽量
126957 -
開發(fā)板
+關(guān)注
關(guān)注
25文章
5499瀏覽量
102046 -
rk3576
+關(guān)注
關(guān)注
1文章
145瀏覽量
544
發(fā)布評(píng)論請(qǐng)先 登錄
米爾RK3576開發(fā)板特惠活動(dòng)!

基于RK3576開發(fā)板的MIPI-DSI使用

評(píng)論