搜索
bottom↓
回复: 14

MSP430F4512 FLASH擦写问题请教

[复制链接]

出20入70汤圆

发表于 2014-6-6 16:07:52 | 显示全部楼层 |阅读模式
本帖最后由 techbaby 于 2014-6-6 17:18 编辑

如下:
      
     
     MSP430F4512的Information memory明明有256Byte,读写FLASH时在0x10C0-0x10FF部分始终无法写入(其他字节正常),不知为何?
     有遇到相同情况的兄弟出来冒个泡!



-------------------------------------------------------------------------------------------------------------------
后记:
问题解决!
INFO FLASH有一个LOCKA锁,专门锁定segmentA。
多谢帮忙的朋友!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2014-6-6 16:10:22 | 显示全部楼层
你先用原厂的FALSH 读写例子试试看。

出20入70汤圆

 楼主| 发表于 2014-6-6 16:21:37 | 显示全部楼层
spacefram 发表于 2014-6-6 16:10
你先用原厂的FALSH 读写例子试试看。

其实就是根据原厂的例程更改的。

出20入70汤圆

 楼主| 发表于 2014-6-6 16:26:04 | 显示全部楼层
有兴趣的哥们帮我验证一下

flash.h

  1. /*
  2. ********************************************************************************
  3. *有限公司
  4. *                                 研    发    部
  5. *               
  6. *                               All Rights Reserved
  7. *
  8. *------------------------------------文件信息-----------------------------------
  9. * 文 件 名: flash.h
  10. * 版          本: v0.01
  11. * 日        期: 2014.03.27
  12. * 作    者:
  13. * 描    述: flash操作函数
  14. ********************************************************************************
  15. */
  16. #ifndef __FLASH_H__
  17. #define __FLASH_H__

  18. /*
  19. ********************************************************************************
  20. *                                                 predefinitions
  21. ********************************************************************************
  22. */
  23. // Information Flash
  24. #define SEGMENT_LENGTH                (0x40)
  25. #define SEGMENT_A_ADDR                 (0x10C0)
  26. #define SEGMENT_B_ADDR                 (0x1080)
  27. #define SEGMENT_C_ADDR                 (0x1040)
  28. #define SEGMENT_D_ADDR                 (0x1000)


  29. /*
  30. ********************************************************************************
  31. *                                                 include files
  32. ********************************************************************************
  33. */

  34. /*
  35. ********************************************************************************
  36. *                                               functions declaration
  37. ********************************************************************************
  38. */
  39. extern void flash_read(int16u addr, int16u num, int8u *buf);
  40. extern void flash_write(int16u addr, int16u num, int8u *buf);

  41. #endif


复制代码


