最近学习STM32的SPI功能,经过一段时间的折腾,终于能写入读写数据了。记录一下。
硬件平台:
MCU: STM32F407
FLASH: AT25DF321A
端口:SPI3
先总结一下自己的经验,再贴代码。
1.不能粗心大意。
例如:while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET);语句后有分号,刚开始时,没有注意,结构总是不能收到数据,总是在SPI_I2S_ReceiveData(SPI3);处循环等待。
2.了解原理
刚开始不懂为什么发送数据的时候,经常会发送0xff这个字节,后来了解原理之后才明白,发送这个字节是伪字节,目的是给从机(AT25DF321A)提供时钟。原理网上很多,这里就不贴了。
3.要仔细阅读flash文档
当执行完擦写命令,读出的数据应该是0xff,可总是是0x00,后来通过读状态寄存器发现,原来flash被锁保护,在进行阅读知道怎么去更改状态寄存器解除保护。
本程序是实现读flash的id和写一个字节到指定地址,测试flash是否可用。
以下是相关代码:
//pin
#define SPI_SCLK_PIN GPIO_Pin_10
#define SPI_MISO_PIN GPIO_Pin_11
#define SPI_MISI_PIN GPIO_Pin_12
#define SPI_GPIO_PORT GPIOC
#define SPI_GPIO_CS_PORT GPIOA
#define SPI_GPIO_CS_PIN GPIO_Pin_15
#define SPI_CS_LOW() GPIO_ResetBits(SPI_GPIO_CS_PORT,SPI_GPIO_CS_PIN) //Chip Select pin set low
#define SPI_CS_HIGH() GPIO_SetBits(SPI_GPIO_CS_PORT,SPI_GPIO_CS_PIN) //Chip Select pin set low
//command of AT25
#define CMD_AT25_READ_ID 0x9f
#define CMD_AT25_WRITE_ENABLE 0x06
#define CMD_AT25_PAGE_PROGRAME 0x02
#define CMD_AT25_READ_STATUSREGISTER 0x05
#define CMD_AT25_READ_ARRAY_1B 0x1b
#define CMD_AT25_READ_ARRAY_0B 0x0b
#define CMD_AT25_ERASE_4K 0x20
#define CMD_AT25_WRITE_STATUSREGISTER_BYTE1 0x01
/*******************************************************************************
* Description : Configure SPI GPIO
*******************************************************************************/
static void SPI_GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE);
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = SPI_SCLK_PIN | SPI_MISI_PIN | SPI_MISO_PIN;