stm32驱动NOR Flash 之MX25L51245G(64MB)

2020-03-23来源: eefocus关键字:stm32  驱动NOR  Flash  MX25L51245G

MX25L51245G 支持SPI的MODE0/MODE3,一般都选择mode3


#define FLASH_SECTOR_SIZE (4*1024)

#define FLASH_PAGE_SIZE 256

引脚定义


/*

* SPI1

* @SCK  : PA5

* @MISO : PA6

* @MOSI : PA7

*

* @CS   : PA0

*/

读写接口


static u8 SPI_Write(u8 byte)

{

u32 timeout = 0xFFFF;

while(!(SPI1->SR & SPI_I2S_FLAG_TXE))

{

if(--timeout == 0)

{

printf("TX timeout ! rn");

return 0;

}

}

SPI1->DR = byte;

 

timeout = 0xFFFF;

while(!(SPI1->SR & SPI_I2S_FLAG_RXNE))

if(--timeout == 0)

{

printf("RX timeout ! rn");

return 0;

}

 

return SPI1->DR;

}

 

static u8 SPI_Read(void)

{

    return (SPI_Write(DUMMY_BYTE));

}

初始化函数


void SPI1_Configuration(void)

{

SPI_InitTypeDef  SPI_InitStructure;

    GPIO_InitTypeDef GPIO_InitStructure;

 

RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    

    /* Configure SPI1 pins: NSS, SCK, MISO and MOSI */

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

    GPIO_Init(GPIOA, &GPIO_InitStructure);

 

    /* Configure PA.0 as Output push-pull, used as Chip select */

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

    GPIO_Init(GPIOA, &GPIO_InitStructure);

 

    /* Deselect the FLASH: Chip Select high */

    SPI_CS_Low();

 

    /* SPI1 configuration */ 

    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;

    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;

    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;

    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;

    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;          /* mode 3 */

    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;

    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;

    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;

    SPI_InitStructure.SPI_CRCPolynomial = 7;

    SPI_Init(SPI1, &SPI_InitStructure);

 

    /* Enable SPI1 NSS output for master mode */

    //SPI_SSOutputCmd(SPI1, DISABLE);    

    /* Enable SPI1  */

    SPI_Cmd(SPI1, ENABLE); 

 

SPI_Write(0xFF); //start transport

}

 

等待忙


/*

* @return : none-zero idle, else busy

*/

static u8 SPI_WaitBusy(void)

{

u32 timeout = 0xFFFF;

while( SET==SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY)) /* SPI_SR */

{

if(--timeout == 0)

return 1;

}

 

return 0;

}

Flash 等待WIP信号


#define    FLASH_WIP_MASK         (1 << 0)

 

/*

* @return : none-zero timeout

*/

static u8 FlashWait_Busy(void)

{

    u8 FLASH_Status;

    u32 retry=0;

    FLASH_CS_Low();

 

/*

* bit 0: WIP (=1 busy, else free)

* bit 1: WEL (=1 write enable)

*/

    SPI_Write(RDSD_CMD);          /* read status register */

    do{

        

        FLASH_Status=SPI_Read();

        if(retry++ > FLASH_BUSY_TIMEOUT)

            return FLASH_Status;

    }while((FLASH_Status & FLASH_WIP_MASK) == FLASH_WIP_MASK);    /* fix : not bit 7 !!! */

    

    //printf("status register : 0x%x rn", FLASH_Status);

 

    SPI_CS_High();

 

return 0;

}

获取flash信息


static void FlashGet_Info(flashInfoTypedef * pFlashInfo)

{

//     FlashWait_Busy();

    FLASH_CS_Low();

    SPI_Write(RDID_CMD);

    pFlashInfo->ManufacturerID=SPI_Read();

    pFlashInfo->DeviceID[0]=SPI_Read();

    pFlashInfo->DeviceID[1]=SPI_Read();

    SPI_CS_High();    

}

 

static void FlashGet_ElectronicInfo(flashInfoTypedef * pFlashInfo)

{

    FLASH_CS_Low();

    SPI_Write(REMS_CMD);

    SPI_Write(DUMMY_BYTE);

    SPI_Write(DUMMY_BYTE);

    SPI_Write(0x00);             //manufacturer's ID first

    pFlashInfo->ManufacturerID=SPI_Read();

    pFlashInfo->DeviceID[0]=SPI_Read();   

    SPI_CS_High();    

}

写使能


static void FlashWriteEnable(void)

{

    FLASH_CS_Low();

    SPI_Write(WREN_CMD);   

    SPI_CS_High();    

}

spi flash初始化


void SpiFlash_Init(void)

{

flashInfoTypedef flashInfo;

 

//SPI1_Configuration();

#if 1

FlashGet_ElectronicInfo(&flashInfo);

 

if((flashInfo.ManufacturerID==0xc2)&&(flashInfo.DeviceID[0]==0x20))

    {

        printf("Flash Info: MXIC(Macronix International Co.,Ltdrn");

    }

#endif

    FlashGet_Info(&flashInfo);

    printf("ManufacturerID = 0x%02X     rn",flashInfo.ManufacturerID);

    printf("DeviceID       = 0x%02X%02X rn",flashInfo.DeviceID[0],flashInfo.DeviceID[1]);

}

