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;
  • 相关阅读:
    vue打包不显示或图片不显示配置
    Vue::is特性用法
    毕业实习报告
    前端vscode常用快捷键总结
    1. 变量常量
    信息收集之CMS指纹识别
    4. EIGRP的复合度量值
    3. EIGRP报文,三张表,邻居建立
    信息收集之目录扫描
    2. EIGRP路由单播邻居和被动接口
  • 原文地址:https://www.cnblogs.com/yangfengwu/p/12390864.html
Copyright © 2011-2022 走看看