打印
[MM32软件]

【MM32 eMiniBoard测评报告】+9、SPI FLASH

[复制链接]
875|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
今天搞了一下SPI FLASH
原理图:

代码:
#include "delay.h"
#include "sys.h"
#include "uart.h"
#include "spi.h"

int main(void)
{

    delay_init();
    uart_initwBaudRate(115200);                         //串口初始化为115200
    SPIM_Test();               
    while(1)                              //无限循环
    {

    }
}


#include "HAL_device.h"
#include "HAL_conf.h"
#include "spi.h"
#include "uart.h"          

unsigned char tmpdata[256];
unsigned char tmpdata1[256];
unsigned char rxtmpdata[256];
volatile unsigned char spi0_rx_flag;
volatile unsigned char spi0_tx_flag;
extern void DataCompare(unsigned char *p1, unsigned char *p2,unsigned int count);
/********************************************************************************************************
**函数信息 :SPIM_CSLow()                     
**功能描述 :为选定的SPI 软件重置内部NSS 管脚
**输入参数 :无
**输出参数 :无
********************************************************************************************************/
void SPIM_CSLow()
{
    //Spi cs assign to this pin,select       
    SPI_CSInternalSelected(SPI2, SPI_CS_BIT0,ENABLE);
}

/********************************************************************************************************
**函数信息 :SPIM_CSHigh()                     
**功能描述 :为选定的SPI 软件配置内部NSS 管脚
**输入参数 :无
**输出参数 :无
********************************************************************************************************/
void SPIM_CSHigh()
{
    //Spi cs release
    SPI_CSInternalSelected(SPI2, SPI_CS_BIT0,DISABLE);
}

/********************************************************************************************************
**函数信息 :SPIM_TXEn()                     
**功能描述 :关闭 SPI 在双向模式下的数据传输方向
**输入参数 : 无
**输出参数 :无
********************************************************************************************************/
void SPIM_TXEn()
{
    //Transmit Enable bit TXEN
    SPI_BiDirectionalLineConfig(SPI2, SPI_Direction_Tx);
}

/********************************************************************************************************
**函数信息 :SPIM_TXDisable()                     
**功能描述 :关闭 SPI 在双向模式下的数据传输方向
**输入参数 :无
**输出参数 :无
********************************************************************************************************/
void SPIM_TXDisable()
{
    //disable TXEN
    SPI_BiDirectionalLineConfig(SPI2, SPI_Disable_Tx);
}

/********************************************************************************************************
**函数信息 :SPIM_RXEn()                     
**功能描述 :关闭 SPI 在双向模式下的数据传输方向
**输入参数 :无
**输出参数 :无
********************************************************************************************************/
void SPIM_RXEn()
{
    //enable RXEN
    SPI_BiDirectionalLineConfig(SPI2, SPI_Direction_Rx);
}

/********************************************************************************************************
**函数信息 :SPIM_RXDisable()                     
**功能描述 :关闭 SPI 在双向模式下的数据传输方向
**输入参数 :无
**输出参数 :无
********************************************************************************************************/
void SPIM_RXDisable()
{
    //disable RXEN
    SPI_BiDirectionalLineConfig(SPI2, SPI_Disable_Rx);
}


/********************************************************************************************************
**函数信息 :SPIMReadWriteByte(unsigned char tx_data)                    
**功能描述 : 通过外设 SPIx 收发数据 ,用于全双工模式(同时收发)
**输入参数 :无
**输出参数 :无
********************************************************************************************************/
unsigned int SPIMReadWriteByte(unsigned char tx_data)
{
    SPI_SendData(SPI2, tx_data);       
    while (1)
    {
        if(SPI_GetFlagStatus(SPI2,SPI_FLAG_TXEPT))
        {
            break;
        }
    }       
    while (1)
    {
        if(SPI_GetFlagStatus(SPI2, SPI_FLAG_RXAVL))       
        {
            return SPI_ReceiveData(SPI2);
        }
    }
}

