[PIC®/AVR®/dsPIC®产品] 【分享】PIC16F1503读写flash所有函数

[复制链接]
8863|31
yhy08090 发表于 2019-7-3 16:32 | 显示全部楼层
本帖最后由 yhy08090 于 2019-7-4 11:32 编辑
lcczg 发表于 2019-7-3 15:54
程序空间一个word是14位。如果要存放16位的数据的话,写入前和读取后应该要做下处理。 ...

嗯,感觉有些奇怪
lcczg 发表于 2019-7-4 08:36 | 显示全部楼层
yhy08090 发表于 2019-7-3 16:32
嗯,感觉处理有些头大。奇怪

只是针对数据存储需要处理,对于程序是不需要的,因为指令都是14位的。这样设计方便指令存储,毕竟Flash基本都是放程序的。

评分

参与人数 1威望 +2 收起 理由
yhy08090 + 2 很给力!

查看全部评分

yhy08090 发表于 2019-7-10 13:21 | 显示全部楼层
本帖最后由 yhy08090 于 2019-7-10 13:28 编辑

我在PIC16  18346 上按照楼主的行写,写一次结束后,重启MCU, 发现电流从200ma掉电至90MA, MCU不能正常工作了。
小卡 发表于 2019-7-12 14:03 | 显示全部楼层
感激分享~  
淘猫汤姆 发表于 2019-7-12 19:43 来自手机 | 显示全部楼层
zbcaich 发表于 2018-1-7 20:53
如附图,在ROM range后面指定要空出来的空间,编译器就不会在这个空间内放置任何数据了
...

这个才是正解
xixi2017 发表于 2019-8-15 14:26 来自手机 | 显示全部楼层
谢谢楼主分享
jiekou001 发表于 2019-8-20 19:29 来自手机 | 显示全部楼层
感谢楼主分享,帮你顶一下
wkq123456789 发表于 2020-9-9 08:26 | 显示全部楼层
Antecer 发表于 2016-1-9 20:40
你好,我用PIC16F1455编写了读写flash的函数,然而读取没问题,擦除和写入都无法成功。

在这里看到了你的 ...

你好,可以和你交流一下1455嘛
自己造声卡 发表于 2020-9-9 08:36 | 显示全部楼层
感谢楼主分享,这种资料太真贵了。谢谢。
看别人照片 发表于 2020-9-9 08:43 | 显示全部楼层
感谢楼主的分享,感谢大家,感谢21ic
Antecer 发表于 2023-7-10 14:26 | 显示全部楼层
本帖最后由 Antecer 于 2023-7-10 14:28 编辑
wkq123456789 发表于 2020-9-9 08:26
你好,可以和你交流一下1455嘛

