STM32 SPI详解

2023-05-16

目录

1、SPI简介

2、SPI特点

2.1、SPI控制方式

2.2、SPI传输方式

2.3、SPI数据交换

2.4、SPI传输模式

3、工作机制

3.1、相关缩写

3.2、CPOL极性

3.3、CPHA相位

3.4、极性和相位图示

3.5 、软件设置极性和相位

4、STM32的SPI控制模块

5、SPI的应用

6、code


1、SPI简介

SPI 规定了两个 SPI 设备之间通信必须由主设备 (Master) 来控制次设备 (Slave). 一个 Master 设备可以通过提供 Clock 以及对 Slave 设备进行片选 (Slave Select) 来控制多个 Slave 设备, SPI 协议还规定 Slave 设备的 Clock 由 Master 设备通过 SCK 管脚提供给 Slave 设备, Slave 设备本身不能产生或控制 Clock, 没有 Clock 则 Slave 设备不能正常工作。

2、SPI特点

2.1、SPI控制方式

采用主-从模式(Master-Slave) 的控制方式。

SPI 规定了两个 SPI 设备之间通信必须由主设备 (Master) 来控制次设备 (Slave). 一个 Master 设备可以通过提供 Clock 以及对 Slave 设备进行片选 (Slave Select) 来控制多个 Slave 设备, SPI 协议还规定 Slave 设备的 Clock 由 Master 设备通过 SCK 管脚提供给 Slave 设备, Slave 设备本身不能产生或控制 Clock, 没有 Clock 则 Slave 设备不能正常工作。

2.2、SPI传输方式

采用同步方式(Synchronous)传输数据

Master 设备会根据将要交换的数据来产生相应的时钟脉冲(Clock Pulse), 时钟脉冲组成了时钟信号(Clock Signal) , 时钟信号通过时钟极性 (CPOL) 和 时钟相位 (CPHA) 控制着两个 SPI 设备间何时数据交换以及何时对接收到的数据进行采样, 来保证数据在两个设备之间是同步传输的。

2.3、SPI数据交换

SPI数据交换框图

上图只是对 SPI 设备间通信的一个简单的描述, 下面就来解释一下图中所示的几个组件(Module):

SSPBUF,Synchronous Serial Port Buffer, 泛指 SPI 设备里面的内部缓冲区, 一般在物理上是以 FIFO 的形式, 保存传输过程中的临时数据;

SSPSR, Synchronous Serial Port Register, 泛指 SPI 设备里面的移位寄存器(Shift Regitser), 它的作用是根据设置好的数据位宽(bit-width) 把数据移入或者移出 SSPBUF;

Controller, 泛指 SPI 设备里面的控制寄存器, 可以通过配置它们来设置 SPI 总线的传输模式。

SPI 设备间的数据传输之所以又被称为数据交换, 是因为 SPI 协议规定一个 SPI 设备不能在数据通信过程中仅仅只充当一个 "发送者(Transmitter)" 或者 "接收者(Receiver)". 在每个 Clock 周期内, SPI 设备都会发送并接收一个 bit 大小的数据, 相当于该设备有一个 bit 大小的数据被交换了. 一个 Slave 设备要想能够接收到 Master 发过来的控制信号, 必须在此之前能够被 Master 设备进行访问 (Access). 所以, Master 设备必须首先通过 SS/CS pin 对 Slave 设备进行片选, 把想要访问的 Slave 设备选上. 在数据传输的过程中, 每次接收到的数据必须在下一次数据传输之前被采样. 如果之前接收到的数据没有被读取, 那么这些已经接收完成的数据将有可能会被丢弃, 导致 SPI 物理模块最终失效. 因此, 在程序中一般都会在 SPI 传输完数据后, 去读取 SPI 设备里的数据, 即使这些数据(Dummy Data)在我们的程序里是无用的。

上面的过程转为动画

初始状态

主机读取一个bit过程

总结:

没有读和写的说法,因为实质上每次SPI是主从设备在交换数据。也就是说,你发一个数据必然会收到一个数据;你要收一个数据必须也要先发一个数据。

