硬件SPI读写W25Q64

STM32的SPI外设

  • STM32内部集成了硬件SPI收发电路,可以由硬件自动执行时钟生成、数据收发等功能,减轻CPU的负担
  • 可配置8位/16位数据帧、高位先行/低位先行
  • 时钟频率:fpclk/(2,4,6,8,16,32,64,128,256)
  • 支持多主机模型、主或从操作
  • 可精简为半双工/单工通信
  • 支持DMA
  • 兼容I2S协议
  • 硬件SPI资源:SPI1、SPI2

SPI基本结构

image-20241117133407446

SS:使用GPIO控制

STM32上的SPI的引脚

SPI1

可以看到SCK、MISO、MOSI分别对应STM32的PA5、PA6、PA7,至于SS一般采用其他的IO口进行控制

下面则是SPI2的引脚

SPI2

程序

相对于硬件SPI,仅修改了SPI.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include "SPI.h"

void MySPI_W_SS(uint8_t BitValue)	//SS 还是使用软件模拟
{
	GPIO_WriteBit(GPIOC, GPIO_Pin_0, (BitAction)BitValue);	//BitAction 非0即1

}

void MySPI_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //	SS:PC0  
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOC, &GPIO_InitStructure);
	
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7; // CLK:PA5  DI/MOSI:PA7
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //MISO:PA6 
	GPIO_Init(GPIOA, &GPIO_InitStructure);



	//SPI初始化
	SPI_InitTypeDef SPI_InitStructure;
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;	//分频  72Mhz/128 
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //第一个边沿采样
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
	SPI_InitStructure.SPI_CRCPolynomial = 7; //手册489页最红有提到默认值为 0x0007
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;	//8位数据帧
	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //双线全双工
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //高位先行
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;	//选择为主机
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
	SPI_Init(SPI1, &SPI_InitStructure);

	SPI_Cmd(SPI1, ENABLE);
	
	//默认给SS输出高电平
	MySPI_W_SS(0);
}


//初始信号
void MySPI_Start(void)
{
	MySPI_W_SS(0);
}

//终止信号
void MySPI_Stop(void)
{
	MySPI_W_SS(1);
}

//通过交换一个字节接收到的数据
uint8_t MySPI_SwapByte(uint8_t ByteSend)
{
	while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE) != SET);		//等待TXE为1
	
	SPI_I2S_SendData(SPI1, ByteSend);															//发送数据,写入DR时会自动清除TXE标志位
	
	while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE) != SET);	//等待RXNE为1
	
	return SPI_I2S_ReceiveData(SPI1);															//接收数据,读DR时会自动清除RXNE标志位
	
	
}
22324
使用 Hugo 构建
主题 StackJimmy 设计