zoukankan      html  css  js  c++  java
  • ESP8266 SDK开发: 外设篇-SPI

    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;
  • 相关阅读:
    C# 不用添加WebService引用,调用WebService方法
    贪心 & 动态规划
    trie树 讲解 (转载)
    poj 2151 Check the difficulty of problems (检查问题的难度)
    poj 2513 Colored Sticks 彩色棒
    poj1442 Black Box 栈和优先队列
    啦啦啦
    poj 1265 Area(pick定理)
    poj 2418 Hardwood Species (trie树)
    poj 1836 Alignment 排队
  • 原文地址:https://www.cnblogs.com/yangfengwu/p/12390864.html
Copyright © 2011-2022 走看看