zhp 发表于 2023-2-13 22:54:19

用户自定义命令实现ISP不停电下载-串口命令模式-STC8H

本帖目的:
      实现用户自定义串口命令实现不停电自动ISP下载的功能

实现原理:
      STC-ISP下载软件检测到用户代码发生改变时,会首先通过串口发送一串用户自定义的命令序列,然后立即进入ISP下载开始发送握手命令7F
      用户程序在运行用户代码过程中需要实时监控串口命令是否是正确的用户自定义命令序列,如果正确则通过触发软复位使单片机复位到系统ISP,即可实现不停电下载

参考代码:
#include "stc8h.h"
#include "stdio.h"
#include "intrins.h"

#define FOSC      11059200UL                  //定义工作频率
#define BAUD      (65536 - FOSC/4/115200)   //定义串口波特率重装值

//#define BRT_T1                              //使用定时器1当作串口波特率发生器
#define BRT_T2                                  //使用定时器2当作串口波特率发生器

typedef bit BOOL;
typedef unsigned char BYTE;

BOOL fBusy;                                     //串口发送忙标志
BYTE bStage;                                    //用户自定义命令检测阶段

void delay_ms(int n);
void CheckCustomCmd(BYTE dat);

void main()
{
    P0M0 = 0; P0M1 = 0;                         //端口模式初始化
    P1M0 = 0; P1M1 = 0;
    P2M0 = 0; P2M1 = 0;
    P3M0 = 0; P3M1 = 0;
    P4M0 = 0; P4M1 = 0;
    P5M0 = 0; P5M1 = 0;
   
#if defined BRT_T1
    AUXR = 0x40;                              //使用定时器1作为串口波特率发生器
    TMOD = 0x00;
    TL1 = BAUD;
    TH1 = BAUD >> 8;
    TR1 = 1;
#elif defined BRT_T2
    T2L = BAUD;                                 //使用定时器2作为串口波特率发生器
    T2H = BAUD >> 8;
    AUXR = 0x15;
#else
    #error "Baudrate generator select error !"
#endif
    SCON = 0x50;
    ES = 1;
    EA = 1;

    fBusy = 0;                                  //初始化用户变量
    bStage = 0;
   
    printf("STC8H系列串口自定义测试程序 !");
   
    while (1);
}

void uart_isr() interrupt 4
{
    if (TI)
    {
      TI = 0;
      fBusy = 0;
    }
   
    if (RI)
    {
      RI = 0;
      CheckCustomCmd(SBUF);                   //检测命令序列
    }
}

char putchar(char dat)                        //重定义putchar系统函数
{
    while (fBusy);
    fBusy = 1;
    SBUF = dat;
   
    return dat;
}

void CheckCustomCmd(BYTE dat)                   //检测命令序列:"@STCISP#"
{
    switch (bStage++)
    {
    default:
L_Check1st:
    case 0:                                     //检测命令头
      bStage = (dat == '@');
      break;
    case 1:
      if (dat != 'S') goto L_Check1st;
      break;
    case 2:
      if (dat != 'T') goto L_Check1st;
      break;
    case 3:
      if (dat != 'C') goto L_Check1st;
      break;
    case 4:
      if (dat != 'I') goto L_Check1st;
      break;
    case 5:
      if (dat != 'S') goto L_Check1st;
      break;
    case 6:
      if (dat != 'P') goto L_Check1st;
      break;
    case 7:
      if (dat != '#') goto L_Check1st;
      delay_ms(10);                           //检测到正确的命令序列后复位到系统区,此处的延时可省去
      IAP_CONTR = 0x60;                     //复位到系统区
      break;
    }
}

void delay_ms(int n)                            //毫秒延时子程序
{
    int i;
   
    while (n--)
    {
      i = 1000;
      while (i--);
    }
}


软件设置:

下软件进行如上图所示的下列步骤:
1、选择正确的单片机型号
2、选择正确的串口号
3、打开目标HEX文件(建议首先直接使用本贴的范例,不要修改)
4、选择“收到用户命令后复位到系统监控程序区”属性页
5、根据用户代码对串口的波特率、校验位进行设置
6、设置用户自定义命令(本范例使用的是默认命令“@STCISP#”)
7、勾选每次下载前都先发自定义命令
8、勾选“每次下载前都重装目标文件”选项和“目标文件发送变化时自动发送下载命令”选项
完成上面步骤后,下次只要重新编译项目并生成行的目标HEX,下载软件就可实现不停电自动下载了

注意:第一次必须使用串口进行正常下载,因为第一次下载时自定义命令还无效



国学芯用 发表于 2023-2-14 13:16:08

已测试 很顺畅

神农鼎 发表于 2023-2-14 13:39:38

好,详细正确,大家直接使用

lgwd 发表于 2023-2-18 23:31:29

通常调试程序的步骤是,编译完程序,无错误、无警告。点击Keil中的仿真按钮开始仿真(其它工作之前都已经做好)。想要修改程序,总是再点击Keil的调试按钮,停止调试并回到代码编辑模式。这时程序完全都停止了。整个程序都不运行,监控代码有何用?再者,要进行调试P3.0和P3.1被占用。ISP都是从这两个引脚通讯写入,怎么能实现串口通讯的不停电自动下载?

晓奇 发表于 2023-4-28 20:56:50

楼主给出的只是进入不停电下载的办法,并不是要占用主串口的意思。
其实在任何一个芯片的代码中只要打开了串口,或者USB CDC/USB HID,在接收数据处理的程序中加入下列代码:

定义一个字符串:
char *USER_STCISPCMD = "@STCISP#";                      //不停电自动ISP下载命令,这个命i令可以随意设置,喜欢就行
1。无USB的串口:
                        // 判别是不是下载命令。strncmp对比较的两个字符串前后无所谓,不影响判别结果
                        if(!strncmp(Rx_Buffer,USER_STCISPCMD,strlen(USER_STCISPCMD)))
                        {
                                IAP_CONTR = 0x60;   //触发软件复位,从ISP开始执行
                        }
2。USB CDC/HID
                        if(!strncmp(Rx_Buffer,USER_STCISPCMD,strlen(USER_STCISPCMD)))
                        {
                                USBCON = 0x00;      //清除USB设置
                                USBCLK = 0x00;
                                IRC48MCR = 0x00;
                                DelaymS(10);             // 此处等待10mS
                                IAP_CONTR = 0x60;   //触发软件复位,从ISP开始执行
                                while (1);
                        }
这并不影响主程序的运行与DEBUG
普通串口或带USB的CDC如楼主所述做ISP软件设置,HID勾选右侧的HID,
最关键是必须要勾选最后一条:“每次下载前都先发送自定义命令”
这样,只要是STC的芯片,开了串口就能不断电自动下载,很顺畅

芯芯向荣up 发表于 2023-5-29 16:19:20

最新的下载软件截图



晓飛飛 发表于 2023-6-28 15:32:29

对于使用USB转串口之类接口的系统板,
目前STC-ISP提供的自定义命令接口的最大波特率为115200,
这个波特率可否增加更高的档位或者支持用户自行编辑

suncat0504 发表于 2023-11-26 14:53:32

好资料,学习并收藏了,谢谢分享!

有你才恋家 发表于 2023-11-26 17:51:54

好办法{:4_174:},学习了

不会点灯 发表于 2023-12-3 11:52:37

{:4_174:}{:4_174:}{:4_174:}
页: [1] 2 3 4 5
查看完整版本: 用户自定义命令实现ISP不停电下载-串口命令模式-STC8H