flash.c
  1. /*
  2. ********************************************************************************
  3. *
  4. *                           有限公司
  5. *                                 研    发    部
  6. *               
  7. *                               All Rights Reserved
  8. *
  9. *------------------------------------文件信息-----------------------------------
  10. * 文 件 名: flash.c
  11. * 版          本: v0.01
  12. * 日        期: 2014.03.27
  13. * 作    者:
  14. * 描    述: flash操作函数
  15. ********************************************************************************
  16. */

  17. /*
  18. ********************************************************************************
  19. *                                                 include files
  20. ********************************************************************************
  21. */
  22. #include "io430.h"
  23. #include "cpu.h"

  24. #include "flash.h"

  25. /*
  26. ********************************************************************************
  27. *                                                 predefinitions
  28. ********************************************************************************
  29. */

  30. /*
  31. ********************************************************************************
  32. * 函数名称: _erase_segment()
  33. * 输   入: addr 擦除段内的任意地址
  34. * 输   出:
  35. * 作   者:
  36. * 日   期:
  37. * 功能描述: 擦除段
  38. ********************************************************************************
  39. */
  40. //static void _erase_segment(int16u addr)
  41. //{
  42. //        char *Flash_ptr;                          // Flash pointer
  43. //       
  44. //        Flash_ptr = (char *)addr;                 // Initialize Flash pointer
  45. //        FCTL3 = FWKEY;                            // Clear Lock bit
  46. //        FCTL1 = FWKEY + ERASE;                    // Set Erase bit
  47. //       
  48. //        *Flash_ptr = 0;                           // Dummy write to erase Flash seg
  49. //       
  50. //        FCTL1 = FWKEY;                            // Clear ERASE bit
  51. //        FCTL3 = FWKEY + LOCK;                     // Set LOCK bit       
  52. //}

  53. /*
  54. ********************************************************************************
  55. * 函数名称: _read_segment()
  56. * 输   入: addr 读单个Information Segment内的任意地址
  57. *           buf  读取数据指针,大小为SEGMENT_LENGTH
  58. * 输   出:
  59. * 作   者:
  60. * 日   期:
  61. * 功能描述: 读取整个Information Segment的内容
  62. ********************************************************************************
  63. */
  64. static void _read_segment(int16u addr, char *buf)
  65. {
  66.         char *Flash_ptr;                          // Flash pointer
  67.         int i;
  68.        
  69.         // 赋值段起始地址
  70.         Flash_ptr = (char *)(addr & ~(SEGMENT_LENGTH - 1));     // Initialize Flash pointer
  71.                
  72.         for (i = 0; i < SEGMENT_LENGTH; i++)
  73.         {
  74.                 *buf++ = *Flash_ptr++;                 // read value from flash
  75.         }
  76. }

  77. /*
  78. ********************************************************************************
  79. * 函数名称: _write_segment()
  80. * 输   入: addr 写入单个Information Segment内的任意地址
  81. *           buf  写入数据指针,大小为SEGMENT_LENGTH
  82. * 输   出:
  83. * 作   者:
  84. * 日   期:
  85. * 功能描述: 将buf信息写入整个Information Segment
  86. ********************************************************************************
  87. */
  88. void _write_segment(int16u addr, char *buf)
  89. {
  90.         char *Flash_ptr;                          // Flash pointer
  91.         unsigned int i;
  92.        
  93.         // 赋值段起始地址
  94.         Flash_ptr = (char *)(addr & ~(SEGMENT_LENGTH - 1));   // Initialize Flash pointer
  95.         FCTL3 = FWKEY;                            // Clear Lock bit
  96.         FCTL1 = FWKEY + ERASE;                    // Set Erase bit
  97.         *Flash_ptr = 0;                           // Dummy write to erase Flash seg
  98.        
  99.         FCTL1 = FWKEY + WRT;                      // Set WRT bit for write operation
  100.        
  101.         for (i = 0; i < 64; i++)
  102.         {
  103.                 *Flash_ptr++ = *buf++;                   // Write value to flash
  104.         }
  105.        
  106.         FCTL1 = FWKEY;                            // Clear WRT bit
  107.         FCTL3 = FWKEY + LOCK;                     // Set LOCK bit
  108. }

  109. /*
  110. ********************************************************************************
  111. * 函数名称: flash_write()
  112. * 输   入: addr 地址
  113. *           num  写入数据数量
  114. *           buf  写入的数据
  115. * 输   出:
  116. * 作   者:
  117. * 日   期: 2014.05.06
  118. * 功能描述: 写入数据到flash中
  119. ********************************************************************************
  120. */
  121. //int _flash_write(int16u addr, int8u num, int8u *buf)
  122. //{
  123. //        char *ptr;
  124. //        char *buffer[SEGMENT_LENGTH];
  125. //        int8u i;
  126. //        int16u addr_start;
  127. //       
  128. //        addr_start = addr & (SEGMENT_LENGTH - 1);
  129. //       
  130. //        // 拷贝数据到临时缓存区
  131. //        ptr = (char *)(addr_start);       
  132. //        for (i = 0; i < SEGMENT_LENGTH; i++)
  133. //        {
  134. //                buffer[i] = *ptr++;               
  135. //        }
  136. //       
  137. //        // 更改缓冲区数据
  138. //        ptr = (char *)(buf + (addr - addr_start));
  139. //        for (i = 0; i < num; i++)
  140. //        {
  141. //                buffer[addr - addr_start + i] = *ptr++;               
  142. //        }
  143. //       
  144. //        // 擦除段         
  145. //        _erase_segment(addr);
  146. //       
  147. //        // 回写数据到flash
  148. //        _write_segment(addr_start, buffer);
  149. //}

  150. /*
  151. ********************************************************************************
  152. * 函数名称: flash_read()
  153. * 输   入: addr 地址
  154. *           num  读取数据数量
  155. *           buf  读取的数据
  156. * 输   出:
  157. * 作   者:
  158. * 日   期: 2014.05.06
  159. * 功能描述: 读取flash中的数据
  160. ********************************************************************************
  161. */
  162. void flash_read(int16u addr, int16u num, int8u *buf)
  163. {
  164.         char *Flash_ptr;                              // Flash pointer
  165.         int i;
  166.        
  167.         Flash_ptr = (char *)addr;             // Initialize Flash pointer
  168.                
  169.         for (i = 0; i < num; i++)
  170.         {
  171.                 *buf++ = *Flash_ptr++;                // read value from flash
  172.         }       
  173. }

  174. /*
  175. ********************************************************************************
  176. * 函数名称: flash_write()
  177. * 输   入: addr 地址
  178. *           num  写入数据数量最大为SEGMENT_LENGTH
  179. *           buf  写入的数据
  180. * 输   出:
  181. * 作   者:
  182. * 日   期: 2014.05.06
  183. * 功能描述: 写入数据到flash中
  184. ********************************************************************************
  185. */
  186. void flash_write(int16u addr, int16u num, int8u *buf)
  187. {
  188.         char *ptr;
  189.         char buffer[SEGMENT_LENGTH];
  190.         unsigned int i;
  191.         unsigned char offset;                        // 偏移
  192.         unsigned int first_segment;                // 第一段地址
  193.         unsigned int second_segment;        // 第二段地址
  194.        
  195.         // MCLK/3 for Flash Timing Generator
  196.         FCTL2 = FWKEY + FSSEL0 + FN1;            
  197.        
  198.         offset = addr & (SEGMENT_LENGTH - 1);
  199.         first_segment = addr & ~(SEGMENT_LENGTH - 1);
  200.         second_segment = first_segment + SEGMENT_LENGTH;
  201.        
  202.         if (addr + num <= second_segment)        // 操作处于单个段内
  203.         {
  204.                 // 读数据到缓存
  205.                 _read_segment(first_segment, buffer);
  206.                
  207.                 // 更改缓存数据
  208.                 ptr = buffer + offset;        // offset
  209.                 for (i = 0; i < num; i++)
  210.                 {
  211.                         *ptr++ = *buf++;                 
  212.                 }
  213.                
  214.                 // 回写数据到缓存
  215.                 _write_segment(first_segment, buffer);       
  216.         }
  217.         else        // 操作处于两个段内
  218.         {       
  219.                 //------操作第一段----------------
  220.                 // 读数据到缓存
  221.                 _read_segment(first_segment, buffer);
  222.                
  223.                 // 更改缓存数据
  224.                 ptr = buffer + offset;        // offset
  225.                 for (i = 0; i < SEGMENT_LENGTH - offset; i++)
  226.                 {
  227.                         *ptr++ = *buf++;                 
  228.                 }
  229.                
  230.                 // 回写数据到缓存
  231.                 _write_segment(first_segment, buffer);       

  232.                 //------操作第二段---------------
  233.                 // 读数据到缓存
  234.                 _read_segment(second_segment, buffer);
  235.                
  236.                 // 更改缓存数据
  237.                 ptr = buffer;        // offset = 0
  238.                 for (i = 0; i < num - (SEGMENT_LENGTH - offset); i++)
  239.                 {
  240.                         *ptr++ = *buf++;                 
  241.                 }
  242.                
  243.                 // 回写数据到缓存
  244.                 _write_segment(second_segment, buffer);                       
  245.         }
  246. }














