STM32 进阶 SPI外设读写Flash 寄存器代码书写

目录

SPI外设

SPI外设框图

需求描述

硬件电路设计

相关寄存器

文字说明:

spi.h

spi.c

 W25Q32.h


SPI外设

与I2C外设一样,STM32芯片也集成了专门用于SPI协议通讯的外设。

STM32 的 SPI 外设可用作通讯的主机及从机,支持最高的 SCK 时钟频率为 fpclk/2 (STM32F103 型号的芯片默认fpclk1为36MHz,fpclk2为72MHz。),完全支持 SPI 协议的 4 种模式,数据帧长度可设置为 8 位或 16 位,可设置数据 MSB 先行或 LSB 先行。它还支持双线全双工、双线单向以及单线模式。

STM32F103系列提供了3个SPI,SPI1挂在APB2总线,SPI2/3挂在APB1总线。

其中双线单向模式可以同时使用 MOSI 及 MISO 数据线向一个方向传输数据,可以加快一倍的传输速度。而单线模式则可以减少硬件接线,当然这样速率会受到影响。

用的比较多还是双线全双工模式。

SPI外设框图

因为NSS只有一个,如果需要其他设备的话解决办法就是:

禁用NSS,用GPIO引脚配置通用推挽,让其和SPI相连,用其进行控制SPI

需求描述

基于寄存器操作,使用SPI功能,完成Flash的读写。

硬件电路设计

 

相关寄存器

SPI_CR1:spi控制寄存器

MSTR:主设备选择

BR:波特率控制

CPOL:时钟极性

CPHA: 时钟相位

DFF:数据帧格式

SSI:内部从设备选择

LSBFIRST:帧格式

SSM:软件从设别管理

SSI:内部从设备管理

SPE:SPI使能

SPI_DR 数据寄存器

16位

SPI_SR:状态寄存器

TXE:发送缓冲为空

RXNE:接收缓冲非空

文字说明:

 

spi.h

#ifndef __SPI_H__
#define __SPI_H__

#include "stm32f10x.h"

#define CS_HIGH (GPIOC->ODR |= GPIO_ODR_ODR13)
#define CS_LOW (GPIOC->ODR &= ~ GPIO_ODR_ODR13)

void SPI_Init(void);

void SPI_Start(void);

void SPI_Stop(void);

uint8_t SPI_SwapByte(uint8_t byte);

#endif /* __SPI_H__ */

spi.c

#include "spi.h"

void SPI_Init(void){
    // 1. GPIOA
    // 1.1 先放时钟
    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;

    // 1.2 PA5 时钟 复用推挽
    GPIOA->CRL &= ~GPIO_CRL_CNF5_0;
    GPIOA->CRL |= GPIO_CRL_CNF5_1;
    GPIOA->CRL |= GPIO_CRL_MODE5;
    // 1.3 PA6 输入信号 浮空输入
    GPIOA->CRL &= ~GPIO_CRL_CNF6_1;
    GPIOA->CRL |= GPIO_CRL_CNF6_0;
    GPIOA->CRL &= ~GPIO_CRL_MODE6;
    // 1.4 PA7 数据输出 复用推挽
    GPIOA->CRL &= ~GPIO_CRL_CNF7_0;
    GPIOA->CRL |= GPIO_CRL_CNF7_1;
    GPIOA->CRL |= GPIO_CRL_MODE7;

    // 2. GPIOC
    // 2.1 放GPIOC的时钟
    RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
    CS_HIGH;
    // 2.2. PC13 片选使能信号 通用推挽
    GPIOC->CRH &= ~GPIO_CRH_CNF13;
    GPIOC->CRH |= GPIO_CRH_MODE13;


    //配置硬件SPI
    //0.1放时钟
    RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
    //0.2 设置DFF位来定义8位或者16位数据格式 当前8位
    SPI1->CR1 &= ~SPI_CR1_DFF;
    //0.3 设置高位优先
    SPI1->CR1 &= ~SPI_CR1_LSBFIRST;
    //0.4 工作模式为主模式
    SPI1->CR1 |= SPI_CR1_MSTR;
    //0.5 波特率的配置 APB2 72M 如果是 000 就是2分频 36M
    SPI1->CR1 &= ~SPI_CR1_BR;
    //0.6 mode0 模式
    SPI1->CR1 &= ~SPI_CR1_CPOL;
    SPI1->CR1 &= ~SPI_CR1_CPHA;
    //0.7 SSOE 配0 这样的话 会关闭SS引脚的输出 同时 会被迫进入
    //多主模式(NSS 会变成一个输入引脚)
    SPI1->CR2 &= ~SPI_CR2_SSOE;
    //0.8 NSS 进入软件模式
    //          SSM 配1 那就是NSS信号 由SSI位来决定
    SPI1->CR1 |= SPI_CR1_SSM;
    //          SSI 配1 再多主模式里 一直处于可通讯状态
    SPI1->CR1 |= SPI_CR1_SSI; 
    // 使能位
    SPI1->CR1 |= SPI_CR1_SPE;
}

void SPI_Start(void){
    CS_LOW;
}

void SPI_Stop(void){
    CS_HIGH;
}

uint8_t SPI_SwapByte(uint8_t byte){
    while (!(SPI1->SR & SPI_SR_TXE))
    {
    }
    SPI1->DR = byte;
    while (!(SPI1->SR & SPI_SR_RXNE))
    {
    }
    uint8_t receive_byte = SPI1->DR;
    return receive_byte;
}

 W25Q32.h

#include "spi.h"

其他不变

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雁过留声花欲落

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值