硬件SPI和软件模拟SPI在配置方面的一点区别

一 硬件SPI和软件SPI

顾名思义这种方式是硬件层面的,需要开启并使用单片机里面的SPI外设,IO口要复用到外设,由外设来控制电平翻转;软件模拟就可以随便选择IO口进行配置,需要手动控制电平翻转

硬件接线:

我使用的是外接Flash模块无论是硬件还是软件接线都使用的是相同的IO口

对应关系:

A4-CS

A5-SCK时钟线

A6-MISO-D0

A7-MOSI-D1 接线口诀:主机MOSI接从机DI 主机 MISO接从机DO

二 配置GPIO

配置IO文字描述:

配置GPIO口

把CS SCK MOSI配置为推挽输出

把MISO配置为浮空输入

默认CS高电平抬起不选中状态

硬件版本

void W25Q_SPI_Init(void)

{

GPIO_InitTypeDef GPIO_InitStruct;

SPI_InitTypeDef SPI_InitStruct;

// 开启时钟:GPIOA、SPI1(SPI1属于APB2)

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1, ENABLE);

// PA5 SCK、PA7 MOSI:复用推挽输出 AF_PP

GPIO_InitStruct.GPIO_Pin = SPI_SCK_PIN | SPI_MOSI_PIN;

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(SPI_GPIO_PORT, &GPIO_InitStruct);

// PA6 MISO:浮空输入

GPIO_InitStruct.GPIO_Pin = SPI_MISO_PIN;

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_Init(SPI_GPIO_PORT, &GPIO_InitStruct);

// PA4 CS:普通推挽输出

GPIO_InitStruct.GPIO_Pin = FLASH_CS_PIN;

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(FLASH_CS_PORT, &GPIO_InitStruct);

FLASH_CS_H(); // 默认片选拉高,不选中Flash

// SPI配置

SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;

SPI_InitStruct.SPI_Mode = SPI_Mode_Master;

SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;

SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low; // CPOL=0 空闲SCK低

SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge; // CPHA=0 第一个边沿采样(Mode0)

SPI_InitStruct.SPI_NSS = SPI_NSS_Soft; // 软件管理片选

SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; //72M/4=18M

SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB; //高位先发,Flash强制要求

SPI_InitStruct.SPI_CRCPolynomial = 7;

SPI_Init(SPI1, &SPI_InitStruct); //硬件SPI必须调用SPI_Init

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

}

软件模拟版本

//软件模拟SPI初始化

void W25Q_SPI_Init(void)

{

GPIO_InitTypeDef GPIO_InitStruct;

// 只开启GPIOA时钟,删掉SPI1时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

// SCK PA5、MOSI PA7:推挽输出

GPIO_InitStruct.GPIO_Pin = SPI_SCK_PIN | SPI_MOSI_PIN;

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(SPI_GPIO_PORT, &GPIO_InitStruct);

// MISO PA6:浮空输入

GPIO_InitStruct.GPIO_Pin = SPI_MISO_PIN;

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_Init(SPI_GPIO_PORT, &GPIO_InitStruct);

// CS PA4:推挽输出

GPIO_InitStruct.GPIO_Pin = FLASH_CS_PIN;

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(FLASH_CS_PORT, &GPIO_InitStruct);

FLASH_CS_H(); // 默认片选拉高

}

三 收发字节函数的区别

收发字节文字描述:

发送一字节数据

函数有返回值因为是全双工 有发送就有接收

要发送的数据作为函数参数传入

通过循环从最高位开始发送数据

每次都要提取出最高位数据进行发送

然后发送数据左移一位

选择模式0 就是上升沿采样

SCK输出高电平,保持不变

读取MISO电平,进行或操作拼接接收电平数据

SCK输出低电平 停止采样

保持一段时间后,进行下一轮数据的发送和读取

硬件版本

uint8_t SPI_RW_Byte(uint8_t txDat)

{

//等待发送缓冲区为空

while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);

SPI_I2S_SendData(SPI1, txDat);

//等待接收完成

while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);

return SPI_I2S_ReceiveData(SPI1);

}

软件模拟版本

uint8_t SPI_RW_Byte(uint8_t txdata)

{

uint8_t i;

uint8_t rxData = 0;

for(i = 0;i<8;i++){

if(txdata & 0x80){

GPIO_SetBits(SPI_GPIO_PORT, SPI_MOSI_PIN);

}else{

GPIO_ResetBits(SPI_GPIO_PORT, SPI_MOSI_PIN);

}

txdata <<= 1;

GPIO_SetBits(SPI_GPIO_PORT, SPI_SCK_PIN);

delay_us(2);//延时函数可以去掉 我加上是为了健壮性

rxData <<= 1;

if(GPIO_ReadInputDataBit(SPI_GPIO_PORT, SPI_MISO_PIN)){

rxData |= 0x01;

}

GPIO_ResetBits(SPI_GPIO_PORT, SPI_SCK_PIN);

delay_us(2);//同理,为了健壮性

}

return rxData;

}

这个SPI手写时序虽然最开始也是参照AI和现成代码写出来的,但是我会一行一行的理解,然后独立参照datasheet写出来,刚开始接触的时候确实感觉很难,但现在感觉好一点了

相关推荐
LCG米3 小时前
STM32硬件SPI驱动SSD1306 OLED实测:上电黑屏排查、页寻址模式与取模扫描方向陷阱
stm32·单片机·嵌入式硬件·嵌入式
深圳老胡4 小时前
STM32C5A3ZG 网络调试总结:从启动失败到连续 Ping 稳定
笔记·stm32·单片机·代码规范
qq_401700414 小时前
100 个 IoT 小项目,给 ESP32 入门补上实操
前端·网络·stm32
硅基造物主4 小时前
STM32 从 0 到 1 做智能家居(八):PWM 控制风扇、加热片与 SG90 窗帘
stm32·嵌入式硬件·智能家居·hal库·pwm
简单电磁炮4 小时前
关于adc采集
stm32·单片机
意法半导体STM325 小时前
【官方原创】如何在STM32CubeMX2中使用UART
stm32·单片机·嵌入式硬件
白搞电子7 小时前
ESP-Mosaico 轮滑动画编排台:拍点吸附、完整动作编辑与工程保存
单片机·嵌入式硬件·电脑
玄芯散人8 小时前
【元婴·114】SD卡和FatFS文件系统:数据持久化
stm32·sd卡·fatfs
从小白到软工8 小时前
5-2 从查表到控件:造按钮
c语言·开发语言·数据结构·经验分享·ai编程
水饺编程8 小时前
第2章:Linux 基础,解压缩【.tar.gz】压缩包
linux·c语言·汇编