N76E003 APROM作为EEPROM使用的问题!

2020-01-13 18:31发布

N76E003跟stm8s003相比没有内部的eeprom,有教程通过用APROM分区(0x3800~0x38FF)作为内部eeprom使用;

  1. bit BIT_TMP;

  2. /* -------------------------------------------------------------------------*/
  3. /*  Dataflash use APROM area                                                                                                                         */
  4. /*        APROM 0x3800~0x38FF demo as dataflash                                                                                                     */
  5. /* Please use Memory window key in C:0x3800 to check earse result                                          */              
  6. /* -------------------------------------------------------------------------*/
  7. UINT8 read_APROM_BYTE(UINT16 code *u16_addr)
  8. {
  9.         UINT8 rdata;
  10.         rdata = *u16_addr>>8;
  11.         return rdata;
  12. }

  13. //-------------------------------------------------------------------------

  14. //-------------------------------------------------------------------------


  15. /*****************************************************************************************************************
  16. write_DATAFLASH_BYTE :
  17. user can copy all this subroutine into project, then call this function in main.
  18. ******************************************************************************************************************/               
  19. void write_DATAFLASH_BYTE(UINT16 u16_addr,UINT8 u8_data)
  20. {
  21.        
  22.         UINT8 looptmp=0,u8_addrl_r;
  23.         unsigned char code *cd_longaddr;
  24.         unsigned char xdata *xd_tmp;
  25.        
  26. //Check page start address
  27.         u8_addrl_r = u16_addr;
  28.         if (u8_addrl_r<0x80)
  29.         {
  30.                 u8_addrl_r = 0;
  31.         }
  32.         else
  33.         {
  34.                 u8_addrl_r = 0x80;
  35.         }
  36. //Save APROM data to XRAM
  37.         xd_tmp = 0x80;
  38.         cd_longaddr = (u16_addr&0xff00)+u8_addrl_r;       
  39.         while (xd_tmp !=0x100)
  40.         {
  41.                 *xd_tmp = *cd_longaddr;
  42.                 looptmp++;
  43.                 xd_tmp++;
  44.                 cd_longaddr++;
  45.         }
  46. // Modify customer data in XRAM
  47.         u8_addrl_r = u16_addr;
  48.         if (u8_addrl_r<0x80)
  49.         {
  50.                 xd_tmp = u8_addrl_r+0x80;
  51.         }
  52.         else
  53.         {
  54.                 xd_tmp = u8_addrl_r+0;
  55.         }
  56.         *xd_tmp = u8_data;
  57. //Erase APROM DATAFLASH page
  58.                 IAPAL = u16_addr;
  59.                 IAPAH = u16_addr>>8;
  60.                 IAPFD = 0xFF;
  61.           set_IAPEN;
  62.                 set_APUEN;
  63.     IAPCN = 0x22;                
  64.                 set_IAPGO;
  65. //Save changed RAM data to APROM DATAFLASH
  66.         u8_addrl_r = u16_addr;
  67.         if (u8_addrl_r<0x80)
  68.         {
  69.                 u8_addrl_r =0;
  70.         }
  71.         else
  72.         {
  73.                 u8_addrl_r = 0x80;
  74.         }
  75.                 xd_tmp = 0x80;
  76.           IAPAL = u8_addrl_r;
  77.     IAPAH = u16_addr>>8;
  78.                 set_IAPEN;
  79.                 set_APUEN;
  80.           IAPCN = 0x21;
  81.                 while (xd_tmp !=0xFF)
  82.                 {
  83.                         IAPFD = *xd_tmp;
  84.                         set_IAPGO;
  85.                         IAPAL++;
  86.                         xd_tmp++;
  87.                 }
  88.                 clr_APUEN;
  89.                 clr_IAPEN;
  90. }   
复制代码
单独的读写验证已经通过,但是当定义如下结构体之后,就无法进行写操作了,

  1. typedef_split3 DisMenu[7]=
  2. {
  3.   {13,0x81,0x01},/* 'P' '1.' '1'*/
  4.   {13,0x81,0x02},/* 'P' '1.' '2'*/
  5.   {13,0x81,0x03},/* 'P' '1.' '3'*/

  6.   {13,16,0x02},/* 'P' '-' '2'*/

  7.   {13,0x83,0x01},/* 'P' '3.' '1'*/
  8.   {13,0x83,0x02},/* 'P' '3.' '2'*/

  9.   {13,16,0x04},/* 'P' '-' '4'*/
  10. };
复制代码
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
10条回答
mandey
1楼-- · 2020-01-14 18:03
 精彩回答 2  元偷偷看……
