LPC1752读取FM25L04B的原理与实现

  1. LPC1752通过SPI与FM25L04B进行通讯。

    图 1 LPC1752 与 FM25L04B 硬件连线图

  2. 初始化LPC1752的SSP0模块

    按着如下步骤进行初始化的操作:

    • 在PCONP寄存器置位PCSSP0,允许SSP0模块的电源输出;
    • 在PCLK_SSP1寄存器中选择PCLK_SEL0,设置SSP0的时钟为CCLK/4;对SSP0的时钟进行分频,设置为CCLK/4/10;
    • 对LPC1752的管脚进行设置;
    • 设置 SPI 为主模式, FM25L04 工作在 SPI 模式 0。

    初始化代码:

void LPC17xx_SPI_Init(void)
{
    volatile uint32_t dummy;

    dummy = dummy;                                   /* avoid warning */

  LPC_SC->PCONP |= (1 << 21);                      /* Enable power to SSPI0 block */

    /* PCLK_SSP0=CCLK */
    LPC_SC->PCLKSEL1 &= ~(3<<10);                    /* PCLKSP0 = CCLK/4 (25MHz) */
    LPC_SC->PCLKSEL1 |=  (1<<10);                    /* PCLKSP0 = CCLK   (100MHz) */    

    LPC17xx_SPI_SetSpeed (SPI_SPEED_10MHz);

  LPC_GPIO0->FIODIR |=  (1<<16);                   /* P0.16 CS is output */

    /* P0.15 SCK, P0.17 MISO, P0.18 MOSI are SSP pins. */
    LPC_PINCON->PINSEL0 &= ~( (2UL<<30) );                  /* P0.15  cleared */
    LPC_PINCON->PINSEL1 &= ~( (2<<2) | (2<<4) );     /* P0.17, P0.18  cleared */
    LPC_PINCON->PINSEL0 |=  ( (2UL<<30) );           /* P0.15 SCK0 */
    LPC_PINCON->PINSEL1 |=  ( (2<<2) | (2<<4) );     /* P0.17 MISO0   P0.18 MOSI0 */

    LPC_SSP0->CR0  = ( 7<<0 );                       /* 8Bit, CPOL=0, CPHA=0         */
    LPC_SSP0->CR1  = ( 1<<1 );                       /* SSP0 enable, master          */

    /* wait for busy gone */
    while( LPC_SSP0->SR & ( 1 << SSPSR_BSY ) );

    /* drain SPI RX FIFO */
    while( LPC_SSP0->SR & ( 1 << SSPSR_RNE ) )
    {
        dummy = LPC_SSP0->DR;
    }
}
  1. 读取FM25L04B

    FM25L04B的读时序

uint8_t FM25L04B_Read(uint32_t Dst, uint8_t* RcvBufPt, uint32_t NByte)
{
    uint8_t addr_a8;
    uint32_t i = 0;
//  if ((Dst+NByte > MAX_ADDR)||(NByte == 0))   return (ERROR);
    addr_a8 = (Dst & 0xffffff00)>>5;

    SPI_FLASH_WP_UNLOCK();
  SPI_FLASH_CS_LOW();
    FM25L04B_ReadWriteByte(READ_CMD|addr_a8);
    FM25L04B_ReadWriteByte(Dst & 0x00ff);
    for (i = 0; i < NByte; i++)
    {
       RcvBufPt[i] = FM25L04B_ReadWriteByte(0xFF);
    }
  SPI_FLASH_CS_HIGH();
    SPI_FLASH_WP_LOCK();

    return 0;
}
  1. 写FM25L04B

    FM25L04B的写时序

uint8_t FM25L04B_Write(uint32_t Dst, uint8_t* SndbufPt,uint32_t NByte)
{
    uint8_t addr_a8;
    uint8_t temp = 0,StatRgVal = 0;
    uint32_t i = 0; 

//  if (( (Dst+NByte-1 > MAX_ADDR)||(NByte == 0) ))
//  {
//      return (ERROR);  /* ?????? */
//  }

    addr_a8 = (Dst & 0xffffff00)>>5;

    SPI_FLASH_WP_UNLOCK();
    SPI_FLASH_CS_LOW();
    FM25L04B_ReadWriteByte(RDSR_CMD);
    temp = FM25L04B_ReadWriteByte(0xFF);
    SPI_FLASH_CS_HIGH();

    for(i = 0; i < NByte; i++)
    {
        SPI_FLASH_CS_LOW();
        FM25L04B_ReadWriteByte(WREN_CMD);
        SPI_FLASH_CS_HIGH();    

        SPI_FLASH_CS_LOW();
        FM25L04B_ReadWriteByte(WRITE_CMD|addr_a8);
      FM25L04B_ReadWriteByte((Dst+i)& 0x00ff);
        FM25L04B_ReadWriteByte(SndbufPt[i]);
        SPI_FLASH_CS_HIGH();            

        do
        {
          SPI_FLASH_CS_LOW();
            FM25L04B_ReadWriteByte(RDSR_CMD);
            StatRgVal = FM25L04B_ReadWriteByte(0xFF);
            SPI_FLASH_CS_HIGH();
        }
        while (StatRgVal == 0x03 );                          

    }

    SPI_FLASH_CS_LOW();
    FM25L04B_ReadWriteByte(WREN_CMD);
    SPI_FLASH_CS_HIGH();            

    SPI_FLASH_CS_LOW();
    FM25L04B_ReadWriteByte(WRSR_CMD);
    FM25L04B_ReadWriteByte(temp);
    SPI_FLASH_CS_HIGH();
    SPI_FLASH_WP_LOCK();

    return 0;
}
  1. 测试代码
uint8_t Recv_buf[16];
uint8_t Send_buf[16] = {0x01,0x02,0x05,0xe4};

int main(void)
{
    SystemInit();

    LPC17xx_SPI_Init();

    FM25L04B_Read(0x0,Recv_buf, sizeof(Recv_buf));
    FM25L04B_Write(0x0,Send_buf, sizeof(Send_buf));

    memset(Recv_buf,0,sizeof(Recv_buf));
    FM25L04B_Read(0x0,Recv_buf, sizeof(Recv_buf));

    while(1) ;
}
时间: 2024-10-11 03:31:44

LPC1752读取FM25L04B的原理与实现的相关文章

Oracle中读取数据一些原理研究

文章很多摘录了 http://blog.163.com/[email protected]/blog/static/7956964020131069843572/ 同时基于这篇文章的基础上,补充一些学习要点,如有问题,希望指出探讨. 1 ORACLE体系结构 下图描述了oracle的体系结构.SGA(system global area)是各个进程共享的内存块,Buffer cache用来缓存数据文件的数据块(block). 2 如何在data buffer中查找数据块 data buffer存

dedeCMS,标准的MVC框架运行原理和缓存

1.织梦的工作原理: a.模板引擎: b.内核文件的载入.读取: 运行原理:url->配置文件->公共函数文件->处理逻辑->模板引擎->展示:(公共函数文件.处理逻辑和模板引擎就是织梦的核心) 2.标准的MVC框架运行流程:程序首先从单人口文件开始运行,然后依次载入内核文件(同时开始各种的初始化).配置.类和动作(在这之前已经载入了模板引擎),运行到业务层,业务层又会给类和动作,最后才展示出来. 3.关于缓存: a.缓存类型: 按缓存类型划分:内存缓存.文件缓存.数据库缓存

linuxShell之一 文件读取 循环与分支

Linux中的Shell非常强大, 可以完成我们很多繁琐低效的工作. 就最近笔者在Shell环境下写java demo的时候就遇到的CLASSPATH问题 写了一个操作HBase的demo发现用到的jar包太多,运行的时候太不好加CLASSPATH . 然而我又很不喜欢做没有任何意义的机械操作  所以我学习并写了两个sh  ,在这里分享给大家 . shell 的文本文件读取 首先shell读取文本文件的原理是按行读取,也就是循环行.下面附上格式 for line in <文本文件路径 do ..

Java InputStream读取网络响应Response数据的方法!(重要)

原文:Java InputStream读取网络响应Response数据的方法!(重要) Java InputStream读取数据问题 ====================================================================== 原理讲解 1. 关于InputStream.read() 在从数据流里读取数据时,为图简单,经常用InputStream.read()方法.这个方法是从流里每次只读取读取一个字节,效率会非常低.     更好的方法是用Inp

分享非常有用的Java程序(关键代码)(八)---Java InputStream读取网络响应Response数据的方法!(重要)

原文:分享非常有用的Java程序(关键代码)(八)---Java InputStream读取网络响应Response数据的方法!(重要) Java InputStream读取数据问题 ====================================================================== 原理讲解 1. 关于InputStream.read()      在从数据流里读取数据时,为图简单,经常用InputStream.read()方法.这个方法是从流里每次只读

cookie实现自动登陆原理

现在很多网站都有为用户保存登陆信息(即保存Cookie)的功能,当用户下一次进入网站时,可以帮助用户自动登陆,使网站显得更加友好. 笔者通过研究ACEGI项目的自动登陆源码,编写了一个安全有效的实现两星期自动登陆功能的JAVA工具类. 下面是具体的实现流程和实现代码: 先说一下流程: 1. 保存用户信息阶段: 当 用户登陆网站时,在登陆页面填写完用户名和密码后,如果用户在提交时还选择了“两星期内自动登陆”复选框,那么在后台程序中验证用户名和密码全都正确后, 还要为用户保存这些信息,以便用户下一次

Java-IO流之BufferedReader 和BufferedWriter的使用和原理

BufferedReader和BufferedWriter出现的目的是为了对FileReader以及FileWriter的读写操作进行增强,而怎么增强呢,原理类似于使用StringBuilder,是把数据先放入他们的一个char数组中,然后再操作char数组. 使用缓冲区的字符流是使用了装饰着模式对FileReader等进行功能上的增强,装饰者模式与继承都可以实现功能上的增强,但是装饰者可以做得更加的灵活,也不会使继承树变得太过复杂. 以下是BufferedWriter源码的一小部分 publi

20160503-spring入门2

使用Spring需要的jar 到http://www.springsource.org/download下载spring,然后进行解压缩,在解压目录中找到下面jar文件,拷贝到类路径下 dist\spring.jar lib\jakarta-commons\commons-logging.jar 如果使用了切面编程(AOP),还需要下列jar文件 lib/aspectj/aspectjweaver.jar和aspectjrt.jar lib/cglib/cglib-nodep-2.1_3.jar

linux磁盘管理和文件系统创建

1      磁盘管理 1.1    硬盘的构造原理 硬盘分类: 机械式硬盘,固态硬盘 硬盘出厂会进行低级格式化,分磁盘,再分扇区,硬盘的第一个磁道的一个扇区就是MBR 512Bytes Master boot record 446 bytes bootloader 主引导程序 64bytes :主分区存储 16bytes表示一个主分区,最多4个主分区 2bytes:magic number 表示mbr是否有效 硬盘的注意事项: a)                1.硬盘需要绝对的无尘环境,生