/********************************************************************************************************
**函数信息 :SPIM_Init(unsigned short spi_baud_div)            
**功能描述 :可修改参数初始化SPI
**输入参数 :spi_baud_div
**输出参数 :无
********************************************************************************************************/
void SPIM_Init(unsigned short spi_baud_div)
{
    SPI_InitTypeDef SPI_InitStructure;
    GPIO_InitTypeDef  GPIO_InitStructure;


    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);  //SPI2 clk enable

    SPIM_CSHigh();

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA|RCC_AHBPeriph_GPIOB, ENABLE);

    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_12;                   //spi2_cs  pb12
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;         // 推免复用输出
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_13;                   //spi2_sck  pb13
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;         // 推免复用输出
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_15;                   //spi2_mosi  pb15
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;         // 推免复用输出
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_14;                  //spi2_miso  pb14
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;                 //上拉输入   
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_PinAFConfig(GPIOB,GPIO_PinSource12,GPIO_AF_0);//需要将SPI的其他几个IO口复用成任意别的(默认是AF0)
    GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_0);//需要将SPI的其他几个IO口复用成任意别的(默认是AF0)
    GPIO_PinAFConfig(GPIOB,GPIO_PinSource14,GPIO_AF_0);
    GPIO_PinAFConfig(GPIOB,GPIO_PinSource15,GPIO_AF_0);

    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
    SPI_InitStructure.SPI_DataWidth = SPI_DataWidth_8b;
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;                            // mode0 SPI_CPOL_Low, SPI_CPHA_1Edge;
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;                          // mode3 SPI_CPOL_High,SPI_CPHA_2Edge
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
    SPI_InitStructure.SPI_BaudRatePrescaler = spi_baud_div;
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_Init(SPI2, &SPI_InitStructure);
    SPIM_TXEn();
    SPIM_RXEn();
    SPI_Cmd(SPI2, ENABLE);//Enables the specified SPI peripheral SPI使能、主机模式 8位数据模式 SPI 的波特率

}

/********************************************************************************************************
**函数信息 :SPIM_ReadID(SPI_TypeDef* SPIx)                  
**功能描述 :读取ID
**输入参数 :SPI_TypeDef* SPIx,可选择SPI1,SPI2
**输出参数 :无
********************************************************************************************************/
void SPIM_ReadID()
{
    unsigned char temp;
    unsigned int i;

    SPIM_CSLow();                                                                //Spi cs assign to this pin,select
    SPIMReadWriteByte(RDID);                               

    for(i=0;i<3;i++)
    {
        temp = SPIMReadWriteByte(0x01);
        printf("temp=0x%x\r\n",temp);               
    }
    SPIM_CSHigh();                                                           //Spi cs release
}

/********************************************************************************************************
**函数信息 :SPIM_WriteEnable()                  
**功能描述 :写数据使能
**输入参数 :无
**输出参数 :无
********************************************************************************************************/
void SPIM_WriteEnable()
{
    SPIM_CSLow();                                                                 //Spi cs assign to this pin,select
    SPIMReadWriteByte(WREN);       
    SPIM_CSHigh();                                                                 //Spi cs release
}

/********************************************************************************************************
**函数信息 :SSPIM_checkStatus()                 
**功能描述 :检查数据发送是否正确
**输入参数 :无
**输出参数 :无
********************************************************************************************************/
void SPIM_checkStatus()
{
    unsigned char temp;
    SPIM_CSLow();                                                                 //Spi cs assign to this pin,select
    SPIMReadWriteByte(RDSR);       
    while(1)
    {
        temp = SPIMReadWriteByte(0x00);       
        if((temp&0x01)==0x0)
            break;
    }
    SPIM_CSHigh();                                                          //Spi cs release
}

/********************************************************************************************************
**函数信息 :SPIM_WriteEnable()                  
**功能描述 :写数据失能
**输入参数 :无
**输出参数 :无
********************************************************************************************************/
void SPIM_WriteDisable()
{       
    SPIM_CSLow();
    SPIMReadWriteByte(WRDI);
    SPIM_CSHigh();
}

/********************************************************************************************************
**函数信息 :SPIM_PageRead(unsigned long address,unsigned char *p,unsigned int number)               
**功能描述 :读取256页数据
**输入参数 : address  ;*p ;number
**输出参数 :无
********************************************************************************************************/
void SPIM_PageRead(unsigned long address,unsigned char *p,unsigned int number)  //page = 256 bytes
{
    unsigned char addr0,addr1,addr2;
    unsigned int i;
    address = address&0xffffff00;                                         //page address
    addr0 = (unsigned char)(address>>16);
    addr1 = (unsigned char)(address>>8);
    addr2 = (unsigned char)address;

    SPIM_CSLow();                                                                 //Spi cs assign to this pin,select

    SPIMReadWriteByte(READ);
    SPIMReadWriteByte(addr0);
    SPIMReadWriteByte(addr1);
    SPIMReadWriteByte(addr2);

    for(i=0;i<256;i++)
    {
        rxtmpdata = SPIMReadWriteByte(0x00);
    }


    SPIM_CSHigh();                                                          //Spi cs release
}

