三,ESP8266 SPI(基于Lua脚本语言)-阿里云开发者社区

开发者社区> 杨奉武> 正文

三,ESP8266 SPI(基于Lua脚本语言)

简介: 重点是说SPI通信协议,,,, 不要害怕协议因为协议是人规定的,,刚好我也是人......规定的协议既然能成为规范让所有人所接受,那么必然有它的优势和优点,必然值得学习,, 害怕协议的人是因为当初碰到了不懂的老师,他只会告诉你这很难.
+关注继续查看

重点是说SPI通信协议,,,,

不要害怕协议因为协议是人规定的,,刚好我也是人......规定的协议既然能成为规范让所有人所接受,那么必然有它的优势和优点,必然值得学习,,

害怕协议的人是因为当初碰到了不懂的老师,他只会告诉你这很难............其实是他不会........

CS      :   Chip Selection    片选引脚,多个设备时可以用这个引脚选择和哪个设备通信

MOSI  :   Master Out   Slave In   主机输出数据引脚,,,,从机接收数据引脚

MISO :   Master In  Slave Out     主机接收数据引脚....从机输出数据引脚

CLK  :    时钟

还有两个参数----假设有的单片机自带硬件SPI,一定会提供设置下面两个参数,,,当然有的支持SPI通信的芯片也可能涉及这两个参数

CPOL    :表示时钟信号(CLK引脚)在空闲时是高电平还是低电平

CPHA    :表示数据在时钟信号(CLK)的第几个沿开始数据传输

现在假如说

CPOL   = 0  ;//时钟信号(CLK引脚)在空闲时是低电平

CPHA   = 0;//数据在时钟信号(CLK)的第1个沿开始数据传输

 

通信的时候先传输高位

假如说  主机发给从机   10101010       从机发给主机    01010101

再假如 主机接收数据存到  MasterData 里面

            从机接收数据存到  SlaveData 里面

 

第一个上升沿  主机的10101010 最高位是 1 所以主机会让MOSI引脚输出高电平

                        从机的01010101最高位是 0  所以从机会让MISO引脚为低电平

 

第一个下降沿  主机接收MISO引脚的数据,因为是低电平所以 MasterData= 0000 0000;

                       从机接收MOSI引脚的数据,因为是高电平所以从机SlaveData = 0000 0001;

 

 

第二个上升沿  主机左移一位  0101010X 最高位是 0 所以主机会让MOSI引脚输出低电平

                        从机左移一位 1010101X 最高位是 1  所以从机会让MISO引脚为高电平

 

 

第二个下降沿  主机接收MISO引脚的数据,因为是高电平所以 MasterData= 0000 0001;

                       从机接收MOSI引脚的数据,因为是低电平所以从机SlaveData = 0000 0010;

 

 就这样8个上升和8个下降沿之后

                        MasterData  = 01010101

                              SlaveData    =  10101010

 

 

 

现在假如说

CPOL   = 0  ;//时钟信号(CLK引脚)在空闲时是低电平

CPHA   = 1;//数据在时钟信号(CLK)的第2个沿开始数据传输

 

第一个下降沿  主机的10101010 最高位是 1 所以主机会让MOSI引脚输出高电平

                        从机的01010101最高位是 0  所以从机会让MISO引脚为低电平

 

第一个上升沿  (注意是标号为1的那个,,,实际上是第二个上升沿)

                       主机接收MISO引脚的数据,因为是低电平所以 MasterData= 0000 0000;

                       从机接收MOSI引脚的数据,因为是高电平所以从机SlaveData = 0000 0001;

 

 

 

第二个下降沿  主机左移一位  0101010X 最高位是 0 所以主机会让MOSI引脚输出低电平

                        从机左移一位 1010101X 最高位是 1  所以从机会让MISO引脚为高电平

 

第二个上升沿  主机接收MISO引脚的数据,因为是高电平所以 MasterData= 0000 0001;

                       从机接收MOSI引脚的数据,因为是低电平所以从机SlaveData = 0000 0010;

 

 第八个下降沿  主机把最后一位0放在了 MOSI引脚输出低电平  

                               从机把最后一位1放在了 MISO引脚输出高电平  

 

其实现在我也有疑惑,,,这样就完了吗??????只把数据放在引脚上就行了吗????然后内部硬件就自动接收了吗????

看一下摩托罗拉的数据手册

难道最后一位会自动的接收?????搞不懂咧咧.....改天自己测试一下,,,让主机工作在

CPOL   = 0  ;//时钟信号(CLK引脚)在空闲时是低电平

CPHA   = 1;//数据在时钟信号(CLK)的第2个沿开始数据传输

然后让主机发一个字节的数据看看CLK怎样变化的..............然后再尝试手写从机接收....然后知道结果了再来修改这个地方....

其余的两种就不说了

其实说白了就是

CPOL控制在空闲状态下CLK是高电平还是低电平

CPHA控制数据是在第一个沿就开始传输还是在第二个沿

其实呢!!写程序最终还是要看芯片的资料,,,,,

现在看一下ESP8266的SPI

 

 

 

spi.setup(1, spi.MASTER, spi.CPOL_HIGH, spi.CPHA_HIGH, 8, 8)

用SPI1,主机模式,,空闲状态下Clk为高电平,,第二个沿开始数据传输,8位数据,8分频(10Mhz),默认半双工

发送数据呢就简单了

比如向从机发送0xaa,0x55,0x02,0x01

 

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

接收数据呢还另有个函数
假设需要接收4个数据

 

ReadData = spi.recv(1,4,0xaa)

