我们从2011年坚守至今,只想做存粹的技术论坛。  由于网站在外面,点击附件后要很长世间才弹出下载,请耐心等待,勿重复点击不要用Edge和IE浏览器下载,否则提示不安全下载不了

 找回密码
 立即注册
搜索
查看: 585|回复: 1

STC_IAP_ISP监控程序

[复制链接]

该用户从未签到

19

主题

61

回帖

124

积分

二级逆天

积分
124

终身成就奖

发表于 2020-12-1 10:26:53 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区

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

×
  1. STC_IAP_ISP监控程序
  2. #define MAIN_Fosc        22118400L    //定义主时钟
  3. #define Baudrate0        115200UL    //串口0波特率600~115200
  4. #include    "STC15Fxxxx.H"
  5. #include    "ymodem.h"
  6. #define    WDT_Enable    0            //1: 允许内部看门狗,    0: 禁止
  7. #define D_BRT0_1T_8bit        (256 - MAIN_Fosc / 32 / Baudrate0)    //计算波特率    1T  8bit
  8. #define    ISP_ADDRESS        0xE400                //ISP开始地址, 高地址必须是偶数, 注意要预留ISP空间,本例程留3K
  9. #define    UserflashLenth     (ISP_ADDRESS-3)        //用户FLASH长度, 保留个字节存放用户地址程序的跳转地址
  10. /*************    本地变量声明    **************/
  11. typedef        void (*pFunction)(void);
  12. pFunction    Jump_To_Application;
  13. u16            JumpAddress;
  14. u16        FileLength;
  15. u16        Y_TimeOut,WaitTime;
  16. u8        packets_received, session_begin;
  17. u8        idata file_name[FILE_NAME_LENGTH];
  18. u8        idata file_size[FILE_SIZE_LENGTH];
  19. u8        StartCode[3];
  20. u16        FlashDestination;
  21. u16        RxCnt;
  22. u8        HandCnt;
  23. u8    xdata    RxBuff[1024];
  24. u8    idata    RxBuff_10[10];
  25. u32        DownCheckSum,FlashCheckSum;
  26. /*************    本地函数声明    **************/
  27. u8        Hex2Ascii(u8 dat);
  28. u8        UART_Download(void);
  29. u16        Str2Int(u8 *inputstr);
  30. void    ISP_WriteByte(u16 addr, u8 dat);
  31. void    ISP_EraseSector(u16 addr);
  32. u8    ISP_ReadByte(u16 addr);
  33. //========================================================================
  34. // 函数: void    TX1_write2buff(u8 dat)
  35. // 描述: 串口发送一个字节.
  36. // 参数: dat: 要发送的字节.
  37. // 返回: none.
  38. // 版本: V1.0, 2013-4-29
  39. //========================================================================
  40. void    TX1_write2buff(u8 dat)
  41. {
  42.     TI = 0;
  43.     SBUF = dat;
  44.     while(!TI);
  45. }
  46. //========================================================================
  47. // 函数: void    PrintString1(u8 *p)
  48. // 描述: 串口发送一个字符串.
  49. // 参数: *p: 要发送的字符串指针.
  50. // 返回: none.
  51. // 版本: V1.0, 2013-4-29
  52. //========================================================================
  53. void    PrintString1(u8 *p)
  54. {
  55.     for(; *p > 0; p++)    TX1_write2buff(*p);
  56. }
  57. //========================================================================
  58. // 函数: void    Tx_DEC_U16(u16 j)
  59. // 描述: 把一个16位整型数转成十进制送串口发送.
  60. // 参数: j: 要处理的16位整型数.
  61. // 返回: none.
  62. // 版本: V1.0, 2013-4-29
  63. //========================================================================
  64. void    Tx_DEC_U16(u16 j)
  65. {
  66.     u8    i;
  67.     u8    tmp[10];
  68.     for(i=4; i<5; i--)    tmp[i] = j % 10 + '0',    j = j / 10;
  69.     for(i=0; i<4; i++)
  70.     {
  71.         if(tmp[i] != '0')    break;
  72.         tmp[i] = ' ';
  73.     }
  74.     for(i=0; i<5; i++)    TX1_write2buff(tmp[i]);
  75. }
  76. //========================================================================
  77. // 函数: void    Tx_HEX_U32(u32 j)
  78. // 描述: 把一个32位长整型数转成十进制送串口发送.
  79. // 参数: j: 要处理的32位整型数.
  80. // 返回: none.
  81. // 版本: V1.0, 2013-4-29
  82. //========================================================================
  83. void    Tx_HEX_U32(u32 j)
  84. {
  85.     u8    i,k;
  86.     u8    tmp[10];
  87.     for(i=8; i>0; i--)
  88.     {
  89.         k = ((u8)j) & 0x0f;
  90.         if(k <= 9)    tmp[i] = k+'0';
  91.         else        tmp[i] = k-10+'A';
  92.         j >>= 4;
  93.     }
  94.     for(i=1; i<9; i++)    TX1_write2buff(tmp[i]);
  95. }
  96. //========================================================================
  97. // 函数: void    ReturnNameAndLength(void)
  98. // 描述: 返回程序的文件名和长度, 和累加校验和.
  99. // 参数: none.
  100. // 返回: none.
  101. // 版本: V1.0, 2013-4-29
  102. //========================================================================
  103. void    ReturnNameAndLength(void)
  104. {
  105.     u16    i;
  106.     PrintString1("================================\r\n File name:     ");
  107.     for(i=0; i<FILE_NAME_LENGTH; i++)   
  108.     {
  109.         if(file_name[i] == 0)    break;
  110.         TX1_write2buff(file_name[i]);
  111.     }
  112.     PrintString1("\r\n File length:   ");
  113.     Tx_DEC_U16(FileLength);
  114.     PrintString1(" Bytes\r\n DownChexkSum:  ");
  115.     Tx_HEX_U32(DownCheckSum);
  116.     PrintString1("\r\n ISP Versiom:   2013-4-30 by Coody");
  117.     PrintString1("\r\n================================\r\n\r\n");
  118. }
  119. //========================================================================
  120. // 函数: void    UART1_RxPackage(void)
  121. // 描述: 串口接收一个数据块.
  122. // 参数: none.
  123. // 返回: none.
  124. // 版本: V1.0, 2013-4-29
  125. //========================================================================
  126. void    UART1_RxPackage(void)
  127. {
  128.     u16    j;    //5ms超时
  129. //    RI = 0;
  130.     RxCnt = 0;
  131.     for(j = 0;    j < 5000; j++)    //最后收到一个字节5ms后,超时退出
  132.     {
  133.         if(RI)
  134.         {
  135.             RI = 0;
  136.             if(RxCnt < 1024)    RxBuff[RxCnt] = SBUF;
  137.             else
  138.             {
  139.                 RxBuff_10[RxCnt-1024] = SBUF;
  140.             }
  141.             if(++RxCnt >= 1034)    RxCnt = 1033;
  142.             j = 0;    //重新定时5ms
  143.         }
  144.     }
  145.     #if (WDT_Enable > 0)
  146.         WDT_reset(D_WDT_SCALE_256);
  147.     #endif
  148. }
  149. //========================================================================
  150. // 函数: void    main(void)
  151. // 描述: 主函数.
  152. // 参数: none.
  153. // 返回: none.
  154. // 版本: V1.0, 2013-4-29
  155. //========================================================================
  156. void    main(void)
  157. {
  158.     u8    i;
  159.     EA = 0;
  160.     Timer0_Stop();
  161.     Timer1_Stop();
  162.     #if (WDT_Enable > 0)
  163.         WDT_reset(D_WDT_SCALE_256);
  164.     #endif
  165.     S1_8bit();
  166.     S1_RX_Enable();
  167.     S1_BRT_UseTimer1();
  168.     Timer1_AsTimer();
  169.     Timer1_1T();
  170.     Timer1_8bitAutoReload();
  171.     Timer1_InterruptDisable();
  172.     TH1 = D_BRT0_1T_8bit;
  173.     Timer1_Run();
  174. //    PrintString1("\r\n STC ISP Demo\r\n");
  175.    
  176.     while(1)
  177.     {
  178.     //    TX1_write2buff('A');
  179.         HandCnt = 0;
  180.         for(WaitTime = 0; WaitTime < 300; WaitTime++)        //1.5秒超时
  181.         {
  182.             UART1_RxPackage();
  183.             if((RxCnt == 1) && (RxBuff[0] == 'd'))
  184.             {
  185.                 if(++HandCnt >= 10)
  186.                 {
  187.                     i = UART_Download();
  188.                     WaitTime = 250;
  189.                     if(i == 1)            PrintString1("\r\n User abort!\r\n");
  190.                     else if(i == 2)        PrintString1("\r\n PC Cancel!\r\n");
  191.                     else if(i == 4)        PrintString1("\r\n Programming Error!\r\n");
  192.                     else if(i == 0)
  193.                     {
  194.                         PrintString1("\r\n\r\n Programming Completed Successfully!\r\n");
  195.                         ReturnNameAndLength();
  196.                     }
  197.                 }
  198.             }
  199.         //    else    HandCnt = 0;
  200.         }
  201.         if(ISP_ReadByte(ISP_ADDRESS-3) == 0x02)
  202.         {
  203.             SCON = 0;
  204.             AUXR = 0;
  205.             TMOD = 0;
  206.             TL0 = 0;
  207.             TH0 = 0;
  208.             TH1 = 0;
  209.             TL1 = 0;
  210.             TCON = 0;
  211.             IAP_CMD = 0;
  212.             JumpAddress = ISP_ReadByte(ISP_ADDRESS-2);
  213.             JumpAddress = (JumpAddress << 8) | ISP_ReadByte(ISP_ADDRESS-1);    //Jump to user application
  214.             Jump_To_Application = (pFunction) JumpAddress;
  215.             Jump_To_Application();
  216.         }
  217.         PrintString1(" No AP\r\n");
  218.     }
  219. }
  220. //========================================================================
  221. // 函数: u16 Str2Int(u8 *inputstr)
  222. // 描述: 字符串转整型.
  223. // 参数: *inputstr: 字符串指针.
  224. // 返回: 16位整型数.
  225. // 版本: V1.0, 2013-4-29
  226. //========================================================================
  227. u16 Str2Int(u8 *inputstr)
  228. {
  229.     u16    val;
  230.     u8    i;
  231.    
  232.     val = 0;
  233.     for (i = 0; i < 5; i++)
  234.     {
  235.         if((inputstr[i] < '0') || (inputstr[i] > '9'))    break;
  236.         val = val * 10 + inputstr[i] - '0';
  237.     }
  238.     return val;
  239. }
  240. //========================================================================
  241. // 函数: void    ISP_WriteByte(u16 addr, u8 dat)
  242. // 描述: 对一个地址写FLASH一个字节.
  243. // 参数: addr: 16位FLASH地址.
  244. //       dat:  要写入的一字节数据.
  245. // 返回: none.
  246. // 版本: V1.0, 2013-4-29
  247. //========================================================================
  248. void    ISP_WriteByte(u16 addr, u8 dat)
  249. {
  250.     IAP_CONTR = ISP_CONTR = (ISP_EN + ISP_WAIT_FREQUENCY);    //使能IAP功能
  251.     ISP_WRITE();            //编程命令
  252.     IAP_ADDRL = addr;
  253.     IAP_ADDRH = addr >> 8;
  254.     IAP_DATA  = dat;        //将当前数据送IAP数据寄存器
  255.     ISP_TRIG();                //触发ISP命令
  256. }
  257. //========================================================================
  258. // 函数: u8    ISP_ReadByte(u16 addr)
  259. // 描述: 从一个地址读FLASH一个字节.
  260. // 参数: addr: 16位FLASH地址.
  261. // 返回: 读出的一字节数据.
  262. // 版本: V1.0, 2013-4-29
  263. //========================================================================
  264. u8    ISP_ReadByte(u16 addr)
  265. {
  266.     IAP_CONTR = ISP_CONTR = (ISP_EN + ISP_WAIT_FREQUENCY);    //使能IAP功能
  267.     ISP_READ();            //编程命令
  268.     IAP_ADDRL = addr;
  269.     IAP_ADDRH = addr >> 8;
  270.     ISP_TRIG();                //触发ISP命令
  271.     return(IAP_DATA);
  272. }
  273. //========================================================================
  274. // 函数: void    ISP_EraseSector(u16 addr)
  275. // 描述: 对FLASH擦除一个扇区.
  276. // 参数: addr: 16位FLASH地址.
  277. // 返回: none.
  278. // 版本: V1.0, 2013-4-29
  279. //========================================================================
  280. void    ISP_EraseSector(u16 addr)
  281. {
  282.     IAP_CONTR = ISP_CONTR = (ISP_EN + ISP_WAIT_FREQUENCY);        //使能IAP功能
  283.     ISP_ERASE();                //擦除命令
  284.     IAP_ADDRL = addr;
  285.     IAP_ADDRH = addr >> 8;
  286.     ISP_TRIG();                //触发ISP命令
  287. }
  288. //========================================================================
  289. // 函数: u8    UART_Download(void)
  290. // 描述: 按Ymodem接收文件数据并写入用户FLASH.
  291. // 参数: none.
  292. // 返回: none.
  293. // 版本: V1.0, 2013-4-29
  294. //========================================================================
  295. u8    UART_Download(void)
  296. {
  297.     u16    i;
  298.     u8    j;
  299.     PrintString1("\r\n\r\n Waiting for the file to be sent ... (press 'a' to abort)\r\n");
  300.    
  301.     Y_TimeOut = 0;
  302.     packets_received = 0;
  303.     session_begin = 0;
  304.     WaitTime = 40;
  305.     DownCheckSum = 0;
  306.    
  307.     while(WaitTime > 0)
  308.     {
  309.         if(Y_TimeOut == 0)
  310.         {
  311.             TX1_write2buff(CRC16);
  312.             Y_TimeOut = 300;
  313.             if(WaitTime > 0) WaitTime--;
  314.         }
  315.         while(Y_TimeOut > 0)
  316.         {
  317.             UART1_RxPackage();
  318.             if(RxCnt == 0)    Y_TimeOut--;
  319.             else
  320.             {
  321.                 if(RxCnt == 1)
  322.                 {
  323.                     if(RxBuff[0] == EOT)
  324.                     {
  325.                         TX1_write2buff(ACK);
  326.                         Y_TimeOut = 40;
  327.                     }
  328.                     else if((RxBuff[0] == ABORT1) || (RxBuff[0] == ABORT2))
  329.                     {
  330.                         return 1;
  331.                     }
  332.                 }
  333.                 else if(RxCnt <= 5)
  334.                 {
  335.                     if((RxBuff[0] == CANCEL) && (RxBuff[1] == CANCEL))
  336.                     {
  337.                         return 2;
  338.                     }
  339.                 }
  340.                 else if((RxCnt == 133) || (RxCnt == 1029))
  341.                 {
  342.                     if (RxBuff[PACKET_SEQNO_INDEX] != (RxBuff[PACKET_SEQNO_COMP_INDEX] ^ 0xff))
  343.                     {
  344.                         TX1_write2buff(NAK);    //错误, 请求重发
  345.                         Y_TimeOut = 300;
  346.                     }
  347.                     else
  348.                     {
  349.                         WaitTime = 5;
  350.                         if (packets_received == 0)    //发送序号为0, 为文件名数据包
  351.                         {
  352.                             if (RxBuff[PACKET_HEADER] != 0)  //文件名不为空
  353.                             {
  354.                                 for (i = 0; i < FILE_NAME_LENGTH; i++)    file_name[i] = 0;
  355.                                 for (i = 0; i < FILE_SIZE_LENGTH; i++)    file_size[i] = 0;
  356.                                 j = PACKET_HEADER;
  357.                                 for (i = 0; (i < FILE_NAME_LENGTH) && (RxBuff[j] != 0); i++)
  358.                                     file_name[i] = RxBuff[j++];        //保存文件名
  359.                                 for (i=0, j++; (RxBuff[j] != ' ') && (i < FILE_SIZE_LENGTH); i++)
  360.                                     file_size[i] = RxBuff[j++];    //保存文件长度
  361.                                 FileLength = Str2Int(file_size);    //文件长度由字符串转成十六进制数据
  362.                                 if (FileLength >= UserflashLenth)    //长度过长错误
  363.                                 {
  364.                                     TX1_write2buff(CANCEL);    //错误返回2个 CA
  365.                                     TX1_write2buff(CANCEL);
  366.                                     return 3;        //长度过长
  367.                                 }
  368.                                 
  369.                                 StartCode[0] = ISP_ReadByte(0);    //保存ISP跳转地址
  370.                                 StartCode[1] = ISP_ReadByte(1);
  371.                                 StartCode[2] = ISP_ReadByte(2);
  372.                                 ISP_EraseSector(0);
  373.                                 ISP_WriteByte(0,StartCode[0]);    //回写ISP跳转地址
  374.                                 ISP_WriteByte(1,StartCode[1]);
  375.                                 ISP_WriteByte(2,StartCode[2]);
  376.                                 for(i=0x200; i < UserflashLenth; i+=0x200)    //擦除N页
  377.                                     ISP_EraseSector(i);
  378.                            
  379.                                 TX1_write2buff(ACK);    //擦除完成, 返回应答
  380.                                 Y_TimeOut = 40;
  381.                                 packets_received ++;
  382.                                 session_begin = 1;
  383.                                 FlashDestination = 0;
  384.                                 DownCheckSum = 0;
  385.                             }
  386.                         }
  387.                         else if(session_begin == 1)    //收过文件名
  388.                         {
  389.                             if(RxBuff[PACKET_SEQNO_INDEX] == 0)    //全0数据帧
  390.                             {
  391.                                 ISP_WriteByte(ISP_ADDRESS-3,StartCode[0]);    //全部下载结束,最后写用户入口地址
  392.                                 ISP_WriteByte(ISP_ADDRESS-2,StartCode[1]);
  393.                                 ISP_WriteByte(ISP_ADDRESS-1,StartCode[2]);
  394.                                 TX1_write2buff(ACK);
  395.                                 
  396.                                 FlashCheckSum  = ISP_ReadByte(ISP_ADDRESS-3);
  397.                                 FlashCheckSum += ISP_ReadByte(ISP_ADDRESS-2);
  398.                                 FlashCheckSum += ISP_ReadByte(ISP_ADDRESS-1);
  399.                                 for(i = 3;    i < FileLength; i++)    FlashCheckSum += ISP_ReadByte(i);    //计算FLASH累加和
  400.                                 if(FlashCheckSum == DownCheckSum)    return 0;    //正确
  401.                                 else
  402.                                 {
  403.                                     ISP_EraseSector(ISP_ADDRESS-0x200);
  404.                                     return 4;    //写入错误
  405.                                 }
  406.                             }
  407.                             else    //数据帧
  408.                             {
  409.                                 for(i=0; i<1024; i++)    RxBuff[i] = RxBuff[i+3];
  410.                                 RxBuff[1021] = RxBuff_10[0];
  411.                                 RxBuff[1022] = RxBuff_10[1];
  412.                                 RxBuff[1023] = RxBuff_10[2];
  413.                                 RxCnt -= 5;
  414.                                 for(i = 0; (i < RxCnt) && (FlashDestination < FileLength); i++)
  415.                                 {
  416.                                     if(FlashDestination == 0)
  417.                                     {
  418.                                         StartCode[0] = RxBuff[0];
  419.                                         StartCode[1] = RxBuff[1];
  420.                                         StartCode[2] = RxBuff[2];
  421.                                         FlashDestination = 3;
  422.                                         i += 3;
  423.                                         DownCheckSum += RxBuff[0]; DownCheckSum += RxBuff[1]; DownCheckSum += RxBuff[2];
  424.                                     }
  425.                                     ISP_WriteByte(FlashDestination,RxBuff[i]);
  426.                                     DownCheckSum += RxBuff[i];
  427.                                     FlashDestination ++;
  428.                                 }
  429.                                 TX1_write2buff(ACK);    //保存完成, 返回应答
  430.                                 Y_TimeOut = 300;
  431.                                 packets_received ++;
  432.                             }
  433.                         }
  434.                     }
  435.                 }
  436.             }
  437.         }
  438.     }
  439.     return 100;    //其他错误
  440. }
复制代码
回复

使用道具 举报

该用户从未签到

1

主题

4703

回帖

5

积分

二级逆天

积分
5

终身成就奖特殊贡献奖原创先锋奖优秀斑竹奖

发表于 2020-12-1 11:16:26 | 显示全部楼层
回复

使用道具 举报

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

本版积分规则

公告:服务器刚移机,
大家请不要下载东西。
会下载失败


Copyright ©2011-2024 NTpcb.com All Right Reserved.  Powered by Discuz! (NTpcb)

本站信息均由会员发表,不代表NTpcb立场,如侵犯了您的权利请发帖投诉

( 闽ICP备2024076463号-1 ) 论坛技术支持QQ群171867948 ,论坛问题,充值问题请联系QQ1308068381

平平安安
TOP
快速回复 返回顶部 返回列表