复制代码

出0入0汤圆

发表于 2014-6-6 16:30:23 | 显示全部楼层
INFO的FLASH读写有专门的锁的。
有专门读写INFO的例程。

出20入70汤圆

 楼主| 发表于 2014-6-6 16:34:27 | 显示全部楼层
divineliu 发表于 2014-6-6 16:30
INFO的FLASH读写有专门的锁的。
有专门读写INFO的例程。

INFO FLASH 256字节分4段,前3段读写都正确,唯独最后一段写入没反映,仿真查看最后一段全是0xFF。

不知道是不是最后一段还有特殊处理,我再看看datasheet(其实还真没有认真看flash这一部分:-) );

出20入70汤圆

 楼主| 发表于 2014-6-6 16:39:55 | 显示全部楼层
divineliu 发表于 2014-6-6 16:30
INFO的FLASH读写有专门的锁的。
有专门读写INFO的例程。

还真有一个LOCKA锁,专门锁定segmentA。

哥们,太谢谢你了,我再研究研究!

出20入70汤圆

 楼主| 发表于 2014-6-6 17:15:02 | 显示全部楼层
divineliu 发表于 2014-6-6 16:30
INFO的FLASH读写有专门的锁的。
有专门读写INFO的例程。

多谢哥们了,如你所言,确实是有LOCKA锁的原因,现在我的问题圆满解决了。
再次感谢所有帮忙的朋友。

