找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 238|回复: 0
打印 上一主题 下一主题
收起左侧

ABOV A94B114芯片EEPROM相关求助

[复制链接]
跳转到指定楼层
楼主
ID:1091450 发表于 2023-10-19 18:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
如题,本人在使用ABOV A94B114芯片进行开发时,在掉电记忆的处理部分遇到了难题,希望有大佬能帮忙看看.大家讨论讨论交流一下思路也好eeprom.c文件内容如下
  1. uint8  xdata SaveData[MAX_TAB_ADDRES];
  2. uint8  xdata NAME_SAVE_FG;

  3. uint8  xdata TestrAM1;
  4. uint8  xdata TestrAM2;
  5. unsigned int User_ID;

  6. unsigned char *PageBufData;
  7. unsigned int   PageBufDataSize;

  8. volatile unsigned char data code_buf[20] _at_ 0x30;   
  9. volatile unsigned char data g_FEMR, g_FECR, g_WDTMR;
  10. volatile unsigned char g_IE, g_IE1, g_IE2;

  11. extern void Flash_Enter(void);

  12. void Init_Flash()
  13. {
  14.    
  15.     User_ID = 0;
  16.     // Set Flash Sector Address as Dummy address
  17.     FEARH = (FLASH_ADDR_DUMMY >> 16) & 0x0f;    //Flash Sector Address High Register
  18.     FEARM = (FLASH_ADDR_DUMMY >> 8) & 0xff; //Flash Sector Address Middle Register
  19.     FEARL = (FLASH_ADDR_DUMMY >> 0) & 0xff; //Flash Sector Address Low Register

  20. }
  21. void Flash_Enter(void)
  22. {
  23.     g_IE = IE;
  24.     g_IE1 = IE1;
  25.     g_IE2 = IE2;
  26.     IE = 0;
  27.     IE1 = 0;
  28.     IE2 = 0;
  29.    
  30.     g_WDTMR = WDTMR;    // Backup WDTMR
  31.     WDTMR   = 0;        // Watch Dog Timer Stop.
  32.     g_WDTMR |= 0x04;    // Clear WDT Counter
  33.    
  34.     // To access Flash Control register, ENTRY_0~2 should be set 0xAA, 0x55, 0xA5.
  35.     *(unsigned char xdata *)0x10D8 = 0xAA;
  36.     *(unsigned char xdata *)0x10DA = 0x55;
  37.     *(unsigned char xdata *)0x10DD = 0xA5;
  38.    
  39.     // Set Flash Sector Address as Dummy address
  40.     FEARH = (FLASH_ADDR_DUMMY >> 16) & 0x0f;    //Flash Sector Address High Register
  41.     FEARM = (FLASH_ADDR_DUMMY >> 8) & 0xff; //Flash Sector Address Middle Register
  42.     FEARL = (FLASH_ADDR_DUMMY >> 0) & 0xff; //Flash Sector Address Low Register
  43.    
  44. }

  45. void Flash_Exit(void)
  46. {
  47.     FECR = 0x33; //FLASH_MODE_EXIT
  48.     // After to change Flash Control register, ENTRY_0~2 should be set 0x00.
  49.     *(unsigned char xdata *)0x10D8 = 0x00;
  50.     *(unsigned char xdata *)0x10DA = 0x00;
  51.     *(unsigned char xdata *)0x10DD = 0x00;

  52.         // Flash code buffer ram clear.
  53. #pragma asm
  54.     mov     r0, #code_buf
  55.     mov     r2, #20
  56.     clr     a
  57. loop0:
  58.     mov     @r0, a
  59.     inc     r0
  60.     djnz    r2, loop0
  61. #pragma endasm

  62.     WDTMR   = g_WDTMR;  // Restore WDTMR

  63.     /* restore IE setting */
  64.     IE = g_IE;
  65.     IE1 = g_IE1;
  66.     IE2 = g_IE2;
  67. }

  68. volatile void write_page_buffer_src()      
  69. {
  70.     FEMR = 0x89;//
  71.             //FLASH_SEL             // FSEL (Select Flash memory)
  72.             //| FLASH_PBUFF_SEL // PBUFF (Select page buffer)
  73.             //| FLASH_CON_ENABLE;   // FEEN (Enable program & erase)

  74. #pragma asm

  75.     mov     r0,#32
  76.     mov     dptr,#0x10E0    ; page buffer address
  77.     write_page_buffer_src_loop:
  78.     mov     a, @r1              ;r1=addr of rxdata
  79.     movx    @dptr,a
  80.     inc     r1
  81.     inc     dptr        
  82.     djnz    r0,write_page_buffer_src_loop
  83. #pragma endasm

  84.     FEMR = 0;
  85. }

  86. void write_page_buffer(unsigned char *dt)   // dt -> r3, r2, r1
  87. {
  88.     uint8 *temp = dt;
  89.    
  90. #pragma asm
  91.     mov     dptr,#write_page_buffer_src
  92.     mov     r0,#0x30
  93.     mov     r2,#0x12
  94. write_page_buffer_loop:
  95.     clr     a
  96.     movc    a,@a+dptr
  97.     mov     @r0,a
  98.     inc     dptr
  99.     inc     r0
  100.     djnz    r2,write_page_buffer_loop
  101.             ljmp    0x8030      ; jump sram region
  102. #pragma endasm
  103. }




  104. volatile void do_flash_at_sram_src()        
  105. {
  106.     #pragma asm
  107.         mov FEMR,g_FEMR             // 3 byte
  108.         mov FECR,g_FECR             // 3 byte
  109.     _flash_busy_wait:
  110.         mov A,FESR                  // 2 byte
  111.         JNB ACC.7,_flash_busy_wait  // 3 byte
  112.         clr A                       // 1 byte
  113.         mov FEMR,A                  // 2 byte
  114.     #pragma endasm
  115. }   // RET                           // 1byte


  116. void do_flash_at_sram()
  117. {
  118.     #pragma asm
  119.         mov     dptr,#do_flash_at_sram_src
  120.         mov     r0,#0x30
  121.         mov     r1,#0x0F
  122.     do_flash_at_sram_loop:
  123.         clr     a
  124.         movc    a,@a+dptr
  125.         mov     @r0,a
  126.         inc     dptr
  127.         inc     r0
  128.         djnz    r1,do_flash_at_sram_loop
  129.         ljmp    0x8030
  130.     #pragma endasm
  131. }





  132. void Update_Flash_Buf(unsigned char *buf, unsigned int buf_size)
  133. {
  134.     //Flash Buffer Update
  135.     User_ID = FLASH_USER_ID;
  136.     PageBufData = buf;
  137.     PageBufDataSize = buf_size;
  138. }



  139. void Update_Flash(unsigned int key)
  140. {
  141.     unsigned char i = 0;
  142.     unsigned int s = 0;
  143.     unsigned long addr;
  144.     unsigned char ret = 0;

  145.     if(key == FLASH_KEY)
  146.     {
  147.         if(User_ID == FLASH_USER_ID)
  148.         {      
  149.             addr = FLASH_ADDR_USER;
  150.             s = PageBufDataSize;
  151.             while(PageBufDataSize > 0)
  152.             {
  153.                 if(PageBufDataSize < PAGE_BUFFER_SIZE)
  154.                 {
  155.                     s = PageBufDataSize;
  156.                     PageBufDataSize = 0;
  157.                 }
  158.                 else
  159.                 {
  160.                     s = PAGE_BUFFER_SIZE;
  161.                     PageBufDataSize -= PAGE_BUFFER_SIZE;
  162.                 }
  163.                  ret = Erase_Flash(FLASH_KEY, FLASH_ADDR_USER + (PAGE_BUFFER_SIZE*i));
  164.                 if(ret == 1 || ret == 2)
  165.                 {
  166.                     //error;
  167.                     while(1);
  168.                 }
  169.                 ret = Write_Flash(FLASH_KEY, FLASH_ADDR_USER + (PAGE_BUFFER_SIZE*i),
  170.                             s, PageBufData + (PAGE_BUFFER_SIZE*i));
  171.                 if(ret == 1 || ret == 4)
  172.                 {
  173.                      //error;
  174.                      while(1);

  175.                 }
  176.                 i++;
  177.             }
  178.         }
  179.         User_ID = 0;
  180.     }
  181. }



  182. unsigned char Erase_Flash(unsigned int key, unsigned long sector_address)
  183. {
  184.     unsigned char code *rom_addr = 0x0000;
  185.     unsigned char i = 0;
  186.     unsigned char tmp = 0;
  187.     unsigned char tmp2 = 0;
  188.     unsigned char ret = 0;

  189.     //Disable EA
  190.     tmp = IE;
  191.     IE &= (~0x80);

  192.    
  193.     //LVR enable, safety code
  194.     tmp2 = LVIR;
  195.     LVIR &= ~(1<<7); //LVR enable  

  196.     if(key == FLASH_KEY)
  197.     {
  198.         key ^= FLASH_XOR;

  199.         if(sector_address < (unsigned long)FLASH_SIZE)
  200.         {
  201.             
  202.             // Flash Flash Control Register CLR change before initialization.
  203.             FECR    = 0;
  204.             FETCR   = 0;
  205.             FEMR    = 0;
  206.             // Enable program mode
  207.             Flash_Enter();
  208.             
  209.             FETCR = WAITTIME;               // 0x9D = 157 : (157+1) * 2 (31.25ns * 256) = 2.528ms
  210.             FECR = 0x02; // Reset page buffer.
  211.             _nop_( );   //Dummy instruction, This instruction must be needed.
  212.             _nop_( );   //Dummy instruction, This instruction must be needed.
  213.             _nop_( );   //Dummy instruction, This instruction must be needed.
  214.             
  215.             g_FEMR = 0x91;   // Set Erase mode.
  216.             g_FECR =    0x0B; // Start Erase.
  217.    
  218.             // Set Flash Sector Address as used area
  219.             FEARH = (sector_address >> 16) & 0xFF;
  220.             FEARM = (sector_address >> 8) & 0xFF;
  221.             FEARL = (sector_address) & 0xFF;
  222.             

  223.             //Check Power stable by LVR Enable
  224.             //if LVR disable, return error 2
  225.             if((LVIR & 0x80) == 0x00)
  226.             {
  227.                 // Check User_ID
  228.                 if(User_ID == FLASH_USER_ID)
  229.                 {
  230.                     // Check valid of Flash Sector Address range
  231.                     if( (unsigned long)FLASH_ADDR_MIN <= sector_address && sector_address <= (unsigned long)FLASH_ADDR_MAX)
  232.                     {
  233.                         if((key ^ FLASH_XOR) == FLASH_KEY)
  234.                         {
  235.                             // Flase Erase at ram
  236.                                 do_flash_at_sram();
  237.                         }
  238.                         
  239.                         Flash_Exit();                       // Set flash to normal mode.
  240.                         //verify data
  241.                         for(i = 0; i < PAGE_BUFFER_SIZE; i++)
  242.                         {
  243.                             if(rom_addr[sector_address + i] != 0x00)
  244.                             {
  245.                                 ret = 2;
  246.                             }
  247.                         }
  248.                     }
  249.                 }
  250.                
  251.             }
  252.             else
  253.             {
  254.                 ret = 1;//LVI error
  255.                
  256.                 Flash_Exit();
  257.             }
  258.             // Set Flash Sector Address as Dummy address
  259.             FEARH = (FLASH_ADDR_DUMMY >> 16) & 0x0f;    //Flash Sector Address High Register
  260.             FEARM = (FLASH_ADDR_DUMMY >> 8) & 0xff;     //Flash Sector Address Middle Register
  261.             FEARL = (FLASH_ADDR_DUMMY >> 0) & 0xff;     //Flash Sector Address Low Register
  262.         }
  263.     }
  264.     LVIR = tmp2;
  265.     IE = tmp;
  266.     return ret;
  267. }




  268. unsigned char Write_Flash(unsigned int key, unsigned long sector_address, unsigned int buf_size, unsigned char *buf)
  269. {
  270.     unsigned char *pdt;
  271.     unsigned char code *rom_addr=0x0000;
  272.     unsigned char i = 0;
  273.     unsigned char tmp = 0;
  274.     unsigned char tmp2 = 0;
  275.     unsigned char ret = 0;

  276.     //Disable EA
  277.     tmp = IE;
  278.     IE &= (~0x80);
  279.    
  280.     //LVR enable, safety code
  281.     tmp2 = LVIR;
  282.     LVIR &= ~(1<<7); //LVR enable
  283.    
  284.     if(key == FLASH_KEY)
  285.     {
  286.         key ^= FLASH_XOR;

  287.         if(sector_address < (unsigned long)FLASH_SIZE)
  288.         {
  289.             // Enable program mode
  290.             Flash_Enter();
  291.             
  292.             FETCR = WAITTIME;               // 0x9D = 157 : (157+1) * 2 (31.25ns * 256) = 2.528ms

  293.             FEMR = 0x81;    // Select flash and enable control.
  294.             FECR = 0x02 ; // (Reset page buffer)
  295.             _nop_( );   //Dummy instruction, This instruction must be needed.
  296.             _nop_( );   //Dummy instruction, This instruction must be needed.
  297.             _nop_( );   //Dummy instruction, This instruction must be needed.
  298.             
  299.             
  300.             
  301.             
  302.             // Set Flash Sector Address as used area
  303.             FEARH = (sector_address >> 16) & 0xFF;
  304.             FEARM = (sector_address >> 8) & 0xFF;
  305.             FEARL = (sector_address) & 0xFF;

  306.             write_page_buffer(buf);
  307.             buf_size = buf_size;//not used A94B114

  308.             g_FEMR = 0xA1;    // Set write mode.
  309.             g_FECR = 0x0B;      // Start program.
  310.             
  311.             //Check Power stable by LVR Enable
  312.             //if LVR disable, return error 2
  313.             if((LVIR & 0x80) == 0x00)
  314.             {
  315.                 // Check User_ID1/2
  316.                 if(User_ID == FLASH_USER_ID)
  317.                 {
  318.                     // Check valid of Flash Sector Address range
  319.                     if( (unsigned long)FLASH_ADDR_MIN <= sector_address && sector_address <= (unsigned long)FLASH_ADDR_MAX)
  320.                     {
  321.                         if((key ^ FLASH_XOR) == FLASH_KEY)
  322.                         {
  323.                                 // Flase Write at ram
  324.                                 do_flash_at_sram();
  325.                         }

  326.                         Flash_Exit();                       // Set flash to normal mode.
  327.                         //verify data
  328.                         pdt = buf;
  329.                         for(i = 0; i < PAGE_BUFFER_SIZE; i++)
  330.                         {
  331.                             sector_address_tmp = sector_address;
  332.                             if(rom_addr[sector_address + i] != *pdt)
  333.                             {
  334.                                 ret = 4;
  335.                             }
  336.                            
  337.                             pdt++;
  338.                         }
  339.                     }
  340.                 }

  341.             }
  342.             else
  343.             {
  344.                 ret = 1;//LVI error
  345.                
  346.                 Flash_Exit();
  347.             }
  348.             // Set Flash Sector Address as Dummy address
  349.             FEARH = (FLASH_ADDR_DUMMY >> 16) & 0x0f;    //Flash Sector Address High Register
  350.             FEARM = (FLASH_ADDR_DUMMY >> 8) & 0xff;     //Flash Sector Address Middle Register
  351.             FEARL = (FLASH_ADDR_DUMMY >> 0) & 0xff;     //Flash Sector Address Low Register
  352.         }
  353.     }
  354.     LVIR = tmp2;
  355.     IE = tmp;
  356.     return ret;
  357. }

  358. void Read_Flash(unsigned long sector_address, unsigned int buf_size, unsigned char *buf)
  359. {
  360.     unsigned char code *rom_addr=0x0000;
  361.     unsigned int i = 0;

  362.     for(i = 0; i < buf_size; i++)
  363.     {
  364.         buf[i] = rom_addr[sector_address + i];
  365.     }
  366. }

  367. void WriteEEprom(void)
  368. {

  369.     if (NAME_SAVE_FG == WRIT_COMMAND_CODE)
  370.     {
  371.         Init_Flash();

  372.         SaveData[1] = TestrAM1;
  373.         SaveData[2] = TestrAM2;
  374.         SaveData[3] = TempMOde;

  375.         SaveData[TEST_C1_ADDRES] = TEST_NAME_C1;
  376.         SaveData[TEST_C2_ADDRES] = TEST_NAME_C2;
  377.         
  378.         Update_Flash_Buf(SaveData, PAGE_BUFFER_SIZE);
  379.         Update_Flash(FLASH_KEY);

  380.         NAME_SAVE_FG = 0;
  381.     }
  382. }

  383. void RestPara(void)
  384. {

  385.     SaveData[1] = 0X90;
  386.     SaveData[2] = 0XA7;
  387.     SaveData[3] = TempMOde = 0;

  388.     SaveData[TEST_C1_ADDRES] = TEST_NAME_C1;
  389.     SaveData[TEST_C2_ADDRES] = TEST_NAME_C2;

  390.     Init_Flash();
  391.     Update_Flash_Buf(SaveData, PAGE_BUFFER_SIZE);
  392.     Update_Flash(FLASH_KEY);
  393. }

  394. void ReadEE(void)
  395. {

  396.     Read_Flash(FLASH_ADDR_USER, PAGE_BUFFER_SIZE, SaveData);

  397.     if ((SaveData[TEST_C1_ADDRES] == TEST_NAME_C1) && (SaveData[TEST_C2_ADDRES] == TEST_NAME_C2))
  398.     {
  399.         TestrAM1 = SaveData[1];
  400.         TestrAM2 = SaveData[2];
  401.         TempMOde = SaveData[3];
  402.     }
  403.     else
  404.     {
  405.         RestPara();
  406.     }
  407.    
  408. }