都在这里了:
  1. <font size="2">/*PIC16F1455 Program Flash Memory 读写库函数*/
  2. #include <pic.h>
  3. #include "Flash.h"

  4. #define FLASHSPACE  0x2000      //单片机的FlashROM大小
  5. #define ROWLENGTH   32          //Flash的擦写块大小

  6. /*************************************************
  7. * 功能:单字读取函数
  8. * 说明: 按字读取闪存(读取1个16位数据)
  9. * 参数: FlashAddr 需要读取的字的地址
  10. * 返回: PMDAT 读取到的数据
  11. *************************************************/
  12. UINT16 FlashReadWord(UINT16 FlashAddr)
  13. {
  14.     if(FlashAddr >= FLASHSPACE) return 0;
  15.     PMCON1bits.CFGS=0;
  16.     PMADR = FlashAddr;
  17.     PMCON1bits.RD=1;
  18.     NOP();
  19.     NOP();
  20.     return PMDAT;
  21. }
  22. /**************************************************
  23. * 功能:多字读取函数
  24. * 说明: 从FLASH中读取多个字到指定数组
  25. * 参数: FlashAddr 要读取的起始地址
  26. *      *DataStr 指向存储数组的指针
  27. *       Length 需要读取的内容长度
  28. * 返回: 无
  29. **************************************************/
  30. void FlashReadWords(UINT16 FlashAddr , UINT16 *DataStr,UINT8 Length)
  31. {
  32.     for(UINT8 i=0;i<Length;i++)
  33.     {
  34.         DataStr[i]=FlashReadWord(FlashAddr);
  35.         FlashAddr++;
  36.     }
  37. }
  38. /**************************************************
  39. * 功能:Bytes读取函数(取程序存储器低8位)
  40. * 说明: 从FLASH中读取多个UINT8数据到指定数组
  41. * 参数: FlashAddr 要读取的起始地址
  42. *      *DataStr 指向存储数组的指针
  43. *       Length 需要读取的内容长度
  44. * 返回: 无
  45. **************************************************/
  46. void FlashReadBytes(UINT16 FlashAddr , UINT8 *DataStr,UINT8 Length)
  47. {
  48.     for(UINT8 i=0;i<Length;i++)
  49.     {
  50.         DataStr[i] = 0xff & FlashReadWord(FlashAddr);
  51.         FlashAddr++;
  52.     }
  53. }

  54. /***************************************************
  55. * 功能:FLASH解锁函数
  56. * 说明: FLASH只有在解锁后才能执块擦除和写入操作
  57. * 参数: 无
  58. * 返回: 无
  59. ***************************************************/
  60. void FlashUnlock(void)
  61. {
  62.     PMCON2=0x55;
  63.     PMCON2=0xAA;
  64.     PMCON1bits.WR=1;
  65.     NOP();
  66.     NOP();
  67. }
  68. /***************************************************
  69. * 功能:FLASH按块擦除函数(只能整块擦除ROWLENGTHByte)
  70. * 说明: Flash块擦除(0x0000~0x001F/0x0010~0x002F/..)
  71. * 参数: FlashAddr 被擦除块的首地址
  72. * 返回: 无
  73. ***************************************************/
  74. void FlashErase(UINT16 FlashAddr)
  75. {
  76.     INTCONbits.GIE=0;
  77.     PMCON1bits.CFGS=0;
  78.     PMADR = FlashAddr & 0x7fff;
  79.     PMCON1bits.FREE=1;
  80.     PMCON1bits.WREN=1;
  81.     FlashUnlock();
  82.     PMCON1bits.WREN=0;
  83.     INTCONbits.GIE=1;
  84. }
  85. /***************************************************
  86. * 功能:FLASH按块写数据函数
  87. * 说明:FLASH块写入(块长度为32)
  88. * 参数:FlashAddr 块首地址
  89. *      *DataStr 数组指针(单个数据不得大于0x3fff)
  90. *       Length 要写的数据长度(不能超过 ROWLENGTH 个)
  91. * 返回:无
  92. * 重要:按块写入数据不能跨越某些边界(0x0100/0x0200/..)
  93. ***************************************************/
  94. void FlashWriteRow(UINT16 FlashAddr,UINT16 *DataStr,UINT8 Length)//必须块地址
  95. {
  96.     UINT8 i=0;
  97.     INTCONbits.GIE=0;
  98.     PMADR = FlashAddr & 0x7fff;
  99.     PMCON1bits.FREE=0;
  100.     PMCON1bits.CFGS=0;
  101.     PMCON1bits.WREN=1;
  102.     PMCON1bits.LWLO=1;
  103.     while(1)
  104.     {
  105.         PMDAT = 0x3fff & DataStr[i];
  106.         i++;
  107.         if(i>=Length) break;
  108.         FlashUnlock();
  109.         PMADRL++;//锁存器地址+1
  110.     }
  111.     PMCON1bits.LWLO=0;
  112.     FlashUnlock();
  113.     PMCON1bits.WREN=0;
  114.     INTCONbits.GIE=1;
  115. }
  116. /***************************************************
  117. * 功能:FLASH按字写函数(写入一个UINT16数据)
  118. * 说明: 任意地址任意字,只写该字,自动原数据重写
  119. * 参数: FlashAddr 写入地址
  120. *       data 写入的内容
  121. * 返回: 无
  122. ***************************************************/
  123. void FlashWriteWord(UINT16 FlashAddr,UINT16 data)
  124. {
  125.     UINT16 tmpdata[ROWLENGTH];
  126.     UINT16 rowFlashAddr = FlashAddr & 0xfff0;
  127.     UINT8 wordFlashAddr=FlashAddr & 0x000f;
  128.     if((rowFlashAddr%0x20) > 0)                         //写入地址块对齐
  129.     {
  130.         rowFlashAddr = rowFlashAddr - 0x10;
  131.         wordFlashAddr = wordFlashAddr + 0x10;
  132.     }
  133.     FlashReadWords(rowFlashAddr,tmpdata,ROWLENGTH);              //整块读出数据
  134.     tmpdata[wordFlashAddr] = data;                      //要写入的数据
  135.     FlashErase(rowFlashAddr);                           //擦除整块
  136.     FlashWriteRow(rowFlashAddr,tmpdata,ROWLENGTH);             //整块写入数据
  137. }
  138. /***************************************************
  139. * 功能:FLASH按Byte写函数(写入程序存储器低8位)
  140. * 说明: 任意地址任意Byte,只写该Byte,自动原数据重写
  141. * 参数: FlashAddr 写入地址
  142. *       data 写入的内容
  143. * 返回: 无
  144. ***************************************************/
  145. void FlashWriteByte(UINT16 FlashAddr,UINT8 data)
  146. {
  147.     UINT16 tmpdata[ROWLENGTH];
  148.     UINT16 rowFlashAddr = FlashAddr & 0xfff0;
  149.     UINT8 wordFlashAddr=FlashAddr & 0x000f;
  150.     if((rowFlashAddr%0x20) > 0)                         //写入地址块对齐
  151.     {
  152.         rowFlashAddr = rowFlashAddr - 0x10;
  153.         wordFlashAddr = wordFlashAddr + 0x10;
  154.     }
  155.     FlashReadWords(rowFlashAddr,tmpdata,ROWLENGTH);               //整块读出数据
  156.     tmpdata[wordFlashAddr] = tmpdata[wordFlashAddr]&0xff00|data;//要写入的数据
  157.     FlashErase(rowFlashAddr);                                   //擦除整块
  158.     FlashWriteRow(rowFlashAddr,tmpdata,ROWLENGTH);              //整块写入数据
  159. }
  160. /***************************************************
  161. * 功能:FLASH写任意长度UINT16函数
  162. * 说明:在任意地址写入任意长度的数据
  163. * 参数:FlashAddr 要写入内容的首地址
  164. *      *DataStr 要写入的数组指针
  165. *       Length 要写入的数组长度
  166. * 返回:无
  167. ***************************************************/
  168. void FlashWriteWords(UINT16 FlashAddr , UINT16 *DataStr,UINT8 Length)
  169. {
  170.     UINT16 tmpdata[ROWLENGTH];
  171.     UINT8 tmpLength = 0;
  172.     UINT16 rowFlashAddr = FlashAddr & 0xfff0;
  173.     UINT8 wordFlashAddr=FlashAddr & 0x000f;
  174.     if((rowFlashAddr%0x20) > 0)                                 //写入地址块对齐
  175.     {
  176.         rowFlashAddr = rowFlashAddr - 0x10;
  177.         wordFlashAddr = wordFlashAddr + 0x10;
  178.     }
  179.     while(1)
  180.     {
  181.         FlashReadWords(rowFlashAddr,tmpdata,ROWLENGTH);                  //整块读出数据
  182.         for(unsigned i=0;i<ROWLENGTH;i++)
  183.         {
  184.             if(i>=wordFlashAddr)
  185.             {
  186.                 tmpdata[i] = DataStr[tmpLength];                //要写入的数据
  187.                 tmpLength++;
  188.             }
  189.             if(tmpLength>=Length) break;
  190.         }
  191.         FlashErase(rowFlashAddr);                               //擦除整块
  192.         FlashWriteRow(rowFlashAddr,tmpdata,ROWLENGTH);                 //整块写入数据
  193.         rowFlashAddr = rowFlashAddr + 0x20;                     //块地址+1
  194.         wordFlashAddr= 0;
  195.         if(tmpLength>=Length) break;
  196.     }

  197. }
  198. /***************************************************
  199. * 功能:FLASH写任意长度UINT8函数(写入程序存储器低8位)
  200. * 说明:在任意地址写入任意长度的数据
  201. * 参数:FlashAddr 要写入内容的首地址
  202. *      *DataStr 要写入的数组指针
  203. *       Length 要写入的数组长度
  204. * 返回:无
  205. ***************************************************/
  206. void FlashWriteBytes(UINT16 FlashAddr , UINT8 *DataStr,UINT8 Length)
  207. {
  208.     UINT16 tmpdata[ROWLENGTH];
  209.     UINT8 tmpLength = 0;
  210.     UINT16 rowFlashAddr = FlashAddr & 0xfff0;
  211.     UINT8 wordFlashAddr=FlashAddr & 0x000f;
  212.     if((rowFlashAddr%0x20) > 0)                                     //写入地址块对齐
  213.     {
  214.         rowFlashAddr = rowFlashAddr - 0x10;
  215.         wordFlashAddr = wordFlashAddr + 0x10;
  216.     }
  217.     while(1)
  218.     {
  219.         FlashReadWords(rowFlashAddr,tmpdata,ROWLENGTH);               //整块读出数据
  220.         for(unsigned i=0;i<ROWLENGTH;i++)
  221.         {
  222.             if(i>=wordFlashAddr)
  223.             {
  224.                 tmpdata[i] = tmpdata[i]&0xff00|DataStr[tmpLength];  //要写入的数据
  225.                 tmpLength++;
  226.             }
  227.             if(tmpLength>=Length) break;
  228.         }
  229.         FlashErase(rowFlashAddr);                                   //擦除整块
  230.         FlashWriteRow(rowFlashAddr,tmpdata,ROWLENGTH);              //整块写入数据
  231.         rowFlashAddr = rowFlashAddr + 0x20;                         //块地址+1
  232.         wordFlashAddr= 0;
  233.         if(tmpLength>=Length) break;
  234.     }
  235. }</font>
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部