SPI引腳
上程序
#include "spi_interface.h" SpiAttr spiConfig;//配置SPI SpiData SpiSend;//配置SPI發送的數據
2.配置GPIO,設置為主機模式
3.關於發送數據
首先大家不要被官方規定的發送的幾種數據所迷惑
你要明白,無論是啥命令,地址,數據
都是用SPI發送數據而已
你要是這都不明白....說明你已經被協議弄糊塗了
其實對於通信而言你需要把大的方向搞明白
什么叫:通信方式 (SPI,串口)
什么叫:通信協議 (在通信方式基礎上規定的數據協議)
之所以有命令,地址,和數據之分,其實是咱和某個支持SPI的芯片通信的時候
如果想讀取SPI芯片某個寄存器里面的值
你需要先用SPI發送發送讀命令(告訴芯片我要讀數據)
然后用SPI發送要讀取的地址
然后另一個芯片就返回過來數據了
3.發送一個字節數據
用cmd測試
為了方便我監控數據,使用了一個1S的硬件定時器
SpiSend.cmd= 0x55;//設置發送的數據 SpiSend.cmdLen=1;//發送的數據個數(字節為單位) SPIMasterSendData(SpiNum_HSPI,&SpiSend);//發送數據
監控如下
4.發送兩個字節數據
SpiSend.cmd= 0x55aa;//設置發送的數據 SpiSend.cmdLen=2;//發送的數據個數(字節為單位) SPIMasterSendData(SpiNum_HSPI,&SpiSend);//發送數據
測試如下
先傳的0xaa 后傳輸的 0x55
用戶實際應用的時候要注意!
5.再看一下 addr
addr最大可以傳輸一個32位的數據(4字節)
5.1 注意下下面的情況
測試如下:
注意:
其實實際上設置為傳輸1位的時候芯片內部默認先取addr數據地址的 低八位
uint32_t data = 0x01;
實際上 data = 0x01000000
傳輸數據的時候芯片先取的最后面的00
使用addr傳輸的1位數據的時候需要注意
注意:
注意:
注意:
使用 addr 只要是不傳輸4位數據
芯片內部都會默認先傳低八位
使用 addr 無論是只要是不傳輸4位數據
芯片內部都會默認先傳低八位
使用 addr 無論是只要是不傳輸4位數據
芯片內部都會默認先傳低八位
下面看用addr傳輸4位數據
u32 cnt = 0; uint32_t data = 0x0103070f; void hw_test_timer_cb(void) { cnt++; if(cnt>1000)//1S { cnt=0; SpiSend.addr= &data;//設置發送的數據 SpiSend.addrLen=4;//發送的數據個數(字節為單位) SPIMasterSendData(SpiNum_HSPI,&SpiSend);//發送數據 } }
測試如下:
正好傳輸4位數據的時候,芯片內部默認先傳輸高八位
5.2 傳輸一個u8型4字節的數組,傳輸個數是2字節
芯片默認是先傳輸數組后面的數據,依次向前
u8 temp[4] = {0x01,0x02,0x03,0x04}; void hw_test_timer_cb(void) { cnt++; if(cnt>1000)//1S { cnt=0; SpiSend.addr= (uint32_t *)(&temp);//設置發送的數據 SpiSend.addrLen=2;//發送的數據個數(字節為單位) SPIMasterSendData(SpiNum_HSPI,&SpiSend);//發送數據 } }
5.3 傳輸一個u8型4字節的數組,如果傳輸個數是4字節
芯片也會先傳輸數組后面的數據,依次向前
u8 temp[4] = {0x01,0x02,0x03,0x04}; void hw_test_timer_cb(void) { cnt++; if(cnt>1000)//1S { cnt=0; SpiSend.addr= (uint32_t *)(&temp);//設置發送的數據 SpiSend.addrLen=2;//發送的數據個數(字節為單位) SPIMasterSendData(SpiNum_HSPI,&SpiSend);//發送數據 } }
以上為 使用addr 傳輸數據時需要注意的地方
6 現在看一下 data
只要記住一點即可
data 和 上面的 addr 傳輸的時候取數據的方式完全相反
data就不再多加測試:用戶只需要記住上面的話即可!
由此便推導出使用data應該會怎么傳輸
我想官方這樣做是為了應對客戶不同的傳輸數據情況!
6.1 測試使用data ,u8型數組傳輸2字節的情況
u8 temp[4] = {0x01,0x02,0x03,0x04}; void hw_test_timer_cb(void) { cnt++; if(cnt>1000)//1S { cnt=0; SpiSend.data= (uint32_t *)(&temp);//設置發送的數據 SpiSend.dataLen=2;//發送的數據個數(字節為單位) SPIMasterSendData(SpiNum_HSPI,&SpiSend);//發送數據 } }
測試如下:
和addr完全相反,data是先傳輸數組前面的數據
6.2 測試使用data ,u8型數組傳輸4字節的情況
u8 temp[4] = {0x01,0x02,0x03,0x04}; void hw_test_timer_cb(void) { cnt++; if(cnt>1000)//1S { cnt=0; SpiSend.data= (uint32_t *)(&temp);//設置發送的數據 SpiSend.dataLen=4;//發送的數據個數(字節為單位) SPIMasterSendData(SpiNum_HSPI,&SpiSend);//發送數據 } }
測試如下:
關於組合起來
u32 cnt = 0; u8 temp[4] = {0x01,0x02,0x03,0x04}; void hw_test_timer_cb(void) { cnt++; if(cnt>1000)//1S { cnt=0; SpiSend.cmd = 0x55; SpiSend.cmdLen = 1; SpiSend.addr= (uint32_t *)(&temp);//設置發送的數據 SpiSend.addrLen=4;//發送的數據個數(字節為單位) SPIMasterSendData(SpiNum_HSPI,&SpiSend);//發送數據 } }
測試如下:
總結:
cmd,addr,data的數據該怎么傳還是怎么傳
但是是先傳 cmd 然后 addr 最后 data
如果想SPI發送數據的時候接收數據
SPIMasterRecvData(SpiNum spiNum, SpiData* pOutData)
史上最短的引腳模擬SPI
/** * @brief SPI函數 * @param value--發送的數據 * @param None * @param None * @retval SPI接收的數據 * @example **/ unsigned char SPIWriteRead(unsigned char value) { unsigned char i=0,temp=0; SPI_CLK = 0;//進入之前其實是高電平 if(SPI_MISO)temp|=0x80;//接收數據 for(i=0;i<8;i++) { SPI_MOSI=value&(0x80>>i);//准備數據 SPI_CLK=1; SPI_CLK = 0; if(i<7)if(SPI_MISO)temp|=0x80>>(i+1);//接收數據 } return temp; }
源碼在默認最大是20M
按照規律修改為其它頻率
typedef enum { SpiSpeed_2MHz = 40 - 1, SpiSpeed_5MHz = 16 - 1, SpiSpeed_10MHz = 8 - 1, SpiSpeed_16MHz = 5 - 1, SpiSpeed_20MHz = 4 - 1, SpiSpeed_40MHz = 2 - 1, SpiSpeed_80MHz = 1 - 1, } SpiSpeed;
NONOS_SDK版本區別
#include "driver/spi_interface.h"
/*配置SPI GPIO 口*/ WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105); PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2); PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, 2); PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2); PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2); /*配置SPI 模式*/ spiConfig.mode = SpiMode_Master;//主機 spiConfig.speed = SpiSpeed_20MHz;//時鍾頻率 spiConfig.subMode = SpiSubMode_0;//模式0 spiConfig.bitOrder = SpiBitOrder_MSBFirst;//先傳輸高位 SpiSend.addr=0; SpiSend.addrLen=0; SpiSend.cmd=0; SpiSend.cmdLen=0; SPIInit(SpiNum_HSPI,&spiConfig);//初始化SPI
其它頻率
typedef enum { SpiSpeed_0_5MHz = 160, SpiSpeed_1MHz = 80, SpiSpeed_2MHz = 40, SpiSpeed_5MHz = 16, SpiSpeed_8MHz = 10, SpiSpeed_10MHz = 8, SpiSpeed_20MHz = 4, SpiSpeed_40MHz = 2, SpiSpeed_80MHz = 1, } SpiSpeed;