历史上的今天
返回首页

历史上的今天

今天是:2025年03月23日(星期日)

正在发生

2020年03月23日 | stm32驱动NOR Flash 之MX25L51245G(64MB)

2020-03-23 来源:eefocus

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]);

}

推荐阅读

史海拾趣

Engelking Elektronik GmbH公司的发展小趣事

Engelking Elektronik GmbH公司成立于20世纪90年代初,最初只是一家小型电子产品制造商。在创始人Engelking先生的领导下,公司专注于生产高质量的电子元件和模块。随着技术的不断进步和市场的扩大,Engelking Elektronik开始将产品范围扩展到更复杂的电子系统。通过持续的研发投入和严格的质量控制,公司逐渐在电子行业中树立了专业可靠的声誉。

Good Will Instrument Co., Ltd.公司的发展小趣事

为了进一步提升技术实力和产品竞争力,Engelking Elektronik积极寻求与高校和研究机构的合作。通过与多家知名科技院校的合作,公司获得了多项技术专利和研发成果。其中,一项重要的技术突破是开发了一种新型的高效能电子元件,该元件在能效和可靠性方面均达到了行业领先水平。这一成果不仅为公司带来了可观的经济效益,也提升了公司在业界的地位。

BH Electronics公司的发展小趣事

近年来,随着环保意识的提高,BH Electronics积极响应国家绿色发展的号召,开始了绿色转型之路。公司加大了对环保技术的研发和应用力度,推出了一系列绿色环保产品。同时,BH Electronics还优化了生产流程,减少了能源消耗和废物排放。这些举措不仅提升了公司的环保形象,也为公司的可持续发展注入了新的动力。

这五个故事只是BH Electronics发展历程中的一部分,但它们却生动地展现了这家公司在电子行业中的崛起之路。从初创时期的筚路蓝缕,到技术创新的突破;从国际化战略的拓展,到品质管理的提升;再到绿色发展的转型,BH Electronics始终保持着敏锐的市场洞察力和不懈的创新精神。正是这些因素的共同作用,使得BH Electronics能够在激烈的市场竞争中脱颖而出,成为电子行业中的佼佼者。

AIRPAX公司的发展小趣事

AIRPAX的故事始于一个对电气保护和传感器技术充满热情的团队。在20世纪初,电气技术的快速发展为各种行业带来了巨大的变革。看到这一机遇,AIRPAX的创始人在美国马萨诸塞州的阿特波罗创立了这家公司,专注于传感器、电气保护器和控制器的设计与制造。最初,AIRPAX的产品主要服务于本地的小规模工业应用,但凭借其卓越的性能和可靠性,很快赢得了市场的认可。

Gauthier Connectique公司的发展小趣事
比较替代产品的灵敏度、功耗、稳定性等性能参数,选择性能更优的产品。
Global Communications公司的发展小趣事
通过温度传感器检测环境温度,并将检测到的温度信号转换为电信号后,送入到专门的补偿电路中。补偿电路根据温度信号调整晶体振荡器的输出频率或相位,以达到补偿的目的。这种方法相对复杂,但可以实现更精确的补偿效果。

问答坊 | AI 解惑

音频的基本知识

本文档主要包括: 第一部分 模拟声音-数字声音原理 第二部分 音频压缩编码 第三部分 和弦铃声格式 第四部分 单声道、立体声和环绕声第五部分 3D环绕声技术 第六部分 数字音频格式和数字音频接口…

查看全部问答>

语音识别芯片 声控芯片 LD3320 非特定人/单芯片/动态编辑识别列表 ICRoute

本帖最后由 jameswangsynnex 于 2015-3-3 19:56 编辑 看看大家能用这个芯片设计制造出什么样好玩又实用的新产品。 :) # 单芯片,非特定人,动态编辑识别列表的识别芯片LD332X系列,可以用于所有的电子产品,只需要最简单的51作为控制芯片即可 ...…

查看全部问答>

上海逻迅:招聘单片机工程师

公司(上海逻迅信息科技有限公司)现处于创业阶段,招3-4个人(全职),不限学历,能把事情做好即可,欢迎有能力、有学习热情者加入公司。 1、熟悉数字、模拟电路 2、熟练使用一款PCB设计软件 3、熟练使用电子测试仪器 4、优先考虑: 掌握一定 ...…

查看全部问答>

交流输出单电容半桥式变压器开关电源(part1)开关电源原理与设计(连载36)

1-8-2-2.交流输出单电容半桥式变压器开关电源 图1-39是单电容半桥式变压器开关电源的工作原理图。这里的单电容是把图1-36中的上分压电容器C1或下分压电容器省掉了的意思,因此,图1-39的单电容半桥式变压器开关电源是相对于图1-36的双电容半桥式 ...…

查看全部问答>

基准源高了好还是低了好?

本信息来自合作QQ群:AVR单片机学习与交流群(17727270) 群管理员在坛子里的ID:铜河   昨天半夜醒了 突然想到个问题 基准源高了好还是低了好 …

查看全部问答>

求救:sed1335控制器320*240液晶显示地址问题

最近在研究430单片机控制lcd液晶显示的问题!可是对液晶控制器1335的资料却研究的不够透彻。关于分屏和每一屏地址的范围总是无法确定,导致图形字符重叠,或者显示不全!希望有高手能进来帮忙指点一下,或者给我留一个液晶开发的群号也可以,一起讨 ...…

查看全部问答>

各位有沒有PCI的DMA的資料,十分感謝。

如題,看了《Programming the Microsoft Windows Driver Model》第一版,還不如直接編程硬件呢。 不知大家有什么好資料,十分感謝。…

查看全部问答>

【问TI】uip 协议栈写LM3S8962以太网

请问一下 我用uip 协议栈写LM3S8962以太网 怎么让数据连续往上位机发送呢 我现在只能上位机发送一次数据 下位机才向上发送一次数据 我想上位机发送一次命令 下位机能连续发送数据 等到我发停止命令 下位机才停止发送 这个程序在原来的基础上什么改 ...…

查看全部问答>

MSP430程序升级方式探讨

MSP430程序升级方式探讨 作者、源出处未明,如知情者请通知我们;我们会及时更新。 对MSP430系列单片机进行编程的方式有以下三种:利用JTAG接口,利用BSL固件和利用用户自定义的升级固件。由于利用自定义升级固件进行程序升级的 ...…

查看全部问答>