ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2.08-外设篇-SPI(RTOS 2.2.0)

2021-04-12 12:00:58  阅读:162  来源: 互联网

标签:cnt addr SpiSpeed RTOS SPI SpiSend 2.08 数据


ESP8266:SDK开发(源码见资料源码)

开发板购买链接:开发板购买链接

资料源码:https://gitee.com/yang456/Learn8266ForSDK.git

开发软件:https://mnifdv.cn/resource/cnblogs/Learn8266ForSDK/AiThinkerIDE_V0.5_Setup.exe

点击加入群聊【ESP8266开发交流群】:ESP8266开发交流群

淘宝上许多贩卖TCP,UDP,APP,上位机,MQTT,云服务器等基础控制教程的,但是基础的没必要拿出来贩卖!

因为过于简单,只能个人玩玩而已,感觉像是在坑小学生。故,我给大家整理好,开源出来以供大家学习使用!

 

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;

复制代码

 

标签:cnt,addr,SpiSpeed,RTOS,SPI,SpiSend,2.08,数据
来源: https://blog.csdn.net/qq_14941407/article/details/115617252

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有