Ray______
2楼-- · 2020-01-14 20:04
涵潇舒雅 发表于 2017-10-23 09:13
前辈,弄否分享一下?感觉这个DEMO太吃内存了~
  1. #define PAGE_ERASE_AP       0x22
  2. #define BYTE_PROGRAM_AP     0x21
  3. #define BYTE_READ_AP        0X00


  4. volatile uint8_t code Data_Flash[128] _at_ 0x0200;
  5. uint8_t saveTmp[USE_EEPROM_SIZE];

  6. /************************************************************************************************************
  7. *    判断是否新片,全FF为新片
  8. *    1:新片    0:用过
  9. ************************************************************************************************************/
  10. uint8_t CheckNewChip(void)
  11. {
  12.     uint8_t datTmp;
  13.    
  14.     datTmp = Data_Flash[0];
  15.     if(datTmp == 0xff)
  16.         return 1;
  17.     else
  18.         return 0;
  19.    
  20.    
  21.    
  22.     return 1;
  23. }
  24. /************************************************************************************************************
  25. *    写一个字节进APROM
  26. ************************************************************************************************************/
  27. void APROM_WriteOneByte(uint16_t addr, uint8_t dat)
  28. {
  29.     uint8_t offset;
  30.     uint8_t i;
  31.    
  32.     offset = addr - START_EEPROM_ADD;
  33.     for( i = 0; i < USE_EEPROM_SIZE; i++){  saveTmp[i] = Data_Flash[i]; }//Copy data to temp area
  34.     saveTmp[offset] = dat;                                               //Write data into temp area
  35.    
  36.     set_IAPEN;              //Enable IAP mode
  37.     set_APUEN;              //Enable APROM update
  38.    
  39.     IAPCN = PAGE_ERASE_AP;  //Erase page ,128byte of one page
  40.     IAPAH = EEPROM_HIGH_ADD;
  41.     IAPAL = 0x00;
  42.     IAPFD = 0xFF;           //Erase
  43.     set_IAPGO;              //Trigger IAP process
  44.    
  45.     IAPCN = BYTE_PROGRAM_AP;//APROM Byte program
  46.     for( i = 0; i < USE_EEPROM_SIZE; i++)//Write data into APROM
  47.     {
  48.         IAPAH = EEPROM_HIGH_ADD;
  49.         IAPAL = i;
  50.         IAPFD = saveTmp[i];
  51.         set_IAPGO;              //Trigger IAP process
  52.     }
  53.                            
  54.     clr_APUEN;              //Disable APROM update
  55.     clr_IAPEN;              //Disable IAP mode
  56. }

  57. /************************************************************************************************************
  58. *    写一串数据进APROM
  59. ************************************************************************************************************/
  60. void APROM_WriteBuf(uint16_t addr, uint8_t *in, uint8_t len)
  61. {
  62.     uint8_t offset;
  63.     uint8_t i;
  64.    
  65.     offset = addr - START_EEPROM_ADD;
  66.     cpybuf( saveTmp, Data_Flash, USE_EEPROM_SIZE);//Copy data to temp area
  67.     cpybuf( saveTmp + offset, in, len);           //Copy buff into temp area
  68.    
  69.     set_IAPEN;              //Enable IAP mode
  70.     set_APUEN;              //Enable APROM update
  71.    
  72.     IAPCN = PAGE_ERASE_AP;  //Erase page ,128byte of one page
  73.     IAPAH = EEPROM_HIGH_ADD;
  74.     IAPAL = 0x00;
  75.     IAPFD = 0xFF;      
  76.     set_IAPGO;              //Trigger IAP process
  77.    
  78.     IAPCN = BYTE_PROGRAM_AP;//APROM Byte program
  79.     for( i = 0; i < USE_EEPROM_SIZE; i++)//Write data into APROM
  80.     {
  81.         IAPAH = EEPROM_HIGH_ADD;
  82.         IAPAL = i;
  83.         IAPFD = saveTmp[i];
  84.         set_IAPGO;              //Trigger IAP process
  85.     }
  86.                            
  87.     clr_APUEN;              //Disable APROM update
  88.     clr_IAPEN;              //Disable IAP mode   
  89. }


  90. /************************************************************************************************************
  91. *    读APROM一个字节
  92. ************************************************************************************************************/
  93. uint8_t Read_APROM_Byte(uint16_t addr)
  94. {
  95.     uint8_t dataTmp;
  96.    
  97.     dataTmp = Data_Flash[addr - START_EEPROM_ADD];
  98.    
  99.     return dataTmp;
  100. }

  101. /************************************************************************************************************
  102. *    读APROM连续字节
  103. ************************************************************************************************************/
  104. void Read_APROM_Buf(uint16_t addr, uint8_t *out, uint8_t len)
  105. {
  106.     uint8_t offset;
  107.    
  108.     offset = addr - START_EEPROM_ADD;
  109.         cpybuf( out, &Data_Flash[offset], len);
  110. }
复制代码
Ray______
3楼-- · 2020-01-14 23:09
Ray______ 发表于 2017-10-23 20:13

有个问题就是按照手册的从0x200开始了,会对应按数据大小生成对应的区域当作EEP用,可以自己选其他的区域,不过读写函数内部有些地址得改下,因为没有用宏做。
蛋定
4楼-- · 2020-01-15 04:06
记号,谢谢,学习了。

一周热门 更多>