構(gòu)建spi參數(shù)結(jié)構(gòu)體
spi.h中同樣是構(gòu)建了一個(gè)結(jié)構(gòu)體,用來對spi進(jìn)行配置:
spi部分對于需要的配置同樣是構(gòu)建了一個(gè)結(jié)構(gòu)體spi_param,便于對spi的最大速率,極性、相位,四線制還是兩線制等參數(shù)做詳細(xì)配置。
spi配置
這部分代碼結(jié)合前面構(gòu)建的spi_param結(jié)構(gòu)體,對結(jié)構(gòu)體成員進(jìn)行了設(shè)置,即完成了spi初始化。設(shè)置了SPI 工作模式。根據(jù)之前講解,SPI根據(jù)相位和極性的不同分為四 種工作模式,在這里四種工作模式為SPI_MODE_x (x = 0、1、2、3)。這里是回環(huán)測試,所以設(shè)置為任意一種工作模式都可以。需要注意的是我們可以分開設(shè)置SPI的讀、寫工作模式。
設(shè)置SPI通信過程中一個(gè)字節(jié)所占的位數(shù)。默認(rèn)情況下設(shè)置為8即可。同樣,這里的讀、寫是分開設(shè)置的。設(shè)置SPI通信的波特率,這里設(shè)置為1M。經(jīng)過以上的配置,SPI已經(jīng)可以通信了。
spi發(fā)送函數(shù)
第一部分:定義并初始化SPI傳輸結(jié)構(gòu)體。SPI傳輸結(jié)構(gòu)體的完整定義如下所示:
結(jié)合注釋很容易理解,簡單說明如下:
(一)tx_buf為發(fā)送地址;
(二)rx_buf接收緩沖區(qū)地址為0,數(shù)據(jù)類型為“__u64”,兼容64位系統(tǒng),64位或32位 由系統(tǒng)自動(dòng)處理,我們不必關(guān)心。len,一次傳輸?shù)臄?shù)據(jù)長度;
(三)speed_hz,指定SPI通信的比特率;
(四)delay_usecs,如果不為零則用于設(shè)置兩次傳輸之間的時(shí)間延遲;
(五)bits_per_word,指定字節(jié)長度,既一個(gè)字節(jié)占用多少比特;
(六)cs_change,取消 選中,如果設(shè)置為真,則在下次傳輸之前會(huì)取消選中當(dāng)前的SPI設(shè)備,更新片選;
(七)tx_nbits,指定“寫”數(shù)據(jù)寬度,SPI 支持 1、2、4位寬度,不過我們使用的SPI3只支持1位數(shù)據(jù)寬度,該值應(yīng)當(dāng)設(shè)置為1或0(設(shè)置為0表示使用默認(rèn)的寬度既寬度為1)。
(八)pad參數(shù)我們沒有用到,不用設(shè)置;
第二部分:調(diào)用ioctl執(zhí)行發(fā)送,參數(shù)fd,是SPI設(shè)備文件描述符,參數(shù)SPI_IOC_MESSAGE(1)用于指定執(zhí) 行傳輸次數(shù),我們這里只定義并初始化了一個(gè)傳輸結(jié)構(gòu)體tr,所以傳輸次數(shù)為1。tr 是第一部分設(shè)置的傳輸結(jié)構(gòu)體變量。
spi接收函數(shù)
spi接收的函數(shù)和發(fā)送函數(shù)基本相同,唯一區(qū)別就是我們不再將接收緩沖區(qū)地址設(shè)為0。
主函數(shù)main
第一部分:tx_buffer是發(fā)送緩沖區(qū),rx_buffer是接收緩沖區(qū)。
第二部分:在main函數(shù)中依次調(diào)用函數(shù)spi_init初始化SPI、調(diào)用函數(shù)transfer執(zhí)行發(fā)送。最后分別打印tx_buffer和rx_buffer的內(nèi)容,正常情況下,程序運(yùn)行后我們可以在控制終端發(fā)現(xiàn)tx_buffer和rx_buffer的內(nèi)容一致。
簡單spi回環(huán)測試代碼
這段代碼是用SPI進(jìn)行回環(huán)測試的程序。讓我們分解代碼的每個(gè)部分:
第一部分:在這部分,包含了一些必要的頭文件,并定義了一些全局變量和結(jié)構(gòu)體。具體來說,`struct_spi_param`是一個(gè)結(jié)構(gòu)體,用于保存與SPI通信相關(guān)的各種參數(shù)。
第二部分:這部分包含了`func_set_opt`函數(shù)的實(shí)現(xiàn),該函數(shù)負(fù)責(zé)初始化SPI設(shè)備。它打開SPI設(shè)備文件(`/dev/spidev1.0`)以讀寫模式,并使用`ioctl`系統(tǒng)調(diào)用來設(shè)置各種SPI參數(shù)。
第三部分:這部分包含了`func_transfer`函數(shù)的實(shí)現(xiàn),該函數(shù)負(fù)責(zé)通過SPI總線傳輸數(shù)據(jù)。它使用`ioctl`系統(tǒng)調(diào)用和`SPI_IOC_MESSAGE`命令來執(zhí)行SPI數(shù)據(jù)傳輸。
第四部分:`main`函數(shù)是程序的入口點(diǎn)。它將`send_num`變量設(shè)置為38,然后調(diào)用`func_set_opt`來配置SPI設(shè)備。接著,它調(diào)用`func_transfer`來發(fā)送和接收數(shù)據(jù),并使用預(yù)定義的`transfer_tx`和`transfer_rx`緩沖區(qū)。最后,它打印接收到的數(shù)據(jù)長度,并關(guān)閉SPI設(shè)備。
下面是代碼的大致執(zhí)行過程:
(一)定義了`struct_spi_param`結(jié)構(gòu)體,用于保存SPI參數(shù),并用默認(rèn)值初始化一個(gè)實(shí)例(`spi_param`)。
(二)定義了兩個(gè)函數(shù):`func_set_opt`和`func_transfer`。
(1)`func_set_opt`函數(shù)初始化SPI設(shè)備,它打開設(shè)備文件并設(shè)置SPI模式、數(shù)據(jù)位數(shù)和速率。
(2)`func_transfer`函數(shù)通過SPI總線傳輸數(shù)據(jù),使用`ioctl`系統(tǒng)調(diào)用和`SPI_IOC_MESSAGE`命令來執(zhí)行SPI數(shù)據(jù)傳輸。
(3)`main`函數(shù)將`send_num`設(shè)置為38,并調(diào)用`func_set_opt`來配置SPI設(shè)備。
(4)`main`函數(shù)接著調(diào)用`func_transfer`來發(fā)送和接收數(shù)據(jù),使用預(yù)定義的`transfer_tx`和`transfer_rx`緩沖區(qū)。
(5)最后,`main`函數(shù)打印接收到的數(shù)據(jù)長度,并關(guān)閉SPI設(shè)備。