找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3882|回复: 0
收起左侧

LPC1778的IAP编程源码

[复制链接]
ID:311811 发表于 2018-4-26 09:38 | 显示全部楼层 |阅读模式
最近在做一个LPC1778的远程烧写,应用到了IAP编程,所以分享一下。

单片机源程序如下:
  1. #include "IAP.h"

  2. /*********************************************************************************************************
  3.   宏定义
  4. *********************************************************************************************************/

  5.                                                                            
  6. #define IAP_ENTER_ADR   0x1FFF1FF1                                      /* IAP入口地址定义              */

  7. #if defined   ( __CC_ARM   )
  8. __align(4)        INT8U            GucIapTmp[1024];                                                            /* 定义4K空间,编程Flash时使用  */                          
  9. #elif defined ( __ICCARM__ )
  10. #pragma pack(push)
  11. #pragma pack(4)
  12. INT8U            GucIapTmp[1024];       
  13. #pragma pack(pop)
  14. #endif                          

  15. /*
  16. *  定义CCLK值大小,单位为KHz
  17. */
  18. #define  IAP_FCCLK            (96000)
  19. #define  IAP_ENTER_ADR        0x1FFF1FF1                                  /* IAP入口地址定义              */

  20. /*
  21. *  定义函数指针  
  22. */
  23. void (*IAP_Entry) (INT32U param_tab[], INT32U result_tab[]);

  24. INT32U  paramin[8];                                                     /* IAP入口参数缓冲区            */
  25. INT32U  paramout[8];

  26. #define     UARTBPS     9600                                            /* 串口通信波特率               */
  27. volatile    INT8U       GucRcvOver;                                                        /* 接收完成标志 1:表示完成     */
  28. volatile    INT32U      GulRcvCount;                                                                    /* 接收字节数                                        */

  29. INT32U                  *GpulFlagPoint   = (INT32U *)UserFlag;                                                /* 用户程序标志指针                                */

  30. INT32U                  *pSECTORADDL1   = (INT32U *)SECTORADDL1;                                        /* 用户程序标志指针                                */
  31. INT32U                  *pSECTORADDL2   = (INT32U *)SECTORADDL2;                                        /* 用户程序标志指针                                */
  32. INT32U                  *pSECTORADDL3   = (INT32U *)SECTORADDL3;                                        /* 用户程序标志指针                                */

  33. INT32U                  *pSECTORADDH1   = (INT32U *)SECTORADDH1;                                        /* 用户程序标志指针                                */
  34. INT32U                  *pSECTORADDH2   = (INT32U *)SECTORADDH2;                                        /* 用户程序标志指针                                */
  35. INT32U                  *pSECTORADDH3   = (INT32U *)SECTORADDH3;                                        /* 用户程序标志指针                                */

  36.                                                    /* IAP出口参数缓冲区            */

  37. /*********************************************************************************************************
  38. ** Function name:       sectorPrepare
  39. ** Descriptions:        IAP操作扇区选择,命令代码50
  40. ** input parameters:    sec1:           起始扇区
  41. **                      sec2:           终止扇区
  42. ** output parameters:   paramout[0]:    IAP操作状态码,IAP返回值     
  43. ** Returned value:      paramout[0]:    IAP操作状态码,IAP返回值                     
  44. *********************************************************************************************************/
  45. INT32U  sectorPrepare (INT8U sec1, INT8U sec2)
  46. {  
  47.     paramin[0] = IAP_Prepare;                                           /* 设置命令字                   */
  48.     paramin[1] = sec1;                                                  /* 设置参数                     */
  49.     paramin[2] = sec2;                           
  50.     (*IAP_Entry)(paramin, paramout);                                    /* 调用IAP服务程序              */
  51.    
  52.     return (paramout[0]);                                               /* 返回状态码                   */
  53. }

  54. /*********************************************************************************************************
  55. ** Function name:       ramCopy
  56. ** Descriptions:        复制RAM的数据到FLASH,命令代码51
  57. ** input parameters:    dst:            目标地址,即FLASH起始地址。以512字节为分界
  58. **                      src:            源地址,即RAM地址。地址必须字对齐
  59. **                      no:             复制字节个数,为512/1024/4096/8192
  60. ** output parameters:   paramout[0]:    IAP操作状态码,IAP返回值     
  61. ** Returned value:      paramout[0]:    IAP操作状态码,IAP返回值                     
  62. *********************************************************************************************************/
  63. INT32U  ramToFlash (INT32U dst, INT32U src, INT32U no)
  64. {  
  65.     paramin[0] = IAP_RAMTOFLASH;                                        /* 设置命令字                   */
  66.     paramin[1] = dst;                                                   /* 设置参数                     */
  67.     paramin[2] = src;
  68.     paramin[3] = no;
  69.     paramin[4] = IAP_FCCLK;
  70.     (*IAP_Entry)(paramin, paramout);                                    /* 调用IAP服务程序              */
  71.    
  72.     return (paramout[0]);                                               /* 返回状态码                   */
  73. }

  74. /*********************************************************************************************************
  75. ** Function name:       sectorErase
  76. ** Descriptions:        扇区擦除,命令代码52
  77. ** input parameters:    sec1            起始扇区
  78. **                      sec2            终止扇区92
  79. ** output parameters:   paramout[0]:    IAP操作状态码,IAP返回值
  80. ** Returned value:      paramout[0]:    IAP操作状态码,IAP返回值                     
  81. *********************************************************************************************************/
  82. INT32U  sectorErase (INT8U sec1, INT8U sec2)
  83. {  
  84.     paramin[0] = IAP_ERASESECTOR;                                       /* 设置命令字                   */
  85.     paramin[1] = sec1;                                                  /* 设置参数                     */
  86.     paramin[2] = sec2;
  87.     paramin[3] = IAP_FCCLK;
  88.     (*IAP_Entry)(paramin, paramout);                                    /* 调用IAP服务程序              */
  89.    
  90.     return (paramout[0]);                                               /* 返回状态码                   */
  91. }

  92. /*********************************************************************************************************
  93. ** Function name:       blankChk
  94. ** Descriptions:        扇区查空,命令代码53
  95. ** input parameters:    sec1:           起始扇区
  96. **                      sec2:           终止扇区92
  97. ** output parameters:   paramout[0]:    IAP操作状态码,IAP返回值
  98. ** Returned value:      paramout[0]:    IAP操作状态码,IAP返回值                     
  99. *********************************************************************************************************/
  100. INT32U  blankChk (INT8U sec1, INT8U sec2)
  101. {  
  102.     paramin[0] = IAP_BLANKCHK;                                          /* 设置命令字                   */
  103.     paramin[1] = sec1;                                                  /* 设置参数                     */
  104.     paramin[2] = sec2;
  105.     (*IAP_Entry)(paramin, paramout);                                    /* 调用IAP服务程序              */

  106.     return (paramout[0]);                                               /* 返回状态码                   */
  107. }

  108. /*********************************************************************************************************
  109. ** Function name:       parIdRead
  110. ** Descriptions:        扇区查空,命令代码54
  111. ** input parameters:    无
  112. ** output parameters:   paramout[0]:    IAP操作状态码,IAP返回值
  113. ** Returned value:      paramout[0]:    IAP操作状态码,IAP返回值                     
  114. *********************************************************************************************************/
  115. INT32U  parIdRead (void)
  116. {  
  117.     paramin[0] = IAP_READPARTID;                                        /* 设置命令字                   */
  118.     (*IAP_Entry)(paramin, paramout);                                    /* 调用IAP服务程序              */

  119.     return (paramout[0]);                                               /* 返回状态码                   */
  120. }

  121. /*********************************************************************************************************
  122. ** Function name:       codeIdBoot
  123. ** Descriptions:        扇区查空,命令代码55
  124. ** input parameters:    无
  125. ** output parameters:   paramout[0]:    IAP操作状态码,IAP返回值
  126. ** Returned value:      paramout[0]:    IAP操作状态码,IAP返回值                     
  127. *********************************************************************************************************/
  128. INT32U  codeIdBoot (void)
  129. {  
  130.     paramin[0] = IAP_BOOTCODEID;                                        /* 设置命令字                   */
  131.     (*IAP_Entry)(paramin, paramout);                                    /* 调用IAP服务程序              */

  132.     return (paramout[0]);                                               /* 返回状态码                   */
  133. }

  134. /*********************************************************************************************************
  135. ** Function name:       dataCompare
  136. ** Descriptions:        校验数据,命令代码56
  137. ** input parameters:    dst:            目标地址,即RAM/FLASH起始地址。地址必须字对齐
  138. **                      src:            源地址,即FLASH/RAM地址。地址必须字对齐
  139. **                      no:             复制字节个数,必须能被4整除
  140. ** output parameters:   paramout[0]:    IAP操作状态码,IAP返回值
  141. ** Returned value:      paramout[0]:    IAP操作状态码,IAP返回值                     
  142. *********************************************************************************************************/
  143. INT32U  dataCompare (INT32U dst, INT32U src, INT32U no)
  144. {  
  145.     paramin[0] = IAP_COMPARE;                                           /* 设置命令字                   */
  146.     paramin[1] = dst;                                                   /* 设置参数                     */
  147.     paramin[2] = src;
  148.     paramin[3] = no;
  149.     (*IAP_Entry)(paramin, paramout);                                    /* 调用IAP服务程序              */

  150.     return (paramout[0]);                                               /* 返回状态码                   */
  151. }
  152. /*********************************************************************************************************
  153. ** Function name:            u16CRC_Calc16
  154. ** Descriptions:            crc16
  155. ** input parameters:    无
  156. ** output parameters:   无
  157. ** Returned value:      无
  158. *********************************************************************************************************/
  159. uint16_t u16CRC_Calc16(const uint8_t *pu8Data, int32_t i32Len)
  160. {
  161.         uint8_t i;
  162.         uint16_t u16CRC = 0;

  163.     while(--i32Len >= 0)
  164.     {
  165.             i = 8;
  166.             u16CRC = u16CRC ^ (((uint16_t)*pu8Data++) << 8);

  167.             do
  168.         {
  169.                     if (u16CRC & 0x8000)
  170.                     {
  171.                             u16CRC = u16CRC << 1 ^ 0x1021;
  172.                     }
  173.                     else
  174.                     {
  175.                             u16CRC = u16CRC << 1;
  176.                     }
  177.         }
  178.             while(--i);
  179.     }
  180.     return u16CRC;
  181. }
  182. /*********************************************************************************************************
  183. ** Function name:            PrepareUpdate
  184. ** Descriptions:            
  185. ** input parameters:    无
  186. ** output parameters:   无
  187. ** Returned value:      无
  188. *********************************************************************************************************/
  189. void PrepareUpdate (void )
  190. {
  191. #if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */
  192.     OS_CPU_SR  cpu_sr;
  193. #endif     
  194.         IAP_Entry = (void(*)())IAP_ENTER_ADR;
  195.         if (*GpulFlagPoint==LOWADD)                                                                                          /* 当前程序运行在LOW区,需要     */
  196.         {                                                                                      /* 对HIGH区进行升级                             */
  197.                 OS_ENTER_CRITICAL();
  198.                 sectorPrepare(SECTORSNH1, SECTORSNH3);                                    /* 选择HIGH扇区                                         */
  199.                 sectorErase(SECTORSNH1, SECTORSNH3);                                    /* 擦除HIGH扇区                   */                                          
  200.                 OS_EXIT_CRITICAL();                                
  201.         }                                                                                                                                                 /* 当前程序运行在HIGH区或者固    */
  202.         else{                                                                                                                         /* 件区,需要对LOW区进行升级     */                                                        
  203.                 OS_ENTER_CRITICAL();
  204.                 sectorPrepare(SECTORSNL1, SECTORSNL3);                                    /* 选择LOW扇区                                         */
  205.                 sectorErase(SECTORSNL1, SECTORSNL3);                                      /* 擦除LOW扇区                                         */
  206.                 OS_EXIT_CRITICAL();
  207.         }       
  208. }
  209. /*********************************************************************************************************
  210. ** Function name:            userFlagUpdate
  211. ** Descriptions:            更新用户程序标志区
  212. ** input parameters:    无
  213. ** output parameters:   无
  214. ** Returned value:      无
  215. *********************************************************************************************************/
  216. void  userFlagUpdate (void)
  217. {
  218. #if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */
  219.     OS_CPU_SR  cpu_sr;
  220. #endif     
  221.         INT32U  *pulDataPoint;                                                                                                         /* 更新用户程序标志空间                  */

  222.         memset(GucIapTmp, 0xff, 256);                                                                                        /* 临时缓冲区清空                                */
  223.         pulDataPoint = (INT32U *)GucIapTmp;
  224.         if (*GpulFlagPoint==LOWADD){       
  225.                 *pulDataPoint=HIGHADD;
  226.         }
  227.         else{
  228.                 *pulDataPoint=LOWADD;
  229.         }       
  230.         OS_ENTER_CRITICAL();
  231.         sectorPrepare (SECTORFLAG, SECTORFLAG);                                                                        /* 扇区准备                                                */
  232.         sectorErase (SECTORFLAG, SECTORFLAG);                                                                        /* 擦除扇区                                                */
  233.         sectorPrepare (SECTORFLAG, SECTORFLAG);                                                                        /* 选择扇区                                                */
  234.         ramToFlash(UserFlag,(INT32U)GucIapTmp, 256);                                                        /* 编程FLASH                                        */
  235.         OS_EXIT_CRITICAL();
  236. }
  237. /*********************************************************************************************************
  238. ** Function name:            userDataProgram
  239. ** Descriptions:            
  240. ** input parameters:    无
  241. ** output parameters:   无
  242. ** Returned value:      无
  243. *********************************************************************************************************/
  244. void user(void)
  245. {       
  246.         defaultVectorHandle();
  247. }
  248. #define SECTORSIZE                (32*1024)                        //扇区大小
  249. /*********************************************************************************************************
  250. ** Function name:            userDataProgram
  251. ** Descriptions:            编程用户代码区
  252. ** input parameters:    无
  253. ** output parameters:   无
  254. ** Returned value:      无
  255. *********************************************************************************************************/
  256. uint8_t  userDataProgram (uint8_t *pdat)
  257. {
  258. #if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */
  259.     OS_CPU_SR  cpu_sr;
  260. #endif     
  261.         uint16_t        filedatcrc;
  262.         uint16_t fnum,fsn,flen;
  263. //        void (*userProgram)();                                                       /* 函数指针                                            */
  264.         uint16_t        NPS;
  265.        
  266. //        userProgram = (void (*)()) user;                                                /* 避免编译警告                                        */
  267.         fnum = *pdat + *(pdat+1)*256;
  268.         fsn = *(pdat+2) + *(pdat+3)*256;
  269.         flen = *(pdat+4) + *(pdat+5)*256;               
  270.         if(fnum==0 && fsn==0 && flen==0){
  271.                 //ANDYDEBUG        20150805               
  272.                 sPTL_104_I_SND.Rson=0x0007;               
  273.                 //ANDYDEBUG        20150805       
  274.                
  275.                 PrepareUpdate();                       
  276.                 SysUpdateFsnBak = fsn;
  277.                 SysUpdateFlag = 1;                                                                         // 启动升级
  278.                 if (*GpulFlagPoint==LOWADD)
  279.                         return UPHI;
  280.                 else
  281.                         return UPLO;               
  282.         }
  283.         //ANDYDEBUG        20150805               
  284.         sPTL_104_I_SND.Rson=0x000A;               
  285.         //ANDYDEBUG        20150805       

  286.         if(SysUpdateFlag==0)                                                                         // 未启动升级
  287.                 return UPERR0;
  288.         if(fnum==fsn && flen==0 && fnum>0)        {                                        // 执行升级程序
  289.                 userFlagUpdate();                                                                        // 升级扇区标识
  290.                 zyReset(ZY_HARD_RESET);       
  291.                 return UPOK;
  292.         }
  293.         if(fnum==0 || fsn ==0 || fsn>fnum)                                                 // 序号排错
  294.                 return UPERR1;       

  295. #ifndef TP1C        
  296.         if (flen != 256 && flen != 512 && flen != 1024 )                   // 帧长归整
  297.         {         // 满足编程字节数的要求,256、512、1024等
  298.                 if (flen < 256)
  299.                         flen = 256;                                       
  300.                 else if (flen < 512)
  301.                         flen = 512;
  302.                 else if (flen < 1024)
  303.                         flen = 1024;
  304.                 else
  305.                         return UPERR3;       
  306.         }
  307.         filedatcrc = u16CRC_Calc16(pdat+6,flen);                                  // CRC16校验
  308.         if(filedatcrc != (*(pdat+6+flen) + *(pdat+7+flen)*256))
  309.                 return UPERRcrc;
  310.         if(fsn!=SysUpdateFsnBak+1)                                                                // 帧顺序校验
  311.                 return UPERR2;
  312.         SysUpdateFsnBak=fsn;
  313.     NPS= SECTORSIZE/flen;                                                                        // 单个扇区帧容量
  314.         memcpy(GucIapTmp,pdat+6,flen);                                                         // 写升级数据入缓存
  315. #else
  316.         if(flen != 128 && flen != 256 && flen != 512 && flen != 1024 )          
  317.         {         // 满足编程字节数的要求,256、512、1024等                           // 帧长归整
  318.                 if (flen < 128)
  319.                         flen = 128;
  320.                 else if (flen < 256)
  321.                         flen = 256;                                       
  322.                 else if (flen < 512)
  323.                         flen = 512;
  324.                 else if (flen < 1024)
  325.                         flen = 1024;
  326.                 else
  327.                         return UPERR3;       
  328.         }
  329.         filedatcrc = u16CRC_Calc16(pdat+6,flen);                                  // CRC16校验
  330.         if(filedatcrc != (*(pdat+6+flen) + *(pdat+7+flen)*256))
  331.                 return UPERRcrc;
  332.         if(fsn!=SysUpdateFsnBak+1)                                                                // 帧顺序校验
  333.                 return UPERR2;
  334.         SysUpdateFsnBak=fsn;
  335.         NPS= SECTORSIZE/flen;                                                                        // 单个扇区帧容量
  336.     if(flen==128){
  337.                 if(fsn%2){
  338.                         if(fsn<fnum){
  339.                                 memcpy(GucIapTmp,pdat+6,flen);                                 // 写升级数据入缓存
  340.                                 return UPOK;
  341.                         }
  342.                         else {
  343.                                 memcpy(GucIapTmp,pdat+6,flen);                                 // 写升级数据入缓存
  344.                                 memset(GucIapTmp+128,0xff,flen);                         // 结束帧补齐256字节
  345.                                 NPS/=2;
  346.                                 fsn/=2;
  347.                                 fsn++;
  348.                                 flen*=2;
  349.                         }
  350.                 }
  351.                 else {                       
  352.                         memcpy(GucIapTmp+128,pdat+6,flen);                                 // 写升级数据入缓存
  353.                         NPS/=2;
  354.                         fsn/=2;
  355.                         flen*=2;
  356.                 }       
  357.         }
  358.         else
  359.                 memcpy(GucIapTmp,pdat+6,flen);                                                 // 写升级数据入缓存
  360. #endif

  361.         if (*GpulFlagPoint==LOWADD)                                                             /* 当前程序运行在LOW区,需要   */
  362.         {                                                                            /* 对HIGH区进行升级              */
  363.     OS_ENTER_CRITICAL();
  364.                 if(fsn>0 && fsn<=NPS){
  365.                         sectorPrepare(SECTORSNH1, SECTORSNH1);                                                                        /* 准备HIGH扇区                              */
  366.                         ramToFlash(SECTORADDH1 + (fsn-1)*flen,(INT32U)GucIapTmp, flen);                        /* 写数据到FLASH                         */
  367.                         if(CMD_SUCCESS != dataCompare((INT32U)GucIapTmp,SECTORADDH1+(fsn-1)*flen,flen))
  368.                                 return UPERRwrt;
  369.                 }                                                                                                                                                               
  370.                 if(fsn>NPS && fsn<=NPS*2){
  371.                         sectorPrepare(SECTORSNH2, SECTORSNH2);
  372.                         ramToFlash(SECTORADDH2 + (fsn-NPS-1)*flen,(INT32U)GucIapTmp, flen);
  373.                         if(CMD_SUCCESS != dataCompare((INT32U)GucIapTmp,SECTORADDH2+(fsn-NPS-1)*flen,flen))
  374.                                 return UPERRwrt;
  375.                 }                                                                          
  376.                 if(fsn>NPS*2 && fsn<=NPS*3){
  377.                         sectorPrepare(SECTORSNH3, SECTORSNH3);
  378.                         ramToFlash(SECTORADDH3 + (fsn-NPS*2-1)*flen,(INT32U)GucIapTmp, flen);
  379.                         if(CMD_SUCCESS != dataCompare((INT32U)GucIapTmp,SECTORADDH3+(fsn-NPS*2-1)*flen, flen))
  380.                                 return UPERRwrt;
  381.                 }                                                      
  382.     OS_EXIT_CRITICAL();
  383.         }
  384.         else                                                                                                           /* 当前程序运行在HIGH区,需要    */
  385.         {                                                                    /* 对LOW区进行升级             */         
  386.     OS_ENTER_CRITICAL();
  387.                 if(fsn>0 && fsn<=NPS){
  388.                         sectorPrepare(SECTORSNL1, SECTORSNL1);                                                                        /* 准备LOW扇区                              */
  389.                         ramToFlash(SECTORADDL1 + (fsn-1)*flen,(INT32U)GucIapTmp, flen);                        /* 写数据到FLASH                         */
  390.                         if(CMD_SUCCESS != dataCompare((INT32U)GucIapTmp,SECTORADDL1+(fsn-1)*flen,flen))
  391.                                 return UPERRwrt;
  392.                 }                                                                                                                       
  393.                 if(fsn>NPS && fsn<=NPS*2){
  394.                         sectorPrepare(SECTORSNL2, SECTORSNL2);
  395.                         ramToFlash(SECTORADDL2 + (fsn-NPS-1) * flen,(INT32U)GucIapTmp, flen);
  396.                         if(CMD_SUCCESS != dataCompare((INT32U)GucIapTmp,SECTORADDL2+(fsn-NPS-1)*flen,flen))
  397.                                 return UPERRwrt;
  398.                 }                                                                          
  399.                 if(fsn>NPS*2 && fsn<=NPS*3){
  400.                         sectorPrepare(SECTORSNL3, SECTORSNL3);
  401.                         ramToFlash(SECTORADDL3 + (fsn-NPS*2-1)*flen,(INT32U)GucIapTmp, flen);
  402.                         if(CMD_SUCCESS != dataCompare((INT32U)GucIapTmp,SECTORADDL3+(fsn-NPS*2-1)*flen,flen))
  403.                                 return UPERRwrt;
  404.                 }                                                                                                             
  405.     OS_EXIT_CRITICAL();
  406.         }
  407.         return UPOK;
  408. }


  409. /*********************************************************************************************************
  410. ** Function name:           zyReset
  411. ** Descriptions:            系统复位
  412. ** input parameters:        uiMode: ZY_POWER_RESET: 上电复位
  413. **                                  ZY_HARD_RESET:  硬件复位
  414. **                                  ZY_SOFT_RESET:  软件复位
  415. **                                  其它:           与系统相关
  416. ** output parameters:       none
  417. ** Returned value:          none
  418. ** Created by:              Chenmingji
  419. ** Created Date:            2009-07-23
  420. **--------------------------------------------------------------------------------------------------------
  421. ** Modified by:
  422. ** Modified date:
  423. *********************************************************************************************************/
  424. void zyReset (unsigned int uiMode)
  425. {
  426.     switch (uiMode) {

  427.     case ZY_POWER_RESET:                                                /*  此系统上电复位等同硬件复位   */

  428. #if 0
  429.         break;
  430. #endif                                                                  /*  0                           */

  431.     case ZY_HARD_RESET:
  432.         //changeToSYSMode();
  433.         //AITCR = (0x05fa << 16) + 4;
  434.                 wdt_entry();
  435.         break;

  436.     case ZY_SOFT_RESET:
  437.         //changeToSYSMode();
  438.         //AITCR = (0x05fa << 16) + 1;
  439.                 wdt_entry();
  440.         break;
  441.    
  442.     default:                                                            /*  参数不正确不复位            */
  443.         break;
  444.     }
  445. }

  446. /*********************************************************************************************************
  447. ** Function name:           defaultVectorHandle
  448. ** Descriptions:            ????????
  449. ** input parameters:        none
  450. ** output parameters:       none
  451. ** Returned value:          none
  452. *********************************************************************************************************/
  453. void defaultVectorHandle (void)
  454. {
  455. #ifdef DEBUG
  456.     while (1);
  457. #else
  458.     zyReset(ZY_HARD_RESET);
  459. #endif                                                                  /*  DEBUG                       */
  460. }


  461. /*********************************************************************************************************
  462.   End Of File
  463. *********************************************************************************************************/

复制代码

所有资料51hei提供下载:
LPC1778 IAP烧写源码.docx (23.1 KB, 下载次数: 19)
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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