获取ID的接口


static void Flash_ReadID(void)

{

flashInfoTypedef flashInfo;

FlashGet_ElectronicInfo(&flashInfo);

 

if((flashInfo.ManufacturerID==0xc2)&&(flashInfo.DeviceID[0]==0x20))

    {

        printf("Flash Info: MXIC(Macronix International Co.,Ltdrn");

    }

    FlashGet_Info(&flashInfo);

    printf("ManufacturerID = 0x%02X     rn",flashInfo.ManufacturerID);

    printf("DeviceID       = 0x%02X%02X rn",flashInfo.DeviceID[0],flashInfo.DeviceID[1]);

}

关键字:stm32  驱动NOR  Flash  MX25L51245G 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic492332.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:stm32外扩外部sram学习笔记
下一篇:STM32芯片开发之添加外置NOR FALSH扩展代码空间

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

stm8l低功耗系列
最近干刚做了一个stm8的项目用的是L低功耗系列,其中遇到一个问题。外设寄存器的值怎么都写入不进去。用IAR仿真产看寄存器的值,不论写进去多少,都是初始值。后来把所有寄存器都写了一遍,发现有的能写进去,有的写不进去。比如GPIO的寄存器就能写进去。百思不得姐,偶然查看clock的库函数发现个函数是设置外设时钟的。这个系列,亦或者整个低功耗系列的每个外设是不是都需要在时钟寄存器中单独设置时钟。(以前所使用的芯片都是在外设寄存器中使能或者是禁使能)
发表于 2020-03-09
STM8L+BC26双低功耗,微安
现在在做一个项目需要用到STM8L和BC26。长时间断链后连接下服务器,并且发送一下当前状态,需要用到STM8L和BC26的低功耗。STM8L低功耗,这里用HALT模式,RTC规定时间唤醒。第一步需要关闭所有外设,把所有管脚为设置为输出,并且输出低,管脚根据具体环境设置,需要输出高电平的则输出高电平。在关闭外设的是后是需要先_DeInit,然后在关闭外设始终,有点需要特别主要,要把在进入halt模式的时候需要把所有的中断的标志位清空,否则使用RTC唤醒则会不起作用。第二步就设置低功耗的一些配置。第三步配置完成后进入低功耗。项目中需要用到外部高速始终和BC26通信,所以在进入和退出halt模式的时候需要重新初始化active模式下的
发表于 2020-03-09
stm8l151低功耗程序架构,调试心得
最近帮医院做了一款体温记录仪,整个硬件方案资源是:stm8L151 + NTC*2 + EEPROM + 锂电池充电保护电路 + 18mAh纽扣电池;软件逻辑是,每隔一分钟,采样两路温度并保存在EEP里;通过USB转TTL,上位机能够读取,展示温度曲线,最大最小平均值等简单的运算;整个方案很简单,但也走了不少弯路......单片机程序框架之伪代码:void main(void){    CLK_Config();    GPIO_Config();    ADC_Config();    USART_Config();   
发表于 2020-03-09
STM8s外部时钟晶振失效时钟安全系统CSS启动演示
使用的最小系统晶振是8m的。这里说下配置过程:时钟自动切换,开启切换中断在中断里面清除中断标志,使能CSS并开启CSS中断CSS中断发生,清除CSS中断标志,将HSI二分频,即16M/2=8M,与外部晶振相同,这样不会影响串口波特率窗口输出配置信息:用手触碰PA1、PA2引脚使外部晶振失效串口输出CSS中断
发表于 2020-03-09
STM8s外部时钟晶振失效时钟安全系统CSS启动演示
STM8S103之时钟设置
最大时钟(指的是system clock):外部晶振24MHz,内部高速RC16MHz三个时钟源:外部晶振、内部高速RC(上电默认) +内部低速RC几个时钟:master clock(即sytem clock),fcpu,外设时钟、AWU时钟调用库函数中CLK_ClockSwitchConfig,参考库函数clk_clockselection,但是分频还得进一步设置上电默认:内部高速RC,HSIDIV=/8,CPUDIV=/1,外部时钟全使能,查看相关寄存器的Reset value
发表于 2020-03-09
STM8S103之时钟设置
stm8 16M晶振下精确软件延时
void inerDelay_us(unsigned char n) {for(;n>0;n--) { asm("nop"); //在STM8里面,16M晶振,_nop_() 延时了 333nsasm("nop"); asm("nop"); asm("nop"); }}//---- 毫秒级延时程序----------------------- void Delayms(unsigned int time) { unsigned int i; 
发表于 2020-03-08
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2020 EEWORLD.com.cn, Inc. All rights reserved