其实就是让CLK产生32个脉冲信号,每8个代表一个字节的数据,,后面的0xaa哈,是在产生脉冲信号的时候MOSI引脚发送的数据,,如果不写

默认发0xFF

 

对了接收到的数据都是以字符串的形式保存在变量里面,,可能会问我怎么自己解析数据呢

假如说判断是不是接收到0xaa 和0x55

aa = spi.recv(1,2,0xaa)

if   aa:byte(1)==0xaa  and  aa:byte(2)==0x55  then

    自己的执行函数

end

大家肯定会说你咋知道要这样写

因为有API文档

链接:http://pan.baidu.com/s/1i5lBi7N%20密码:2b5h

 链接:http://pan.baidu.com/s/1crUXUe%20密码:bs83

 还有一点,,我一开始看到过别人这样做过,,所以呢我就知道可以这样用....知识这东西一定要活学活用

http://blog.csdn.net/silno/article/details/72866623?locationNum=10&fps=1

 

 最后说一下和STM32进行SPI通信的一些注意,,,当然是把stm32配置成从机模式,,然后呢其余的设置一定要一样

列如我配置的

void Spi2SlaveInit(void)
{
  SPI_InitTypeDef   SPI_InitStructure;
  GPIO_InitTypeDef  GPIO_InitStructure;

    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,  ENABLE );//SPI2时钟使能       
         
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;//CS
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
    GPIO_Init(GPIOB,&GPIO_InitStructure);
    
    //GPIO_ResetBits(GPIOB,GPIO_Pin_12);  //PB13/14/15上拉
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;        
    GPIO_Init(GPIOB,&GPIO_InitStructure);
  
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15 ;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; 
    GPIO_Init(GPIOB,&GPIO_InitStructure);    
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14 ;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
    GPIO_Init(GPIOB,&GPIO_InitStructure);    
  
    GPIO_ResetBits(GPIOB,GPIO_Pin_14);  //PB13/14/15上拉
  
    GPIO_ResetBits(GPIOB,GPIO_Pin_15);  //PB13/14/15上拉
    

    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
//     SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
    SPI_InitStructure.SPI_NSS = SPI_NSS_Hard;  //如果这里使用硬件模式,从机低电平
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial = 7;
    SPI_Init(SPI2, &SPI_InitStructure); 
    
    SPI_I2S_ITConfig(SPI2,SPI_I2S_IT_RXNE,ENABLE);
    
    SPI_Cmd(SPI2 , ENABLE);
}

 

要注意

CS引脚在模块刚启动的时候一定是低电平............

再说一点,我的32程序用的中断接收的SPI的数据,然后在中断里面准备发送的数据,,大家这样想

主机的数据发过来一个字节数据之后才进的中断,,所以如果想在中断里面发送数据,,应该在进中断之前准备好数据的第一个字节

假设主机需要读四个字节就会进四次中断

我从机发给主机的数据是0xaa 0x55 0x01 0x02

char table[4] = {0xaa, 0x55, 0x01, 0x02}

在主机发送数据之前

我需要   SPI2->DR = table;

              Spi2SendBuff = table+1;

void SPI2_IRQHandler(void)  
{  
  if(SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_RXNE) == SET)  
  {    
        SPI2->DR = *Spi2SendBuff;
        Spi2ReadBuff[Spi2ReadCnt] = SPI2->DR;
        
        Spi2ReadCnt ++;    
        Spi2SendBuff ++;
  }  
} 

这样的话来第一个中断的时候我的第一个数据0xaa也发向了主机,然后又准备了第二个数据,,,,,,,四次中断就会把数据发给了主机,,注意指针溢出乱指了一下

这篇文章呢主要是会用ESP8266的SPI就行哈......


 

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Redis进阶应用:Redis+Lua脚本实现复合操作
通过阅读本文将Redis+Lua有了一定的了解,并能使用脚本完成一些简单的复合操作。
4189 0
notepad++ 查找引用(Find Reference)(适用于c c++及各类脚本比如lua、python等)
在程序开发过程中,程序员经常用到的一个功能就是查找引用(Find Reference),Visual Studio里面的对应功能是“查找所有引用”(Find All References)。     我在使用notepad++写代码的时候一开始一直因为找不到类似的功能而苦恼。
1327 0
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
7238 0
八,ESP8266 文件保存数据(基于Lua脚本语言)
应该是LUA介绍8266的最后一篇,,,,,,下回是直接用SDK,,然后再列个12345.......不过要等一两个星期,先忙完朋友的事情 前面几篇 用AT指令版本的 一,  http://www.cnblogs.
1305 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
8919 0
《Lua游戏开发实践指南》一第2章 脚 本 语 言
本节书摘来华章计算机《Lua游戏开发实践指南》一书中的第2章 ,(美)Paul SchuytemaMark Manyen著 田剑译 更多章节内容可以访问云栖社区“华章计算机”公众号查看。
943 0
使用OpenApi弹性释放和设置云服务器ECS释放
云服务器ECS的一个重要特性就是按需创建资源。您可以在业务高峰期按需弹性的自定义规则进行资源创建,在完成业务计算的时候释放资源。本篇将提供几个Tips帮助您更加容易和自动化的完成云服务器的释放和弹性设置。
11017 0
+关注
杨奉武
优秀不够,你是否无可替代;知识从未如此性感 --群1: 235371864 --群2: 607064330 --QQ:946029359 --淘宝 https://shop411638453.taobao.com/
119
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《Nacos架构&原理》
立即下载
《看见新力量:二》电子书
立即下载
云上自动化运维(CloudOps)白皮书
立即下载