1. SPI簡介
SPI是串行外設(shè)接口(Serial Peripheral Interface)的縮寫,是 Motorola 公司推出的一種同步串行接口技術(shù),是一種高速、全雙工、同步的通信總線在用戶空間的應(yīng)用程序中,完全可以不必理會SPI協(xié)議的詳細(xì)規(guī)定。只需要按照驅(qū)動層提供給我們的操作SPI外設(shè)的操作接口函數(shù)就可以像操作linux中其他普通設(shè)備文件那樣輕松的操作SPI外設(shè)了。
EASY EAI Orin-Nano的SPI接口分布如下圖所示:
1.1 SPI參數(shù)配置解析
設(shè)備文件格式:/dev/spidev(bus.select)
bus:代表SPI總線號,即一組SCLK、MOSI、MISO
select:代表SPI設(shè)備號,同一條總線上用不同的片選信號區(qū)分:CSN0、CSN1等
以O(shè)rin-Nano默認(rèn)SPI資源為例:啟用SPI功能后,會出現(xiàn)下面4個(gè)設(shè)備節(jié)點(diǎn)(即有兩條總線,四個(gè)設(shè)備)。
/dev/spidev0.0
/dev/spidev0.1
/dev/spidev3.0
/dev/spidev3.1
SPI通信有4種不同的模式,不同的從設(shè)備在出廠時(shí)配置模式已經(jīng)固定,這是不能改變的,但通信雙方設(shè)備必須工作在同一模式下,所以可以對主設(shè)備的SPI模式進(jìn)行配置,通過CPOL(時(shí)鐘極性)和CPHA(時(shí)鐘相位)來控制主設(shè)備的通信模式。
模式 | CPOL | CPHA |
Mode0 | 0 | 0 |
Mode1 | 0 | 1 |
Mode2 | 1 | 0 |
Mode3 | 1 | 1 |
時(shí)鐘極性CPOL是用來配置SCLK電平的有效態(tài)的;
時(shí)鐘相位CPHA是用來配置數(shù)據(jù)采樣是發(fā)生在第幾個(gè)邊沿的。
CPOL=0表示當(dāng)SCLK=0時(shí)處于空閑態(tài),所以SCLK處于高電平時(shí)有效;
CPOL=1表示當(dāng)SCLK=1時(shí)處于空閑態(tài),所以SCLK處于低電平時(shí)有效;
CPHA=0表示數(shù)據(jù)采樣是在第1個(gè)邊沿,數(shù)據(jù)發(fā)送在第2個(gè)邊沿;
CPHA=1表示數(shù)據(jù)采樣是在第2個(gè)邊沿,數(shù)據(jù)發(fā)送在第1個(gè)邊沿;
【*】SPI主模塊和與之通信的外設(shè)通信時(shí),兩者的時(shí)鐘相位和極性應(yīng)該保持一致。
其余的參數(shù)如:speed:通信的比特率,delay:設(shè)置通信的時(shí)間延遲,bits通信所占的位數(shù)。
1.2 硬件連接
本示例采用RFID讀卡模塊:RC522進(jìn)行輔助演示。
RC522模塊與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/07_SPI/ ./build.sh

此處會根據(jù)源碼輸出3個(gè)示例程序:test-rfid、test-fram、test-spidev。本文檔用到的輔助示例是test-rfid。其它示例用在別的應(yīng)用場景里,此處的代碼僅供參考。
運(yùn)行例程命令如下所示:
sudo ./Release/test-rfid
執(zhí)行效果如下所示。
API的詳細(xì)說明,以及API的調(diào)用(本例程源碼),詳細(xì)信息見下方說明。
3. RFID讀取ID例程
RFID例程源碼位于:
07_SPI/rfid.c。
07_SPI/dev/rc522.c。
07_SPI/include/rc522.h。
利用了RC522芯片進(jìn)行實(shí)現(xiàn)及講解,操作流程如下。
參考例程如下所示。
static unsigned char flag = 0; static unsigned char bits = 8; static unsigned int speed = 100000; static uint16_t delay = 0; unsigned char card_rev_buf[16] = { 0 }; /* *扇區(qū)密碼:A,扇區(qū)數(shù):16,每個(gè)扇區(qū) *密碼字節(jié)數(shù):16Byte */ unsigned char sector_key_a[16][16]; unsigned char data_buf[16] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10}; int main (int argc, char **argv) { memset(data_buf, 0x00, sizeof data_buf); int status = MI_ERR; int numAtempt = 1; int fd = spi_init(dev_spi_bus, dev_spi_select, mode, bits, speed, delay); rfid_init(dev_spi_bus ,dev_spi_select , fd); flag = MI_GET_ID; while(1) { while(rfid_request(PICC_REQIDL, &card_rev_buf[0]) != MI_OK && numAtempt-- >= 0) { usleep(500); } if(rfid_anticoll(&card_rev_buf[2]) == MI_OK) { status = rfid_select(&card_rev_buf[2]); if(status != MI_ERR) { if(flag == MI_GET_ID) { printf("Card ID:%02x%02x%02x%02xn", card_rev_buf[2], card_rev_buf[3],card_rev_buf[4], card_rev_buf[5]); } else if (flag == MI_READ) { memset(sector_key_a, 0xff, 256); memset(data_buf, 0x00, sizeof data_buf); status = rfid_auth_state(PICC_AUTHENT1A, addr, sector_key_a[addr/4], &card_rev_buf[2]); if(status == MI_OK) { status = rfid_read(addr, data_buf); if(status == MI_OK) { print_buff(data_buf, 16); } } else { printf("Error reading"); close(fd); exit(1); } } else if (flag == MI_WRITE) { memset(sector_key_a, 0xff, 256); if(addr == 0 || addr % 4 == 3) { close(fd); exit(1); } status = rfid_auth_state(PICC_AUTHENT1A, addr, sector_key_a[addr/4], &card_rev_buf[2]); if(status == MI_OK) { status = rfid_write(addr, data_buf); if(status != MI_OK) { printf("rfid write failure!n"); close(fd); exit(1); } } else { printf("Error writing"); close(fd); exit(1); } } else { printf("Not implementedn"); } status = rfid_halt(); if(status != MI_OK) { //printf ("rfid halt failure! [ERROR %d]n", status); } } else { // printf("Nonen"); } } else { // printf("Nonen"); } } spi_exit(dev_spi_bus , dev_spi_select); return 0; } /* ----- End of main() ----- */
此外,spi接口的鐵電存儲器通信源碼位于:
07_SPI/fram.c。
07_SPI/mb85rs64.c。
07_SPI/mb85rs64.h。
spi接口的讀寫通信源碼位于:
07_SPI/spidev_test.c。
4. 注意事項(xiàng)
RC522主要為輔助SPI的API使用說明,對于此模塊的資料及使用說明請?zhí)D(zhuǎn):
www.xxx.com(官網(wǎng)的模塊網(wǎng)址)
審核編輯 黃宇
-
SPI
+關(guān)注
關(guān)注
17文章
1788瀏覽量
95041 -
串行接口
+關(guān)注
關(guān)注
3文章
384瀏覽量
43211 -
開發(fā)板
+關(guān)注
關(guān)注
25文章
5590瀏覽量
103196 -
rk3576
+關(guān)注
關(guān)注
1文章
159瀏覽量
618
發(fā)布評論請先 登錄
米爾RK3576開發(fā)板特惠活動!

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

評論