/********************************************************************************************************
**函数信息 :SPIM_PageProgram(unsigned long address,unsigned char *p,unsigned int number)              
**功能描述 :发送256页数据
**输入参数 : address;*p;number
**输出参数 :无
********************************************************************************************************/
void SPIM_PageProgram(unsigned long address,unsigned char *p,unsigned int number)
{
    unsigned int j;
    unsigned char addr0,addr1,addr2;
    address = address&0xffffff00;                                         //page address
    addr0 = (unsigned char)(address>>16);
    addr1 = (unsigned char)(address>>8);
    addr2 = (unsigned char)address;

    SPIM_WriteEnable();
    SPIM_CSLow();                                                                  //Spi cs assign to this pin,select
    SPIMReadWriteByte(PP);
    SPIMReadWriteByte(addr0);
    SPIMReadWriteByte(addr1);
    SPIMReadWriteByte(addr2);
    for(j=0;j<number;j++)
    {
        SPIMReadWriteByte(*(p++));
    }

    SPIM_CSHigh();                                                          //Spi cs release

    SPIM_checkStatus();
}

/********************************************************************************************************
**函数信息 :SPIM_SectorErase()            
**功能描述 :擦除数据
**输入参数 :unsigned long address,删除指定sector的地址 each sector = 64Kbytes
**输出参数 :无
********************************************************************************************************/
void SPIM_SectorErase(unsigned long address)
{
    unsigned char addr0,addr1,addr2;
    address = address & 0xffff0000;
    addr0 = ((unsigned char)(address>>16))&0xff;
    addr1 = ((unsigned char)(address>>8))&0xff;
    addr2 = ((unsigned char)address)&0xff;

    SPIM_WriteEnable();

    SPIM_CSLow();                                                                  //Spi cs assign to this pin,select

    SPIMReadWriteByte(SE);
    SPIMReadWriteByte(addr0);
    SPIMReadWriteByte(addr1);
    SPIMReadWriteByte(addr2);
    SPIM_CSHigh();                                                          //Spi cs release

    SPIM_checkStatus();
}

/********************************************************************************************************
**函数信息 :SPIM_BlockErase()            
**功能描述 :擦除数据
**输入参数 :无
**输出参数 :无
********************************************************************************************************/
void SPIM_BlockErase()
{
    SPIM_WriteEnable();

    SPIM_CSLow();                                                                  //Spi cs assign to this pin,select

    SPIMReadWriteByte(BE);       

    SPIM_CSHigh();                                                          //Spi cs release

    SPIM_checkStatus();
}
/********************************************************************************************************
**函数信息 :SPIM_Close()            
**功能描述 : CS信号拉高,停止通信
**输入参数 :无
**输出参数 :无
********************************************************************************************************/
void SPIM_Close()
{
    SPIM_CSHigh();                                                          //Spi cs release
    SPIMReadWriteByte(0x01);
}

/********************************************************************************************************
**函数信息 :SPIM_Test()         
**功能描述 :测试程序,使用串口打印256页数据
**输入参数 :无
**输出参数 :无
********************************************************************************************************/
void SPIM_Test(void)
{
    unsigned int i;
    for(i=0;i<256;i++)
    {
        tmpdata = i;
    }

    printf("SPI2 test\r\n");
    SPIM_Init(0x8);//波特率 72M/2=36M

    SPIM_ReadID();

    SPIM_SectorErase(0);

    SPIM_PageProgram(0,tmpdata,256);

    for(i=0;i<256;i++)
    {
        rxtmpdata = 0x0;
    }
    SPIM_PageRead(0,rxtmpdata,256);                 //把写进去的一页256字节读出来

    for(i=0;i<10;i++)
    {
        printf("rx[%d]=0x%x\r\n",i,rxtmpdata);
    }

    printf("SPI2 test over\r\n");

}

效果图:


注意:
SW2要拨到右边

工程:
SPI_FLASH.rar (339.8 KB)

使用特权

评论回复
沙发
caizhiwei| | 2020-5-10 08:57 | 只看该作者
点赞,小辣椒哥哥

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:绿水本无忧因风皱面,青山原不老为雪白头。

553

主题

3530

帖子

19

粉丝