出0入0汤圆

发表于 2014-6-6 17:38:44 | 显示全部楼层
问题解决了大家都很高兴。
仿真器每次upload程序的时候,偶然发现infoA总是擦不干净,
后来调查了一下,知道了有个特别的锁。

出20入70汤圆

 楼主| 发表于 2014-6-6 21:34:08 | 显示全部楼层
divineliu 发表于 2014-6-6 17:38
问题解决了大家都很高兴。
仿真器每次upload程序的时候,偶然发现infoA总是擦不干净,
后来调查了一下,知 ...

看来你是用了不少430的片子,我是第一次使用,呵呵!

出20入70汤圆

 楼主| 发表于 2014-6-30 11:29:46 | 显示全部楼层
本帖最后由 techbaby 于 2014-6-30 11:30 编辑
cocalli 发表于 2014-6-30 11:20
你好,能共享下最后的读写代码?
我也是第一次使用430直接上项目,查看了不少,就怕有漏的。
我刚开始以 ...


读写代码上面的回复中有啊!

唯一不同的是擦除时将LOCKA复位,如下:

  1. static void _write_segment(int16u addr, char *buf)
  2. {
  3.         char *Flash_ptr;                          // Flash pointer
  4.         unsigned int i;
  5.        
  6.         // 赋值段起始地址
  7.         Flash_ptr = (char *)(addr & ~(SEGMENT_LENGTH - 1));   // Initialize Flash pointer
  8.         FCTL3 = FWKEY + LOCKA;                    // Clear Lock bit
  9.         FCTL1 = FWKEY + ERASE;                    // Set Erase bit
  10.         *Flash_ptr = 0;                           // Dummy write to erase Flash seg
  11.        
  12.         FCTL1 = FWKEY + WRT;                      // Set WRT bit for write operation
  13.        
  14.         for (i = 0; i < SEGMENT_LENGTH; i++)
  15.         {
  16.                 *Flash_ptr++ = *buf++;                // Write value to flash
  17.         }
  18.        
  19.         FCTL1 = FWKEY;                            // Clear WRT bit
  20.         FCTL3 = FWKEY + LOCK + LOCKA;             // Set LOCK bit
  21. }
复制代码

出20入70汤圆

 楼主| 发表于 2014-6-30 11:56:10 | 显示全部楼层
FLASH次数有限制,这个没办法啊!只能尽量减少擦写次数。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-24 00:25

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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