寒假学习之stm32(17)----SPI通信协议

发布者:asa1670最新更新时间:2017-10-09 来源: eefocus关键字:stm32  SPI  通信协议 手机看文章 扫描二维码
随时随地手机看文章

背景知识介绍:

  1. wiki : http://wiki.csie.ncku.edu.tw/embedded/SPI#introduction

  2. 百度:http://baike.baidu.com/item/SPI 
    一定要看啊!!!

小小的摘要:

1. 通信模式:SPI是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线(SDI,SDO,SCLK,CS)

MISO(master in slaver out) 主设备数据输入,从设备数据输出。
MOSI(master out slaver in) 主设备数据输出,从设备数据输入。
SCLK时钟信号,由主设备产生。
CS从设备片选信号,由主设备控制

2. 内部结构: 
这里写图片描述

3. 工作原理:

1. 硬件上为4根线。

2. 主机和从机都有一个串行移位寄存器,主机通过向它的SPI串行寄存器写入一个字节来发起一次传输。

3. 串行移位寄存器通过MOSI信号线将字节传送给从机,从机也将自己的串行移位寄存器中的内容通过MISO信号线返回给主机。这样,两个移位寄存器中的内容就被交换。(具有环形通信的特点)

4. 外设的写操作和读操作是同步完成的。如果只进行写操作,主机只需忽略接收到的字节;反之,若主机要读取从机的一个字节,就必须发送一个空字节来引发从机的传输。

4. 应用:主要应用在 EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间。

我们可以看一下SPI的单从机模式的接线: 
这里写图片描述

多从机模式(从这里也能够看出片选接口的作用): 
这里写图片描述


stm32下的SPI配置

PS:我发现这些通信协议的配置真特么相似啊啊啊啊啊

这里写图片描述

然后就是它的框图:

这里写图片描述

配置过程:

  1. 配置相关引脚的复用功能,使能SPIx时钟

    void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);

  2. 初始化SPIx,设置SPIx工作模式

    void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct);

  3. 使能SPIx

    void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState);

  4. SPI传输数据

    void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data); 
    uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx) ;

  5. 查看SPI传输状态

    SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE);

完整的配置过程:

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

    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );//PORTB时钟使能 
    RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2,  ENABLE );//SPI2时钟使能   

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //PB13/14/15复用推挽输出 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB

    GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);  //PB13/14/15上拉

    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;       //设置SPI工作模式:设置为主SPI
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;       //设置SPI的数据大小:SPI发送接收8位帧结构
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;     //串行同步时钟的空闲状态为高电平
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;    //串行同步时钟的第二个跳变沿(上升或下降)数据被采样
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;       //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;        //定义波特率预分频的值:波特率预分频值为256
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;  //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
    SPI_InitStructure.SPI_CRCPolynomial = 7;    //CRC值计算的多项式
    SPI_Init(SPI2, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器

    SPI_Cmd(SPI2, ENABLE); //使能SPI外设

    SPI2_ReadWriteByte(0xff);//启动传输      }   
//SPI 速度设置函数//SpeedSet://SPI_BaudRatePrescaler_2   2分频   //SPI_BaudRatePrescaler_8   8分频   //SPI_BaudRatePrescaler_16  16分频  //SPI_BaudRatePrescaler_256 256分频 void SPI2_SetSpeed(u8 SPI_BaudRatePrescaler)
{
  assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));
    SPI2->CR1&=0XFFC7;
    SPI2->CR1|=SPI_BaudRatePrescaler;   //设置SPI2速度 
    SPI_Cmd(SPI2,ENABLE); 

} 

//SPIx 读写一个字节//TxData:要写入的字节//返回值:读取到的字节u8 SPI2_ReadWriteByte(u8 TxData)
{       
    u8 retry=0;                 
    while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位
        {
        retry++;        if(retry>200)return 0;
        }             
    SPI_I2S_SendData(SPI2, TxData); //通过外设SPIx发送一个数据
    retry=0;    while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) //检查指定的SPI标志位设置与否:接受缓存非空标志位
        {
        retry++;        if(retry>200)return 0;
        }                               
    return SPI_I2S_ReceiveData(SPI2); //返回通过SPIx最近接收的数据                     }


关键字:stm32  SPI  通信协议 引用地址:寒假学习之stm32(17)----SPI通信协议

上一篇:STM32的PWM产生主要工作
下一篇:寒假学习之stm32(16)----IIC通信协议

推荐阅读最新更新时间:2024-03-16 15:39