2.4、SPI传输模式

上升沿、下降沿、前沿、后沿触发。当然也有MSB和LSB传输方式.

3、工作机制

3.1、相关缩写

SPI的极性Polarity和相位Phase,最常见的写法是CPOL和CPHA,不过也有一些其他写法,简单总结如下:

(1) CKPOL (Clock Polarity) = CPOL = POL = Polarity = (时钟)极性

(2) CKPHA (Clock Phase) = CPHA = PHA = Phase = (时钟)相位

(3) SCK=SCLK=SPI的时钟

(4) Edge=边沿,即时钟电平变化的时刻,即上升沿(rising edge)或者下降沿(falling edge)

对于一个时钟周期内,有两个edge,分别称为:

Leading edge=前一个边沿=第一个边沿,对于开始电压是1,那么就是1变成0的时候,对于开始电压是0,那么就是0变成1的时候;

Trailing edge=后一个边沿=第二个边沿,对于开始电压是1,那么就是0变成1的时候(即在第一次1变成0之后,才可能有后面的0变成1),对于开始电压是0,那么就是1变成0的时候;

3.2、CPOL极性

先说什么是SCLK时钟的空闲时刻,其就是当SCLK在数发送8个bit比特数据之前和之后的状态,于此对应的,SCLK在发送数据的时候,就是正常的工作的时候,有效active的时刻了。

先说英文,其精简解释为:Clock Polarity = IDLE state of SCK。

再用中文详解:

SPI的CPOL,表示当SCLK空闲idle的时候,其电平的值是低电平0还是高电平1:

CPOL=0,时钟空闲idle时候的电平是低电平,所以当SCLK有效的时候,就是高电平,就是所谓的active-high;

CPOL=1,时钟空闲idle时候的电平是高电平,所以当SCLK有效的时候,就是低电平,就是所谓的active-low;

3.3、CPHA相位

首先说明一点,capture strobe = latch = read = sample,都是表示数据采样,数据有效的时刻。相位,对应着数据采样是在第几个边沿(edge),是第一个边沿还是第二个边沿,0对应着第一个边沿,1对应着第二个边沿。

对于:

CPHA=0,表示第一个边沿:

对于CPOL=0,idle时候的是低电平,第一个边沿就是从低变到高,所以是上升沿;

对于CPOL=1,idle时候的是高电平,第一个边沿就是从高变到低,所以是下降沿;

CPHA=1,表示第二个边沿:

对于CPOL=0,idle时候的是低电平,第二个边沿就是从高变到低,所以是下降沿;

3.4、极性和相位图示

图例1

图例2

3.5 、软件设置极性和相位

SPI分主设备和从设备,两者通过SPI协议通讯。

而设置SPI的模式,是从设备的模式,决定了主设备的模式。

所以要先去搞懂从设备的SPI是何种模式,然后再将主设备的SPI的模式,设置和从设备相同的模式,即可正常通讯。

对于从设备的SPI是什么模式,有两种:

1.固定的,有SPI从设备硬件决定的

SPI从设备,具体是什么模式,相关的datasheet中会有描述,需要自己去datasheet中找到相关的描述,即:

关于SPI从设备,在空闲的时候,是高电平还是低电平,即决定了CPOL是0还是1;

然后再找到关于设备是在上升沿还是下降沿去采样数据,这样就是,在定了CPOL的值的前提下,对应着可以推算出CPHA是0还是1了。

2.可配置的,由软件自己设定

从设备也是一个SPI控制器,4种模式都支持,此时只要自己设置为某种模式即可。

然后知道了从设备的模式后,再去将SPI主设备的模式,设置为和从设备模式一样,即可。

对于如何配置SPI的CPOL和CPHA的话,不多细说,多数都是直接去写对应的SPI控制器中对应寄存器中的CPOL和CPHA那两位,写0或写1即可。

4、STM32的SPI控制模块