复制代码


在eeprom.c文件当中,除了最后的WriteEEprom,RestPara,ReadEE,其余的部分都是从A94B114官方提供的flash.c例程中copy过来的, 以下是eeprom.h文件内容
  1. #ifndef _EEPROM_H
  2. #define _EEPROM_H

  3. extern uint8 xdata NAME_SAVE_FG;
  4. #define WRIT_COMMAND_CODE 0X12


  5. #define TEST_NAME_C2 0XA4
  6. #define TEST_NAME_C1 0xB4

  7. #define TEST_C1_ADDRES 0
  8. #define TEST_C2_ADDRES 12

  9. #define MAX_TAB_ADDRES   32

  10. //Device Dependent=======================================
  11. #define FLASH_SIZE (0x001FFF)
  12. #define PAGE_BUFFER_SIZE (0x20)

  13. //Modify to use==========================================
  14. //Flash Address for used
  15. #define FLASH_ADDR_USER 0x001f80

  16. //Flash Address Min/Max value for permitted area
  17. #define FLASH_ADDR_MIN 0x001f80
  18. #define FLASH_ADDR_MAX 0x001fff

  19. //more than 2.0V @ IRC 16MHz
  20. #define FLASH_LVI 0x01  //LVI 2.4V(2.05V~2.35V)

  21. //Flash Dummy Address value, not used area
  22. #define FLASH_ADDR_DUMMY 0x03FF00
  23. //=====================================================

  24. //safety code for operation of flash memory
  25. #define FLASH_KEY 0xAA55
  26. #define FLASH_XOR 0x9C75

  27. #define WAITTIME 0x9D   // 2.5ms

  28. //Flash Mode Control value
  29. #define FLASH_PAGEBUFFER_RESET 0x01

  30. //Flash User ID value, used password
  31. #define FLASH_USER_ID 0xCC33

  32. extern void Init_Flash();
  33. extern void Update_Flash_Buf(unsigned char *buf, unsigned int size);
  34. extern void Update_Flash(unsigned int key);
  35. extern unsigned char Erase_Flash(unsigned int key, unsigned long sector_address);
  36. extern unsigned char Write_Flash(unsigned int key, unsigned long sector_address, unsigned int size, unsigned char *buf);
  37. extern void Read_Flash(unsigned long sector_address, unsigned int size, unsigned char *buf);

  38. extern void ReadEE(void);
  39. extern void WriteEEprom(void);

  40. #endif
复制代码

在调试过程中发现,每次都是在Write_Flash()函数中,似乎是数据验证出错,导致ret = 4,然后在Update_Flash()中while(1)死循环触发复位, 希望大家能帮忙看看,谢谢!
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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