SPI 实验

下面这些图来自b站,理解了这几张图,基本就懂了SPI,   ps:深入理解SPi通讯协议,5分钟看懂!_哔哩哔哩_bilibili 

 SPI:

  • SCK = Serial Clock = This line is used for clock pulses to synchronize data transmission from Master devices
  • MOSI = Master Out Slave In = This line is used for sending data from Master device to Slave devices.
  • MISO = Master In Slave Out = This line is used for sending data from Slave devices to Master device.
  • SS = Slave Select = This pin is used by Master device to enable and disable specific devices to communicate with only some number of devices out of all.

(时钟信号) 

 

 

完整实验安装下文操作即可:

ps:SPI Communication Between Two Arduino Boards SPI Communication Between Two Arduino Boards - Arduino SPI Guide

主从的代码略改写了一下,增加了注释等: SPI.h? 内置的,可以直接用。

#include <SPI.h>  
  
// 定义引脚号  
#define PUSH_BUTTON 2  
#define LED_PIN 4  
#define SS_PIN 10  // 假设SS引脚连接到数字引脚10,这取决于你的硬件设置  
  
// 声明变量  
int pushButtonValue;  
int ledState;  
byte masterSend, masterReceive;  
  
void setup() {  
  Serial.begin(115200);  // 初始化串口通信  
    
  pinMode(PUSH_BUTTON, INPUT);  // 设置按钮引脚为输入模式  
  pinMode(LED_PIN, OUTPUT);     // 设置LED引脚为输出模式  
  pinMode(SS_PIN, OUTPUT);      // 设置SS引脚为输出模式,用于控制从设备  
    
  SPI.begin();  // 初始化SPI总线  
  SPI.setClockDivider(SPI_CLOCK_DIV8);  // 设置SPI时钟分频  
  digitalWrite(SS_PIN, HIGH);  // 初始时将SS引脚拉高,防止SPI通信意外启动  
}  
  
void loop() {  
  // 读取按钮状态  
  pushButtonValue = digitalRead(PUSH_BUTTON);  
    
  // 根据按钮状态设置要发送的数据  
  if (pushButtonValue == HIGH) {  
    masterSend = 1;  // 按钮被按下,发送1  
  } else {  
    masterSend = 0;  // 按钮未被按下,发送0  
  }  
    
  // 拉低SS引脚,启动SPI通信  
  digitalWrite(SS_PIN, LOW);  
    
  // 通过SPI发送数据并接收从设备返回的数据  
  masterReceive = SPI.transfer(masterSend);  
    
  // 根据接收到的数据控制LED  
  if (masterReceive == 1) {  
    ledState = HIGH;  // 如果从设备返回1,点亮LED  
  } else {  
    ledState = LOW;   // 如果从设备返回0,熄灭LED  
  }  
    
  digitalWrite(LED_PIN, ledState);  // 设置LED状态  
    
  // 延时一秒后再次检测按钮状态  
  delay(1000);  
    
  // 拉高SS引脚,结束SPI通信  
  digitalWrite(SS_PIN, HIGH);  
}

从机:略

stm32:

在STM32上使用SPI(Serial Peripheral Interface)来读写存储芯片(如Flash, EEPROM等)是一个常见的任务。这里我将给出一个简化的示例,展示如何使用STM32 HAL库来配置SPI并读写一个简单的EEPROM(如AT24C系列)。请注意,虽然示例是针对EEPROM的,但大多数SPI设备的读写逻辑是类似的。

步骤 1: 初始化SPI

首先,你需要使用STM32CubeMX或手动配置SPI接口的相关参数(如时钟极性CPOL、时钟相位CPHA、数据位长度等)。以下是一个使用STM32 HAL库初始化SPI的基本示例。

#include "stm32f1xx_hal.h"  
  
SPI_HandleTypeDef hspi1;  
  
void MX_SPI1_Init(void)  
{  
    hspi1.Instance = SPI1;  
    hspi1.Init.Mode = SPI_MODE_MASTER;  
    hspi1.Init.Direction = SPI_DIRECTION_2LINES;  
    hspi1.Init.DataSize = SPI_DATASIZE_8BIT;  
    hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;  
    hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;  
    hspi1.Init.NSS = SPI_NSS_SOFT;  
    hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;  
    hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;  
    hspi1.Init.TIMode = SPI_TIMODE_DISABLE;  
    hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;  
    hspi1.Init.CRCPolynomial = 7;  
    HAL_SPI_Init(&hspi1);  
}

步骤 2: 编写SPI读写函数

对于EEPROM,你可能需要发送设备地址和内存地址(取决于EEPROM的类型),然后读取或写入数据。

#define EEPROM_CS_GPIO_Port GPIOC  
#define EEPROM_CS_Pin GPIO_PIN_13  
  
void EEPROM_CS_LOW(void)  
{  
    HAL_GPIO_WritePin(EEPROM_CS_GPIO_Port, EEPROM_CS_Pin, GPIO_PIN_RESET);  
}  
  
void EEPROM_CS_HIGH(void)  
{  
    HAL_GPIO_WritePin(EEPROM_CS_GPIO_Port, EEPROM_CS_Pin, GPIO_PIN_SET);  
}  
  
// 发送一个字节  
void EEPROM_WriteByte(uint8_t byte)  
{  
    HAL_SPI_Transmit(&hspi1, &byte, 1, HAL_MAX_DELAY);  
}  
  
// 读取一个字节  
uint8_t EEPROM_ReadByte(void)  
{  
    uint8_t byte = 0xFF;  
    HAL_SPI_Receive(&hspi1, &byte, 1, HAL_MAX_DELAY);  
    return byte;  
}  
  
// 写入一个字节到EEPROM  
void EEPROM_WriteData(uint16_t devAddress, uint16_t memAddress, uint8_t data)  
{  
    // 根据EEPROM的协议发送设备地址和内存地址  
    // 这里只是一个示例,具体取决于EEPROM的数据手册  
    EEPROM_CS_LOW();  
    // 发送设备地址  
    EEPROM_WriteByte(0xA0); // 假设的设备地址和写指令  
    // 发送内存地址  
    EEPROM_WriteByte(memAddress >> 8);  
    EEPROM_WriteByte(memAddress & 0xFF);  
    // 发送数据  
    EEPROM_WriteByte(data);  
    EEPROM_CS_HIGH();  
}  
  
// 从EEPROM读取一个字节  
uint8_t EEPROM_ReadData(uint16_t devAddress, uint16_t memAddress)  
{  
    uint8_t data;  
      
    EEPROM_CS_LOW();  
    // 发送设备地址和读指令  
    EEPROM_WriteByte(0xA1); // 假设的设备地址和读指令  
    // 发送内存地址  
    EEPROM_WriteByte(memAddress >> 8);  
    EEPROM_WriteByte(memAddress & 0xFF);  
    // 读取数据  
    data = EEPROM_ReadByte();  
    EEPROM_CS_HIGH();  
      
    return data;  
}
注意事项
  • 上述代码示例基于假设的EEPROM设备地址和指令。你需要根据你所使用的EEPROM的数据手册来调整这些值。
  • 确保在发送或接收数据之前,通过GPIO控制CS(Chip Select)引脚来选中EEPROM设备。
  • 根据EEPROM的要求,可能需要额外的延时来等待操作完成。
  • 以上代码未包含错误检查或处理,实际使用中应添加适当的错误处理逻辑。

总结

这是一个基本的STM32 SPI读写EEPROM的示例。你需要根据具体的硬件和EEPROM的数据手册来调整代码中的参数和指令。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值