SPI是英语Serial Peripheral interface的缩写,顾名思义就是串行外围设备接口。是Motorola首先在其MC68HCXX系列处理器上定义的。SPI接口主要应用在EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间。SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议,STM32也有SPI接口。

SPI接口一般使用4条线通信:

MISO  主设备数据输入,从设备数据输出。

MOSI  主设备数据输出,从设备数据输入。

SCLK  时钟信号,由主设备产生。

CS  从设备片选信号,由主设备控制。

SPI主要特点有:可以同时发出和接收串行数据;可以当作主机或从机工作;提供频率可编程时钟;发送结束中断标志;写冲突保护;总线竞争保护等。

STM32的SPI功能很强大,SPI时钟最多可以到18Mhz,支持DMA,可以配置为SPI协议或者I2S协议

关于SPI,从数据手册查到

STM32F207VCT6共有3个SPI。

从下表查出每个SPI对应的管脚

STM32标准外设库SPI_InitTypeDef的定义


typedef struct
{
    uint16_t SPI_Direction; // 设置SPI 的通信方式,可以选择为半双工,全双工,以及串行发和串行收方式
   uint16_t SPI_Mode; // 设置SPI 的主从模式
   uint16_t SPI_DataSize; // 为8 位还是16 位帧格式选择项
   uint16_t SPI_CPOL; // 设置时钟极性
   uint16_t SPI_CPHA; // 设置时钟相位
   uint16_t SPI_NSS;   //设置NSS 信号由硬件(NSS管脚)还是软件控制
   uint16_t SPI_BaudRatePrescaler;  //设置SPI 波特率预分频值
   uint16_t SPI_FirstBit;    //设置数据传输顺序是MSB 位在前还是LSB 位在前
   uint16_t SPI_CRCPolynomial; //设置CRC 校验多项式,提高通信可靠性,大于1 即可
}SPI_InitTypeDef;

第一个参数SPI_Direction 是用来设置SPI的通信方式,可以选择为半双工,全双工,以及串行发和串行收方式,这里我们选择全双工模式SPI_Direction_2Lines_FullDuplex。

第二个参数SPI_Mode用来设置SPI的主从模式,这里我们设置为主机模式 SPI_Mode_Master,当然有需要你也可以选择为从机模式 SPI_Mode_Slave。

第三个参数SPI_DataSiz为8位还是16位帧格式选择项,这里我们是8位传输,选择SPI_DataSize_8b。

第四个参数SPI_CPOL用来设置时钟极性,我们设置串行同步时钟的空闲状态为高电平所以我们选择SPI_CPOL_High。

第五个参数SPI_CPHA 用来设置时钟相位,也就是选择在串行同步时钟的第几个跳变沿(上升或下降)数据被采样,可以为第一个或者第二个条边沿采集,这里我们选择第二个跳变沿,所以选择 SPI_CPHA_2Edge

第六个参数SPI_NSS设置NSS信号由硬件(NSS管脚)还是软件控制,这里我们通过软件控制NSS关键,而不是硬件自动控制,所以选择 SPI_NSS_Soft。

第七个参数 SPI_BaudRatePrescaler很关键,就是设置 SPI 波特率预分频值也就是决定 SPI 的时钟的参数,从不分频道256分频8个可选值,初始化的时候我们选择256分频值SPI_BaudRatePrescaler_256,传输速度为36M/256=140.625KHz。

第八个参数 SPI_FirstBit设置数据传输顺序是 MSB 位在前还是LSB位在前,这里我们选择SPI_FirstBit_MSB高位在前。

第九个参数 SPI_CRCPolynomial是用来设置CRC校验多项式,提高通信可靠性,大于1即可。

示例代码:

