这是一个SPI读写AT45DB32的函数 #define DUMMY_BYTE 0xA5 void Flash_ReadString(unsigned int pageaddr, unsigned int byteaddr, unsigned char *strp,unsigned char len) { #if (BYTES_PER_PAGE == 512) pageaddr = pageaddr << 1; #else pageaddr = pageaddr << 2; #endif ENABLE_FLASH; SPI_Byte(0xE8); //Continuous Array Read SPI_Byte(HighByte(pageaddr)); SPI_Byte(LowByte(pageaddr)+HighByte(byteaddr)); SPI_Byte((unsigned char)byteaddr); SPI_Byte(DUMMY_BYTE); SPI_Byte(DUMMY_BYTE); SPI_Byte(DUMMY_BYTE); SPI_Byte(DUMMY_BYTE); for(; len; len--) { *strp++ = SPI_Byte(DUMMY_BYTE); } DISABLE_FLASH; return; }
这个函数在C8051F023上成功.C8051F023的SPI Master模式, 发送一个数据的时候同时会吧MISO上的数据移进寄存器, 在发完的时候读取就可以. unsigned char SPI_Byte(unsigned char databyte) reentrant { SPI0DAT = databyte; while (TXBSY); SPIF = 0; return SPI0DAT; }
在STM32F103上面也应该是这样的 我是这样实现的. unsigned char SPI_Byte(unsigned char ch) { SPI1->DR = ch; while((SPI1->SR & (~0x02)) == 0);//等待发送完成 while((SPI1->SR & (~0x01)) == 0);//等待数据放入RX_Buf return SPI1->DR; } SPI的配置: void SPI1_Config(void) { SPI_InitTypeDef SPI_InitStruct; 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_High; SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge; SPI_InitStruct.SPI_NSS = SPI_NSS_Hard; SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStruct.SPI_CRCPolynomial = 7; SPI_Init(SPI1, &SPI_InitStruct); //SPI_DMACmd(SPI1, SPI_DMAReq_Tx, ENABLE); SPI_Cmd(SPI1, ENABLE); }
AT45DB32连续读操作要求在发送完地址后要发送32个CLK, 如下. SPI_Byte(DUMMY_BYTE); SPI_Byte(DUMMY_BYTE); SPI_Byte(DUMMY_BYTE); SPI_Byte(DUMMY_BYTE); 在C8051F023上没问题.
但是在STM32F103 我必须发送5个DUMMY_BYTE, SPI_Byte(DUMMY_BYTE); SPI_Byte(DUMMY_BYTE); SPI_Byte(DUMMY_BYTE); SPI_Byte(DUMMY_BYTE); SPI_Byte(DUMMY_BYTE); 要不然每次读到的第一个数据都是0xFF, 第二个数据才是真正要读的第一个数据, 第一个数据并不是丢掉了.
|