crystal1987的个人空间 https://passport2.21ic.com/?1370010 [收藏] [复制] [RSS]

日志

STM32的IO口模拟SPI读写铁电SRAM之二

已有 1109 次阅读2018-12-13 14:29 |个人分类:单片机驱动相关模块|系统分类:ARM| STM32, 模拟SPI, SRAM

之前做了一个使用底层SPI读写铁电SRAM试验,由于本次使用的单片机IO口较少,底层SPI的IO口也被其他功能使用,没办法了,只能模拟SPI与铁电SRAM进行通信。在网上找了一段代码进行修改,然后调试时发现写入的数据,读出来之后是之前的写入数据的2倍;经调试发现是将一个字节数据,读写了9次,将小于等于修改成小于就通过啦。虽然通过了,但是写程序的时候还是需要细心,否则还是容易出现问题。
一、SPI_FLASH.H
#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

二、SPI_FLASH.C

#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****/
三、main.c

/************************************main函数**************************************/
int main(void)
{
        system_init();
        while(1)
        {
                 Task_Count++;
                 if(Task_Count >= 22000)
                {
                        SPI_FLASH_BufferTest();
                        Task_Count = 0;
                }
        }
}





路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)