void  SPIInit( void )
{
    SPI_InitTypeDef SPI_InitStructure;
    FLASH_GPIO_Init();
    /*!< Deselect the FLASH: Chip Select high */
    GPIO_SetBits( GPIOA, GPIO_Pin_4 );
    /*!< SPI configuration */
    SPI_InitStructure.SPI_Direction     = SPI_Direction_2Lines_FullDuplex;      /* 双线双向全双工 */
    SPI_InitStructure.SPI_Mode      = SPI_Mode_Master;                      /* 主 SPI */
    SPI_InitStructure.SPI_DataSize      = SPI_DataSize_8b;                      /* SPI 发送接收 8 位帧结构 */
    SPI_InitStructure.SPI_CPOL      = SPI_CPOL_High;                        /* 串行同步时钟的空闲状态为高电平 */
    SPI_InitStructure.SPI_CPHA      = SPI_CPHA_2Edge;                       /* 第二个跳变沿数据被采样 */
    SPI_InitStructure.SPI_NSS       = SPI_NSS_Soft;                         /* NSS 信号由软件控制 */
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;             /* 预分频 16 */
 
    SPI_InitStructure.SPI_FirstBit      = SPI_FirstBit_MSB;                     /* 数据传输从 MSB 位开始 */
    SPI_InitStructure.SPI_CRCPolynomial = 7;                                    /* CRC 值计算的多项式 */
    SPI_Init( SPI1, &SPI_InitStructure );
    /*!< Enable the sFLASH_SPI  */
    SPI_Cmd( SPI1, ENABLE );
}

看到这里,可能觉的前面讲原理并没有太大的用处,因为STM32集成了SPI控制器,配置一下即可。

一方面我们学习原理是为了更好的理解SPI,用于对接不同的SPI设备,像norflash的spi驱动网上有大量的例子,不容易出错。但并不是特别常见的,spi驱动SD卡,SPI驱动网络PHY,SPI驱动ESP8266,甚至在设计两个IC通信时,由于没有过多GPIO,又觉的IIC通信速度慢的话,可以设计两个IC之间使用SPI通信,显然这些场景就需要了解SPI的原理

另外一方面,实际应用中,有可能因为芯片其他管脚用于特殊功能,留下的管脚没有硬件SPI功能,只能模拟实现,这个时候学习SPI原理就很有必要了。

5、SPI的应用

SPI的常用应用NorFlash

从数据手册上看到,SPI传输:CKPOL=1 , CKPHA=1

所以STM32的SPI读取NorFlash的配置如下

抓取下面代码波形

抓取的波形如下

0100 1011 就是0X4B

其中看到:

起始电平是高电平,也就是CKPOL=1

第二个边沿采样,也就是CKPHA=1

其实说成类似IIC的高电平有效也是没有问题的

下面这句话是写模拟SPI的核心

自己的理解:在下降沿转换数据,在上升沿采样数据

除了抓取波形,在华邦Flash也看到了时序图

6、code

读取norflash

使用STM32F207硬件SPI模块

/**
  * @brief  Initializes the peripherals used by the SPI FLASH driver.
  * @param  None
  * @retval None
  */
void FLASH_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  
  /*!< Enable the SPI clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
  
  /*!< Enable GPIO clocks */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);  
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); 
  /*!< SPI pins configuration *************************************************/
  
  /*!< Connect SPI pins to AF5 */  
  GPIO_PinAFConfig(GPIOA, 5, GPIO_AF_SPI1);
  GPIO_PinAFConfig(GPIOA, 6, GPIO_AF_SPI1);
  GPIO_PinAFConfig(GPIOB, 5, GPIO_AF_SPI1);
  
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;//GPIO_PuPd_DOWN;
  
  /*!< SPI SCK pin configuration */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  
  /*!< SPI MISO pin configuration */
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  
  /*!< SPI MOSI pin configuration */
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_5;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  
  /*!< Configure sFLASH Card CS pin in output pushpull mode */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOE, &GPIO_InitStructure);
}

/**
  * @brief  Initializes the peripherals used by the SPI FLASH driver.
  * @param  None
  * @retval None
  */
void  FLASH_SPIInit(void)
{  
  
  SPI_InitTypeDef  SPI_InitStructure;
  
  FLASH_GPIO_Init();
  
  /*!< Deselect the FLASH: Chip Select high */
  GPIO_SetBits(GPIOE,GPIO_Pin_12);
  
  /*!< SPI configuration */
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//双线双向全双工
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//主 SPI
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;// SPI 发送接收 8 位帧结构
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;//串行同步时钟的空闲状态为高电平 
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;//第二个跳变沿数据被采样
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//NSS 信号由软件控制
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;//预分频 16
  
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;//数据传输从 MSB 位开始
  SPI_InitStructure.SPI_CRCPolynomial = 7;//CRC 值计算的多项式
  SPI_Init(SPI1, &SPI_InitStructure);
  /*!< Enable the sFLASH_SPI  */
  SPI_Cmd(SPI1, ENABLE);
}

软件模拟SPI协议

/**
  * @brief  Sends a byte through the SPI interface and return the byte received
  *         from the SPI bus.
  * @param  byte: byte to send.
  * @retval The value of the received byte.
  */
uint8_t SPI_ReadWriteByte(uint8_t data)
{
  uint8_t i,data_read = 0;  
  if(data!=0xA5){
    for(i=0;i<8;i++){
      MSPI_CLK_L(); 		                                               
      if(data&0x80){		                                                
	MSPI_MOSI_H();
      }else{
	MSPI_MOSI_L();
      }
      MSPI_DELAY();
      data = data<<1;		                                                
      MSPI_CLK_H(); 		                                                
      MSPI_DELAY();	                                                        
    }
    return data_read;
  }else{
    for(i=0;i<8;i++){
      MSPI_CLK_L();			                                 
      MSPI_DELAY();			                                 
      data_read = data_read<<1;			                               
      MSPI_CLK_H();			                                
      if(MSPI_READ_IN()){	                                                
	data_read |= 0x01;		                               
      }
      MSPI_DELAY();
    }
    return data_read;
  }                                              
}

/**
  * @brief  Initializes the peripherals used by the SPI FLASH driver.
  * @param  None
  * @retval None
  */
void FLASH_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  /*!< Enable GPIO clocks */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);  
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
  
  /*!< Configure sFLASH Card CS pin in output pushpull mode */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOE, &GPIO_InitStructure);
  
  /*!< SPI SCK pin configuration */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  MSPI_CLK_H();
  
  /*!< SPI MOSI pin configuration */
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_5;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  MSPI_MOSI_H();
  
  /*!< SPI MISO pin configuration */
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
}

/**
  * @brief  Initializes the peripherals used by the SPI FLASH driver.
  * @param  None
  * @retval None
  */
void  FLASH_SPIInit(void)
{  
  
  FLASH_GPIO_Init();
  
  /*!< Deselect the FLASH: Chip Select high */
  GPIO_SetBits(GPIOE,GPIO_Pin_12);
}

开源地址:

https://github.com/strongercjd/STM32F207VCT6

点击查看本文所在的专辑,STM32F207教程

关注公众号,第一时间收到文章更新。评论区不能及时看到,需要交流可以到公众号沟通

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32 SPI详解 的相关文章

  • 133-基于stm32单片机停车场车位管理系统Proteus仿真+源程序

    资料编号 133 一 功能介绍 1 采用stm32单片机 4位数码管 独立按键 制作一个基于stm32单片机停车场车位管理系统Proteus仿真 2 通过按键进行模拟车辆进出 并且通过程序计算出当前的剩余车位数量 3 将剩余的车位数量显示到
  • 135-基于stm32单片机超声波非接触式感应水龙头控制系统Proteus仿真+源程序

    资料编号 135 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DHT11传感器 电机 超声波传感器 制作一个基于stm32单片机超声波非接触式感应水龙头控制系统Proteus仿真 2 通过DHT11传感器检测当前
  • Push_back() 导致程序在进入 main() 之前停止

    我正在为我的 STM32F3 Discovery 板使用 C 进行开发 并使用 std deque 作为队列 在尝试调试我的代码 直接在带有 ST link 的设备上或在模拟器中 后 代码最终在 main 中输入我的代码之前在断点处停止 然
  • STM32F4 通过软复位跳转到引导加载程序,无需 BOOT0 和 BOOT1 引脚

    我问这个问题是因为可以在这里找到类似问题的答案 通过应用程序跳转到 STM32 中的引导加载程序 即从用户闪存在引导模式下使用引导 0 和引导 1 引脚 用户 JF002 JF002回答 当我想跳转到引导加载程序时 我在其中一个备份寄存器中
  • 匹配 STM32F0 和 zlib 中的 CRC32

    我正在研究运行 Linux 的计算机和 STM32F0 之间的通信链路 我想对我的数据包使用某种错误检测 并且由于 STM32F0 有 CRC32 硬件 并且我在 Linux 上有带有 CRC32 的 zlib 所以我认为在我的项目中使用
  • STM32F103

    提示 来源正点原子 参考STM32F103 战舰开发指南V1 3PDF资料 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 提示 这里可以添加本文要记录的大概内容 开发环境硬件普中科技 接线图在g
  • 物联网网关

    物联网网关是 连接物联网设备和互联网的重要桥梁 它负责将物联网设备采集到的数据进行处理 存储和转发 使其能够与云端或其它设备进行通信 物联网网关的作用是实现物联网设备与云端的无缝连接和数据交互 物联网网关功能 数据采集 物联网网关可以从物联
  • STM32 GPIO工作原理详解

    STM32 GPIO介绍 1 STM32引脚说明 GPIO是通用输入 输出端口的简称 是STM32可控制的引脚 GPIO的引脚与外部硬件设备连接 可实现与外部通讯 控制外部硬件或者采集外部硬件数据的功能 以STM32F103ZET6芯片为例
  • [屏驱相关]【SWM166-SPI-Y1.28C1测评】+ 有点惊艳的开箱

    耳闻华芯微特许久了 看到论坛得评测活动赶紧上了末班车 毕竟对有屏幕得板子也是很喜欢得 京东快递小哥客客气气 微笑着把快递给了我 好评 直接拆了包 在此之前没看过视频号 所以这个圆盘盘得模具还是有点惊喜的 正面照如下 开机有灯光秀 还有动画
  • VS Code 有没有办法导入 Makefile 项目?

    正如标题所说 我可以从现有的 Makefile 自动填充 c cpp properties json 吗 Edit 对于其他尝试导入 makefile 的人 我找到了一组脚本 它们完全可以实现我想要实现的目标 即通过 VS Code 管理
  • 1.69寸SPI接口240*280TFT液晶显示模块使用中碰到的问题

    1 69寸SPI接口240 280TFT液晶显示模块使用中碰到的问题说明并记录一下 在网上买了1 69寸液晶显示模块 使用spi接口 分辨率240 280 给的参考程序是GPIO模拟的SPI接口 打算先移植到FreeRtos测试 再慢慢使用
  • STM32F207 I2C 测试失败

    我正在使用 STM32F207 微控制器在 STM3220G EVAL 板上学习嵌入式开发 我尝试通过连接同一芯片上的两个 I2C2 和 I2C3 模块并发送 接收字符来测试 I2C 接口 这是我当前编写的代码 使用 mdk arm 5 i
  • Spidev 不使用 ioctl 同时写入/读取

    我希望找到一些帮助 即使这个问题可能更多地与硬件相关而不是与软件相关 我们将会看到 我正在开发基于 Freescales P1021 处理器 ppc e500v2 内核 的定制板 将连接外部 PCB 并可通过 SPI 进行配置 该外部 PC
  • 树莓派 pico rfid rc522 (Micropython)

    我想使用 RPi Pico 从 mfrc522 Iduino RFID rc522 读卡器读取数据 但我不知道如何操作 我试图使用为此目的制作的 mfrc522 py MicroPython 库 阅读器正在通过 SPI 与 Pi 通信 我将
  • 特殊寄存器

    特殊寄存器 文章目录 前言 一 背景 二 2 1 2 2 总结 前言 前期疑问 STM32特殊寄存器到底是什么 特殊寄存器怎么查看和调试代码 本文目标 记录和理解特殊寄存器 一 背景 最近在看ucosIII文章是 里面提到特殊寄存器 这就进
  • 嵌入式 C++11 代码 — 我需要 volatile 吗?

    采用 Cortex M3 MCU STM32F1 的嵌入式设备 它具有嵌入式闪存 64K MCU固件可以在运行时重新编程闪存扇区 这是由闪存控制器 FMC 寄存器完成的 所以它不像a b那么简单 FMC 获取缓冲区指针并将数据刻录到某个闪存
  • STM32F0、ST-link v2、OpenOCD 0.9.0:打开失败

    我在用着发射台 http www ti com ww en launchpad about htmlgcc arm none eabi 4 9 2015q2 为 STM32F0 进行编译 现在我想使用该集合中的 arm none eabi
  • 哪些变量类型/大小在 STM32 微控制器上是原子的?

    以下是 STM32 微控制器上的数据类型 http www keil com support man docs armcc armcc chr1359125009502 htm http www keil com support man d
  • 如何用 C 语言从串行(SPI)连接读取数据?

    我正在尝试编写一个程序 该程序将安装在 Linux MCU Raspberry Pi 上 该程序将读取从另一个 MCU 我将自己构建的自制程序 发送到它的串行数据 我研究了如何做到这一点 并认为我有 大局 但仍然缺少一些东西 其一 我需要启
  • stm32l0: 执行MI命令失败。使用 vFlashErase 数据包擦除闪存时出错

    我正在使用 Nucleo STM32L031 和 AC6 STM32 工作台 eclipse 我编写应用程序并进入调试模式 一切正常 直到我在应用程序中添加另一个功能 我注意到当我删除 评论 新函数 软件可以再次进入调试模式 但是当我添加