STM32以太网MAC Loopback的实现
前言 在STM32以太网调试中经常会遇到“设备接收不到数据”,或者“设备发出的数据对端设备收不到”之类的问题。遇到这类问题首先要做的是定位问题发生的部位,这样做的好处就是可以指明下一步调试的方向,缩小分析的范围。以下图为例我们做个简单的说明,设备A和设备B通过以太网通信,现发现设备B无法接收设备A发送的消息,问题可能出现在几个地方: 应用层的程序,或者协议栈出错,数据根本没有到STM32以太网外设。这种情况我们在调试的时候,在以太网输出函数low_level_output中打个断点就可以检查出来。 STM32以太网MAC出现问题,没有把数据发送出去。对于这种情况,可以通过STM32以太网的MAC loopback功能来检查MAC
[单片机]
<font color='red'>STM32</font>以太网MAC Loopback的实现
将不同型号LCD触摸屏移植的相关问题
简介:今日将某著名STM32开发板提供商的应用程序移植到自己的板子上,遇到触摸屏不准的情况,于是查看触摸屏相关控制代码。发现如下。 u16 TPReadX(void) { u16 x=0; TP_CS(); SpiDelay(10); //SPI_WriteByte(0xD0); SPI_WriteByte(0xd0); SpiDelay(20); x=SPI_WriteByte(0x00); x =8; x+=SPI_WriteByte(0x00); SpiDelay(20); TP_DCS(); //x = 3671 - x; x = x 3; return (x); } u16 TPReadY(void) { u1
[单片机]
stm32 SPI 读取和写入的问题
stm32 SPI的读取和写入和USART 一样需要判断标志位 unsigned char SPI1_ReadWrite(unsigned char writedat) { /* Loop while DR register in not emplty */ while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE) == RESET); /* Send byte through the SPI1 peripheral */ SPI_I2S_SendData(SPI1, writedat); /* Wait to receive a byte */ while(SP
[单片机]
stm32 灵活静态存储控制器(FSMC)(NORFLASH\PSRAM)
Flexible static memory controller(FSMC) 今天在处理TFT彩屏的时候突然发现有人用FSMC控制器来处理,然后就认真的研究了下FSMC; 可见他分为4个块,三个类型,我们可以根据自己的需要来选择;这次我就直说FSMC 的Block 1; 首先,基地址BASE_ADDR = 6000 0000;至于片选,datasheet上也说了,我们可以通过控制HADDR(27,26)来选择操作; 然后还有今天一直困扰我的问题,我要选择A16,我用的是16位数据,他的数据地址为6000 0000 + 2^16*2 = 6002 0000;我一直都在疑惑:明明是A16,为什么是第17位被置1,后来
[单片机]
<font color='red'>stm32</font> 灵活静态存储控制器(FSMC)(NORFLASH\PSRAM)
stm32学习笔记---计数器定时中断(1s)
#include tim_driver.h //tim2³õʼ»¯:1ÃëÖÓ¸üÐÂÊý¾Ý void tim2_init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; //ʹÄÜʱÖÓ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
[单片机]
<font color='red'>stm32</font>学习笔记---计数器定时中断(1s)
存储器系统的非对齐访问
我是之前在试验STM32G031G8U6单片机内部FLASH读操作时候发现的这个问题:STM32F103的flash数据可以从任意地址读,而STM32G031G8U6就不行,读数据地址不对齐的话会死机, 关于什么是非对齐访问,可以参考下图1,来源于CM3权威指南CH5相关内容: 图1 先说结论: 1.Cortex-M0内核不支持****非对齐访问 2.Cortex-M3内核支持非对齐访问 3.intel i5支持非对齐访问 4 .是否支持对存储器的非对齐访问取决于具体使用的内核 本次试验的完成耽误了很久,因为最近一周我得新冠了,体质差得新冠了啥也做不了。以下记录了我的 实验验证过程,过程很长, 没
[单片机]
存储器系统的非对齐访问
基于W5500的NetBIOS应用实例
一 实例背景 最近一个做智能家居的朋友面临这样的一个烦恼,他想让用户通过智能手机在家里方便地控制家居设备,又想让用户免除下载安装App的麻烦,通过浏览器直接打开设备内嵌的网页便可实现控制。但是设备的IP地址都是通过家里的路由器自动获得的,设备上又没有屏幕来显示其IP地址。问我有没有办法不输入IP地址来实现浏览器访问该设备网页的办法,就是类似DNS之类,但是无需连外网,只在家庭网络内能访问即可。 这使我想起一个古老的协议,NetBIOS(Network Basic Input/Output System)。这个在上世纪80年代由IBM开发的协议,主要用于数十台左右计算机组成的小型局域网,该协议的主要用途之一就是把计算机名称解
[单片机]
基于W5500的NetBIOS应用实例
基于STM32设计的实时心率检测仪
一、开发环境介绍 主控芯片: STM32F103ZET6 代码编程软件: keil5 心率检测模块: PulseSensor WIFI模块: ESP8266 --可选的。直接使用串口有线传输给上位机也可以。 上位机: C++(QT) 设计的。 支持PC机电脑、Android手机显示。 与上位机的传输协议: 支持串口传输、WIFI网络传输两种。 如果是PC就可以直接连接串口传输数据,如果不方便可以直接通过WIFI---TCP协议传输。 代码下载地址: 心率检测 二、PulseSensor心率模块介绍 PulseSensor 是一款用于脉搏心率测量的光电反射式模拟传感器。 可以将其佩戴于手指、耳垂、手腕
[单片机]
基于<font color='red'>STM32</font>设计的实时心率检测仪
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved