社区导航

 
查看: 4856|回复: 9

[讨论] TI的CC2540读写spiflash

[复制链接]

14

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2015-4-7 11:06:33 | 显示全部楼层 |阅读模式
最近用TI的cc2540(51的核,8Kram,128kflash)读写华邦的W25Q16的SPIflash,发现CC2540每一个小时都会定时死机,只有重新上电复位才能重新开始工作,经过多方调试才把问题定位到了是spiflash有问题,但是研究代码又没发现有什么问题!真是纠结了。
我程序的流程是每2秒写一次flash,每次写的数据量是9个字节,写完后spiflash进入休眠,cc2540也进入休眠,2秒的定时到了之后,重复上面的过程,数据是循环写的。

写数据的程序如下:

void spi_flash_BufferWrite(uint8* pBuffer, uint32 WriteAddr, uint16 NumByteToWrite)
{
    uint8 Addr = 0, NumOfPage = 0, NumOfSingle = 0, count = 0, temp = 0;

    Addr = WriteAddr % SPI_FLASH_PageSize; //某页中的第Addr个地址
    count = SPI_FLASH_PageSize - Addr;  //某页中还剩余coun个地址空闲
    NumOfPage =  NumByteToWrite / SPI_FLASH_PageSize; //待写数据占用了页数
    NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize; //待写数据写了整数页大小的数据量后还剩多少个字节要写

    if (Addr == 0) // 写入的地址刚好在下页地址首地址  
    {
        if (NumOfPage == 0) // 待写入的数据小于一页的容量256
        {
            spi_flash_PageWrite(pBuffer, WriteAddr, NumByteToWrite);
        }
        else // 待写入的数据大于一页的容量256
        {
            while (NumOfPage--)
            {
                spi_flash_PageWrite(pBuffer, WriteAddr, SPI_FLASH_PageSize);
                WriteAddr +=  SPI_FLASH_PageSize;
                pBuffer += SPI_FLASH_PageSize;
            }

            spi_flash_PageWrite(pBuffer, WriteAddr, NumOfSingle);
        }
    }
    else // 待写入的地址不在某页的首地址
    {
        if (NumOfPage == 0) // 待写入的数据 < 256字节
        {
            if (NumOfSingle > count) // 待写入的数据量 + 待写入数据的首地址 > 当前页空余的空间
            {
                temp = NumOfSingle - count;

                spi_flash_PageWrite(pBuffer, WriteAddr, count);
                WriteAddr +=  count;
                pBuffer += count;

                spi_flash_PageWrite(pBuffer, WriteAddr, temp);
            }
            else
            {
                spi_flash_PageWrite(pBuffer, WriteAddr, NumByteToWrite);
            }
        }
        else // 待写入的数据 > 256字节
        {
            NumByteToWrite -= count;
            NumOfPage =  NumByteToWrite / SPI_FLASH_PageSize;
            NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize;

            spi_flash_PageWrite(pBuffer, WriteAddr, count);
            WriteAddr +=  count;
            pBuffer += count;

            while (NumOfPage--)
            {
                spi_flash_PageWrite(pBuffer, WriteAddr, SPI_FLASH_PageSize);
                WriteAddr +=  SPI_FLASH_PageSize;
                pBuffer += SPI_FLASH_PageSize;
            }

            if (NumOfSingle != 0)
            {
                spi_flash_PageWrite(pBuffer, WriteAddr, NumOfSingle);
            }
        }
    }
}

----------------------------------------------------------------------------------------------------------------------------------
void spi_flash_PageWrite(uint8* pBuffer, uint32 WriteAddr, uint16 NumByteToWrite)
{
   
    halspi_cs_low(); // 使能slave
   
    spi_flash_WriteEnable(); // 使能Flash写操作
      
    spi_flash_SendByte(W25X_PageProgram); // 发送 "Write to Memory " 指令
   
    //if(WriteAddr >= 0x1fffff)  WriteAddr = START_WRITE_LOCATION;//写到片尾,从第三个sector手开始从新写
   
    spi_flash_SendByte((WriteAddr & 0xFF0000) >> 16); // 发送待写入地址的高地址位
   
    spi_flash_SendByte((WriteAddr & 0xFF00) >> 8); // 发送待写入地址的中间不服地址位
   
    spi_flash_SendByte(WriteAddr & 0xFF); // 发送待写入地址的低地址位
   
    if(NumByteToWrite > SPI_FLASH_PerWritePageSize)
    {
        NumByteToWrite = SPI_FLASH_PerWritePageSize;
    }
   
    while (NumByteToWrite--) // 循环写数据
    {
        
        spi_flash_SendByte(*pBuffer); // 发送当前待写入的数据
        
        pBuffer++; // 下一个待写入数据
    }
   
    halspi_cs_high(); // 禁用slave
   
    spi_flash_WaitForWriteEnd(); // 等待Flash写操作结束
}

回复

使用道具 举报

752

TA的帖子

0

TA的资源

纯净的硅(初级)

Rank: 4

发表于 2015-4-7 17:05:45 | 显示全部楼层
cc2540f先建议不用休眠模式测试!!!!!!!!!!!!
大秦正声电子之家 http://yang96381.blog.163.com
提供蓝牙、zigbee芯片批量生产烧录服务:1带3脱机烧录工具,支持cc2540/cc2541,cc2530/2531,也支持nrf51822

回复 支持 反对

使用道具 举报

752

TA的帖子

0

TA的资源

纯净的硅(初级)

Rank: 4

发表于 2015-4-7 17:08:07 | 显示全部楼层
另外需要大批量烧录cc2540f芯片工具可以联系我!
大秦正声电子之家 http://yang96381.blog.163.com
提供蓝牙、zigbee芯片批量生产烧录服务:1带3脱机烧录工具,支持cc2540/cc2541,cc2530/2531,也支持nrf51822

回复 支持 反对

使用道具 举报

93

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2015-4-8 11:03:23 | 显示全部楼层
大秦正声 发表于 2015-4-7 17:05
cc2540f先建议不用休眠模式测试!!!!!!!!!!!!

无休眠模式测试过,也是1小时左右准时死机,死机提示IDATA益处,等几十秒后再提示XDATA益处!不知道是在操作flash的哪个步骤引起的问题!

回复 支持 反对

使用道具 举报

3405

TA的帖子

6

TA的资源

版主

Rank: 6Rank: 6

发表于 2015-4-8 13:24:17 | 显示全部楼层
这么有规律的错误显然是你的代码造成的,而且提示也很明确了,Xdata溢出。有可能是你的指针一直在加,直到超过了8K的范围,再读写这个指针指向的内容的时候就会出现这种情况了。仔细检查一下吧。
而且Flash每2秒写一些,一个扇区也就用三四天吧。我记得flash的扇区擦写次数也就10万次,具体的看一下datashet吧,确认一下这样的操作会不会影响flash的寿命。

回复 支持 反对

使用道具 举报

93

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2015-4-8 17:04:04 | 显示全部楼层
jishuaihu 发表于 2015-4-8 13:24
这么有规律的错误显然是你的代码造成的,而且提示也很明确了,Xdata溢出。有可能是你的指针一直在加,直到超过了8K的范围,再读写这个指针指向的内容的时候就会出现这种情况了。仔细检查一下吧。
而且Flash每2秒写一些,一个扇区也就用三四天吧。我记得flash的扇区擦写次数也就10万次,具体的看一下datashet吧,确认一下这样的操作会不会影响flash的寿命。

  一个扇区怎么可能用三到四天……循环写的!写一年都不会出事!XDATA溢出肯定知道是程序在某些情况操作出错导致程序跑飞呀,要不然程序怎么会跑飞呢?经过多次测试已经证明代码没错了!

回复 支持 反对

使用道具 举报

3405

TA的帖子

6

TA的资源

版主

Rank: 6Rank: 6

发表于 2015-4-8 17:59:09 | 显示全部楼层
自己确定了就行。既然代码没有问题那就是硬件问题。自己找呗

回复 支持 反对

使用道具 举报

1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2016-11-24 21:49:35 | 显示全部楼层
TI的CC2540读写spiflash,你这个搞好了么?可以把相关驱动发我一份么?谢谢,joneming@163.com

回复 支持 反对

使用道具 举报

60

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2017-3-25 20:44:44 | 显示全部楼层
你这个操作spiflash的流程有问题吧
1.要写入spiflash数据,如果不是全FF,需要先擦除后再写
2.写数据流程:
    2.1:先写首页;判断首页还剩下多少bytes
    2.2:写中间页
    2.3:写最后页

回复 支持 反对

使用道具 举报

60

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2017-3-25 20:57:15 | 显示全部楼层
CC2540自身去操作spiflash的话很容易导致蓝牙断开,TI本身就有这个bug。
像这种应用,最好外挂一个MCU去操作外挂的spiflash,不然很容易导致蓝牙断开。SPIFLASH擦除很费时间的,一个sector的擦除都要150ms具体看规格书

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

小黑屋|手机版|Archiver|电子工程世界 ( 京ICP证 060456

GMT+8, 2017-6-28 23:52 , Processed in 0.384211 second(s), 15 queries , Redis On.

快速回复 返回顶部 返回列表
关闭