30-ESP8266 SDK開發基礎入門篇--SPI


 

 

 

 這節只是做記錄,

整個的教程呢,重新整理下

教程有點亂,需要再細分一下

這節只是做一下我使用其SPI的記錄

 

還是老樣子,看人家LUA源碼里面怎么使用的

 

注意哈,對於8266 SDK的學習我還是建議大家直接拷貝lua源碼里面的直接用

站在巨人的肩上嘛,,如果你自己寫,你很難寫到人家那樣穩定可靠....別自己瞎研究哈....

知識永遠學不完的,你需要掌握方法!需要學會借力!

lua源碼里面基本上所有的功能都有直接的例子.

 

初始化引腳  

lua語言呢是  spi.setup(id, mode, cpol, cpha, databits, clock_div[, duplex_mode])

 

 

 

 

去源碼里面看看

 

 

 

 

 

 

 

 

 

 

 

 

/******************************************************************************
 * FunctionName : spi_master_init
 * Description  : SPI master initial function for common byte units transmission
 * Parameters   : uint8 spi_no - SPI module number, Only "SPI" and "HSPI" are valid
*******************************************************************************/
void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, uint32_t clock_div)
{
    uint32 regvalue; 

    if(spi_no>1)         return; //handle invalid input number

    SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_CS_SETUP|SPI_CS_HOLD|SPI_RD_BYTE_ORDER|SPI_WR_BYTE_ORDER);

    // set clock polarity (Reference: http://bbs.espressif.com/viewtopic.php?f=49&t=1570)
    // phase is dependent on polarity. See Issue #1161
    if (cpol == 1) {
        SET_PERI_REG_MASK(SPI_PIN(spi_no), SPI_IDLE_EDGE);
    } else {
        CLEAR_PERI_REG_MASK(SPI_PIN(spi_no), SPI_IDLE_EDGE);
    }
    
    //set clock phase
    if (cpha == cpol) {
        // Mode 3: MOSI is set on falling edge of clock
        // Mode 0: MOSI is set on falling edge of clock
        CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_CK_OUT_EDGE);
    } else {
        // Mode 2: MOSI is set on rising edge of clock
        // Mode 1: MOSI is set on rising edge of clock    
        SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_CK_OUT_EDGE);        
    }

    CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_FLASH_MODE|SPI_USR_MISO|SPI_USR_ADDR|SPI_USR_COMMAND|SPI_USR_DUMMY);

    //clear Dual or Quad lines transmission mode
    CLEAR_PERI_REG_MASK(SPI_CTRL(spi_no), SPI_QIO_MODE|SPI_DIO_MODE|SPI_DOUT_MODE|SPI_QOUT_MODE);

    spi_set_clkdiv(spi_no, clock_div);

    if(spi_no==SPI){
        PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, 1);//configure io to spi mode
        PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, 1);//configure io to spi mode    
        PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, 1);//configure io to spi mode    
        PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, 1);//configure io to spi mode    
    }
    else if(spi_no==HSPI){
        PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2);//configure io to spi mode
        PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2);//configure io to spi mode    
        PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2);//configure io to spi mode    
        PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, 2);//configure io to spi mode    
    }
}

 

 

 

使用(作為主機)

spi_master_init(1, 0, 0, 0)

1:HSPI
0:時鍾信號(CLK引腳)在空閑時是低電平
0:數據在時鍾信號(CLK)的第1個沿開始數據傳輸
0:0分頻,就是80MHZ



 

 

發送數據

 

 

 

 

加點解釋

比如向從機發送0xaa,0x55,0x02,0x01

spi.send(1,0xaa,0x55,0x02,0x01)

 

 

 

 

 

 

 

 

 

 

 

 

 

發送0xaa,0x55,0x02,0x01

發現沒

 

 

 

 

不用理會這些,,,再怎么則只是SPI傳輸數據罷了

再怎么搞也是SPI通信......SPI_MOSI引腳發送數據的時候,可以判斷SPI_MISO引腳的電平接收數據

給大家個我寫的史上最簡單的SPI通信函數例子給大家壓壓驚

SPI_MOSI : 發送數據引腳

SPI_MISO : 接收數據引腳

SPI_CLK   : 時鍾引腳

/**
* @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;
}

 

 

比如向從機發送data = 0xaa;

第一種: spi_mast_transaction(1, 8, data , 0, 0,0, 0, 0); 

 

 

 

不要有任何疑問....再怎么着只是SPI發送數據而已

 

 

第二種: spi_mast_transaction(1, 0, 0, 8, data,0, 0, 0); 

 

第三種: spi_mast_transaction(1, 0, 0, 0, 0,8, data, 0); 

 

那很多人就疑問了

 

 

 

這不是命令  地址嗎....

哎呀   什么命令地址,就是要發送的數據罷了.

我有個SPI的從機模塊,假設模塊地址 0x00 里面有數據,

想設置里面的數據需要先發0x00,

讓芯片知道設置的地址是0x00地址

然后發送要設置的數據.

 

實際上怎么做???

先用SPI發送個  0x00

然后再發送設置的數據.

正常的話應該發送兩次SPI數據

但是呢封裝好了

 spi_mast_transaction(1, 0, 0, 8, (0x00),8, (0xff), 0);  假設設置為0xFF

 

 

 

有些人還問,為啥前面還有命令???

我有個SPI的從機模塊,假設模塊設置的地址 0x00 里面有數據,這個地址里面的數據可以設置可以讀取

我想設置怎么辦???先發個設置指令 假設是0xAA吧(注:芯片手冊會說的)

然后呢發送0x00 告訴他是設置0x00里面的信息

然后再發設置的數據

正常的話應該發送三次SPI數據

但是呢封裝好了

 spi_mast_transaction(1, 8, (0xAA), 8, (0x00),8, (0xff), 0);  假設設置為0xFF

 

 

 

所有的都封裝好了.可以直接把SPI.C 和SPI.H直接拷貝過去用

 

 

 

 

不過我發現,RTOS版本的也自帶

 

 

 

 

 

那就不用拷貝了...

不過我發現 初始化里面沒有設置引腳

所以把設置引腳拷貝過來了

 

    //拷貝的lua里面的配置引腳
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_HSPIQ_MISO);
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_HSPI_CS0);
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_HSPID_MOSI);
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, FUNC_HSPI_CLK);

    spiConfig.mode = SpiMode_Master;//主機
    spiConfig.speed = SpiSpeed_20MHz;//時鍾頻率
    spiConfig.subMode = SpiSubMode_0;//時鍾信號(CLK引腳)在空閑時是低電平
    spiConfig.bitOrder = SpiBitOrder_MSBFirst;//數據在時鍾信號(CLK)的第1個沿開始數據傳輸

    SPIInit(SpiNum_HSPI,&spiConfig);//初始化SPI

 

 

發送數據

    u8 data[4] = { 0xaa, 0x55,0x00,0x01};

    SpiSend.addr=0;
    SpiSend.addrLen=0;
    SpiSend.cmd=0;
    SpiSend.cmdLen=0;
    SpiSend.data=&data;
    SpiSend.dataLen=4;

    SPIMasterSendData(SpiNum_HSPI,&data);

 

 

 

 

 

 

 

 

 

 

 

 

 

 

這節只是做下記錄..............

等我新板子到了,我便測試整改教程,把lua和SDK同時開進,源碼還是公開.

Android 和 C# 單獨拿出來講解,不再混到一塊了.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM