之前做了一个使用底层SPI读写铁电SRAM试验,由于本次使用的单片机IO口较少,底层SPI的IO口也被其他功能使用,没办法了,只能模拟SPI与铁电SRAM进行通信。在网上找了一段代码进行修改,然后调试时发现写入的数据,读出来之后是之前的写入数据的2倍;经调试发现是将一个字节数据,读写了9次,将小于等于修改成小于就通过啦。虽然通过了,但是写程序的时候还是需要细心,否则还是容易出现问题。
#ifndef __SPI_FLASH_H
#define __SPI_FLSH_H
#include "stm32f10x.h"
#define SPI_FLASH_PageSize 256
#define WRITE 0x02 ///* Write to Memory instruction */
#define WRSR 0x01 ///* Write Status Register instruction */
#define WREN 0x06 ///* Write enable instruction */
#define READ 0x03 ///* Read from Memory instruction */
#define RDSR 0x05 ///* Read Status Register instruction */
#define RDID 0x9F ///* Read identification */
#define SE 0xD8 ///* Sector Erase instruction */
#define BE 0xC7 ///* Bulk Erase instruction */
#define WIP_Flag 0x01 ///* Write In Progress (WIP) flag */
#define Dummy_Byte 0xA5
///////////////////////////////////////////////////////////////////////////////////////
// SPI_CS -- PA4
// SPI_SCK -- PA5
// SPI_MISO -- PA6
// SPI_MOSI -- PA7
//////////////////////////////////////////////////////////////////////////////////////
#define PORT_SPI_CS GPIOA
#define PORT_SPI_SCK GPIOA
#define PORT_SPI_MISO GPIOA
#define PORT_SPI_MOSI GPIOA
#define PIN_SPI_CS GPIO_Pin_4
#define PIN_SPI_SCK GPIO_Pin_5
#define PIN_SPI_MISO GPIO_Pin_6
#define PIN_SPI_MOSI GPIO_Pin_7
#define SPI_CS_DISABLE {PORT_SPI_CS->BRR = PIN_SPI_CS;}
#define SPI_CS_ENABLE {PORT_SPI_CS->BSRR = PIN_SPI_CS;}
#define SPI_SCK_LOW {PORT_SPI_SCK->BRR = PIN_SPI_SCK;}
#define SPI_SCK_HIGH {PORT_SPI_SCK->BSRR = PIN_SPI_SCK;}
#define SPI_MISO_READ {GPIO_ReadInputDataBit(PORT_SPI_MISO,PIN_SPI_MISO)}
#define SPI_MOSI_LOW {PORT_SPI_MOSI->BRR = PIN_SPI_MOSI;}
#define SPI_MOSI_HIGH {PORT_SPI_MOSI->BSRR = PIN_SPI_MOSI;}
extern void SPI_FLASH_Init(void);
extern void SPI_FLASH_BufferRead(u8* pBuffer, u16 ReadAddr, u16 NumByteToRead);
extern void SPI_FLASH_BufferWrite(u8* pBuffer, u16 WriteAddr, u16 NumByteToWrite);
extern void SPI_FLASH_BufferTest(void);
#endif
#include "SPI_FLASH.h"
/*******************************************************************************
* Function Name : SPI_FLASH_Init
* Description : SPI 寄存器初始化,中断初始化
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void SPI_FLASH_Init(void)//io初始化配置
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //RCC中已经初始化过,
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;//CS CLK
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //MOSI
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //MISO
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
SPI_CS_DISABLE;
SPI_SCK_HIGH;
SPI_MOSI_HIGH;
}
/*******************************************************************************
* Function Name : SPI_Delay
* Description : 模拟SPI通信延时函数
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void SPI_Delay(void)
{
u8 i = 0;
for(i = 0;i <= 200;i++)
{
;
}
}
/*******************************************************************************
* Function Name : SPI_FLASH_SendByte
* Description : 模拟SPI通信写FLASH一个字节
* Input : u8 byte 要写入数据
* Output : None
* Return : None
*******************************************************************************/
void SPI_FLASH_SendByte(u8 byte)
{
u8 cnt = 0;
for(cnt = 0;cnt < 8;cnt++)
{
SPI_SCK_LOW;
SPI_Delay();
if(byte & 0x80)
{
SPI_MOSI_HIGH;
}
else
{
SPI_MOSI_LOW;
}
byte <<= 1;
SPI_Delay();
SPI_SCK_HIGH;
SPI_Delay();
}
}
/*******************************************************************************
* Function Name : SPI_FLASH_ReadByte
* Description : 模拟SPI通信读FLASH一个字节
* Input : None
* Output : None
* Return : None
*******************************************************************************/
u8 SPI_FLASH_ReadByte(void)
{
u8 cnt = 0;
u8 RxData = 0;
for(cnt = 0;cnt < 8;cnt++)
{
SPI_SCK_LOW;
SPI_Delay();
RxData <<= 1;
if(GPIO_ReadInputDataBit(PORT_SPI_MISO,PIN_SPI_MISO))
{
RxData |= 0x01;
}
SPI_SCK_HIGH;
SPI_Delay();
}
return RxData;
}
/*******************************************************************************
* Function Name : SPI_Flash_ReadSR
* Description : 模拟SPI通信 读FLASH状态寄存器值
* Input : None
* Output : u8 byte FLASH状态寄存器值
* Return : None
*******************************************************************************/
u8 SPI_Flash_ReadSR(void)
{
u8 byte = 0;
SPI_CS_DISABLE; //使能器件
SPI_FLASH_SendByte(RDSR); //发送读取状态寄存器命令
byte = SPI_FLASH_ReadByte(); //读取一个字节
SPI_CS_ENABLE; //取消片选
return byte;
}
/*******************************************************************************
* Function Name : SPI_FLASH_Write_SR
* Description : 模拟SPI通信 写FLASH状态寄存器值
* Input : u8 byte 要写入FLASH状态寄存器值
* Output : None
* Return : None
*******************************************************************************/
void SPI_FLASH_Write_SR(u8 sr)
{
SPI_CS_DISABLE; //SPI_FLASH_CS=0; //片选
SPI_FLASH_SendByte(WREN); //SPI_ReadWriteByte(SST25_EnableWriteStatusReg); //使能写状态寄存器命令
SPI_CS_ENABLE; //SPI_FLASH_CS=1; //取消片选
SPI_CS_DISABLE;//SPI_FLASH_CS=0; //片选
SPI_FLASH_SendByte(WRSR); //发送写取状态寄存器命令
SPI_FLASH_SendByte(sr); //写入一个字节
SPI_CS_ENABLE; //SPI_FLASH_CS=1; //取消片选
}
/*******************************************************************************
* Function Name : SPI_FLASH_Write_Enable
* Description : 模拟SPI通信 SPI_FLASH写使能,将WEL置位
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void SPI_FLASH_Write_Enable(void)
{
SPI_CS_DISABLE; //使能器件
SPI_FLASH_SendByte(WREN); //发送写使能
SPI_CS_ENABLE; //取消片选
}
/*******************************************************************************
* Function Name : SPI_Flash_ReadID
* Description : 模拟SPI通信 读取SPI_FLASH芯片的ID
* Input : None
* Output : None
* Return : None
*******************************************************************************/
u16 SPI_Flash_ReadID(void)
{
u16 Temp = 0;
SPI_CS_DISABLE;
//发送读取ID命令
SPI_FLASH_SendByte(0x9F);
//发送24位的地址
SPI_FLASH_SendByte(0x00);
SPI_FLASH_SendByte(0x00);
SPI_FLASH_SendByte(0x00);
//读取返回的16位值
Temp=SPI_FLASH_ReadByte()<<8; //高8位数据
Temp+=SPI_FLASH_ReadByte(); //低八位数据
SPI_CS_ENABLE;
return Temp;
}
/*******************************************************************************
* Function Name : SPI_FLASH_BufferRead
* Description : 模拟SPI通信 在指定地址开始读取指定长度的数据
* Input : pBuffer:数据存储区
: ReadAddr:开始读取的地址(16bit)
: NumByteToRead:要读取的字节数(最大32768即32k)
* Output : None
* Return : None
*******************************************************************************/
void SPI_FLASH_BufferRead(u8* pBuffer,u16 ReadAddr,u16 NumByteToRead)
{
u16 i;
SPI_CS_DISABLE; //使能器件
SPI_FLASH_SendByte(READ); //发送读取命令
SPI_FLASH_SendByte((u8)((ReadAddr)>>8));
SPI_FLASH_SendByte((u8)ReadAddr);
for(i=0;i<NumByteToRead;i++)
{
pBuffer[i] = SPI_FLASH_ReadByte(); //循环读数
}
SPI_CS_ENABLE; //取消片选
}
/*******************************************************************************
* Function Name : SPI_FLASH_BufferWrite
* Description : 模拟SPI通信 在指定地址开始写入指定长度的数据
* Input : pBuffer:数据存储区
: ReadAddr:开始写入的地址(16bit)
: NumByteToRead:要写入的字节数
* Output : None
* Return : None
*******************************************************************************/
void SPI_FLASH_BufferWrite(u8* pBuffer, u16 WriteAddr, u16 NumByteToWrite)
{
/* Enable the write access to the FLASH */
SPI_FLASH_Write_Enable();
/* Select the FLASH: Chip Select low */
SPI_CS_DISABLE;
/* Send "Write to Memory " instruction */
SPI_FLASH_SendByte(WRITE);
/* Send WriteAddr high nibble address byte to write to */
SPI_FLASH_SendByte((WriteAddr & 0xFF00) >> 8);
/* Send WriteAddr low nibble address byte to write to */
SPI_FLASH_SendByte(WriteAddr & 0xFF);
/* while there is data to be written on the FLASH */
while(NumByteToWrite--)
{
/* Send the current byte */
SPI_FLASH_SendByte(*pBuffer);
/* Point on the next byte to be written */
pBuffer++;
}
/* Deselect the FLASH: Chip Select high */
SPI_CS_ENABLE;
}
/*******************************************************************************
* Function Name : SPI_FLASH_BufferTest
* Description : 模拟SPI通信 读写测试程序
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void SPI_FLASH_BufferTest(void)
{
u8 ReadBuff[20] = {0};
u8 WriteBuff[20] = {0};
u8 i = 0;
for(i = 0;i<20;i++)
{
ReadBuff[i] = 0x55;
WriteBuff[i] = 0xCB;
}
SPI_FLASH_BufferWrite(WriteBuff,0,20);
for(i = 0;i<200;i++)
{
;
}
SPI_FLASH_BufferRead(ReadBuff,0,20);
for(i = 0;i<200;i++)
{
;
}
}
/******************* (C) COPYRIGHT 2012 STMicroelectronics *****END OF FILE****/