随机推荐

  • STM32片上Flash内存映射、页面大小、寄存器映射

    本文以STM32F103RBT6为例介绍了片上Flash Embedded Flash 若干问题 xff0c 包括Flash大小 内存映射 块大小 页面大小 寄存器 二 块大小 Flash先分块再分页 xff0c 擦除是按块进行 xff0c
  • keil 修改RAM、ROM

  • 单片机flash不足,keil如下方式进行优化

    单片机的flash不够的时候可以使用keil的优化等级进行优化 xff1b 但是使用Opt进行优化的时候会遇到难以预料的错误 xff0c 所以使用时要对一些变量进行标识 xff0c 比如使用volatile关键字 还有其他方式也能减少内存的
  • msp430看门狗定时器

    看门狗定时器用来防止程序因供电电源 空间电磁干扰或其它原因引起的强烈干扰噪声而跑飞的事故 在很多单片机中都内置了看门狗 xff0c 看门狗本身是一个定时器 xff0c 当定时器溢出时即进行系统复位 xff0c 因此需要在程序中对看门狗定时器
  • UART、SPI和IIC详解与比较(超级实用的调试经验)

    1 UART UART有4个pin xff08 VCC GND RX TX xff09 用的TTL电平 低电平为0 0V xff0c 高电平为1 xff08 3 3V或以上 xff09 UART使用的是异步串行通信 UART是两线 xff0
  • RS232、RS485和CAN协议总结与对比

    一 RS232串口是计算机上一种非常通用的设备通信协议 串口的电气特性 xff1a 1 RS 232串口通信最远距离是50英尺 xff1b 2 RS232可做到双向传输 xff0c 全双工通讯 xff0c 最高传输速率20kbps xff1
  • STM32 GPIOx_CRL/GPIOx_CRH 寄存器

    GPIOx CRL GPIOx CRH xff08 x xff1a A F xff09 寄存器用来对GPIO进行端口设置 xff0c 如 xff1a 设置GPIO为输入模式或输出模式 每个寄存器含有32位 xff0c 每4位用来设置1个GP
  • SHT10 温湿度传感器的程序以及调试总结

    没有其他东西 直接上调试注意事项和代码 xff01 xff01 调试要点 xff1a 1 DATA加10K上拉电阻 2 注意示波器观察各个信号 基础要点 xff1a 1 串行时钟输入 xff08 SCK xff09 单片机模拟时钟 2 串行
  • 晶振原理解析

    目录 01 压电效应 02 晶体振荡器的应用 03 无源晶振和有源晶振的区别 04 STM32外接晶振 下文将进一步讲解晶振的原理 xff0c 以及晶振和STM32的关系 01 压电效应 压电效应 xff1a 某些电介质在沿一定方向上受到外
  • 字符串大小的比较

    字符串大小比较的步骤 xff1a 从左至右一位一位比较 xff0c 如果相同 xff0c 则继续下一位 xff0c 如果不同 xff0c 则谁的ASCII大谁的字符串就大如果比较到其中一者已经结束了 xff0c 还没有分出大小 xff0c
  • STM32延时函数的四种方法

    目录 1 普通延时 2 定时器中断 3 查询定时器 4 汇编指令 单片机编程过程中经常用到延时函数 xff0c 最常用的莫过于微秒级延时delay us 和毫秒级delay ms 本文基于STM32F207介绍4种不同方式实现的延时函数 1
  • STM32的FSMC外设简介

    目录 01 FSMC特点 02 AHB接口 03 外部设备地址映射 04 NOR PSRAM控制器 05 外部存储器接口信号 06 NOR PSRAM控制器异步事务 07 模式1 08 模式A 09 代码说明 01 FSMC特点 Flexi
  • STM32使用DMA接收串口数据

    目录 01 概述 02 DMA接收 03 中断 04 代码 01 概述 在之前的文章里 STM32串口详解 和 STM32 DMA详解 文章中 xff0c 详细讲解了STM32的串口和DMA外设 xff0c 本篇文章将不在细述串口和DMA的
  • 指针与数组

    1 定义 指针 xff1a C语言中某种数据类型的数据存储的内存地址 xff0c 例如 xff1a 指向各种整型的指针或者指向某个结构体的指针 数组 xff1a 若干个相同C语言数据类型的元素在连续内存中储存的一种形态 数组在编译时就已经被
  • 关于软件定时器的一些讨论

    1 简介 这里先介绍下软件定时器和硬件定时器的区别 硬件定时器 xff1a CPU内部自带的定时器模块 xff0c 通过初始化 配置可以实现定时 xff0c 定时时间到以后就会执行相应的定时器中断处理函数 硬件定时器一般都带有其它功能 xf
  • 表驱动法在STM32中的应用

    1 概念 所谓表驱动法 Table Driven Approach 简而言之就是用查表的方法获取数据 此处的 表 通常为数组 xff0c 但可视为数据库的一种体现 根据字典中的部首检字表查找读音未知的汉字就是典型的表驱动法 xff0c 即以
  • 关于共享资源保护的思考

    1 引言 先聊聊分享这篇文章的原因 xff0c 在使用STM32时 xff0c 我发现对于GPIO输出操作 xff0c 可以使用GPIOx ODR寄存器 xff0c 也可以使用GPIOx BSRR寄存器 对应的标准外设库API接口有 voi
  • 预编译#error的使用

    1 引言 说到预编译 xff0c 大家立刻就能想到 define if ifdef和 ifndef等熟悉的预编译命令 其实 include xff0c 我们通常放在源文件用来包含头文件 xff0c 它也是预编译命令 当然这不是这篇文章的重点
  • STM32 IIC详解

    目录 1 IIC定义 2 IIC协议规范 2 1 SDA和SCL信号 2 2 数据有效性 2 3 开始和结束信号 2 4 字节格式 2 5 从机地址和读写位 3 计算IIC的频率 4 PCF8536 4 1 Acknowledge 4 2
  • STM32 SPI详解

    目录 1 SPI简介 2 SPI特点 2 1 SPI控制方式 2 2 SPI传输方式 2 3 SPI数据交换 2 4 SPI传输模式 3 工作机制 3 1 相关缩写 3 2 CPOL极性 3 3 CPHA相位 3 4 极性和相位图示 3 5