打印
[STC单片机]

官方:用其它MCU对STC15系列单片机进行串口ISP下载C例程(ZT)

[复制链接]
6967|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 autopccopy 于 2014-3-17 22:53 编辑

/*---------------------------------------------------------------------*/
/* --- STC MCU Limited ------------------------------------------------*/
/* --- 使用其它MCU对STC15系列单片机进行串口ISP下载举例 ----------------*/
/* --- Mobile: (86)13922805190 ----------------------------------------*/
/* --- Fax: 86-755-82905966 -------------------------------------------*/
/* --- Tel: 86-755-82948412 -------------------------------------------*/
/* --- Web: www.**.com --------------------------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了宏晶科技的资料及程序   */
/* 如果要在**中应用此代码,请在**中注明使用了宏晶科技的资料及程序   */
/*---------------------------------------------------------------------*/
//本示例在Keil开发环境下请选择Intel的8052芯片型号进行编译
//假定测试芯片的工作频率为11.0592MHz
//注意:使用本代码对STC15系列的单片机进行下载时,必须要执行了Download代码之后,
//才能给目标芯片上电,否则目标芯片将无**确下载
#include "reg51.h"
typedef bit BOOL;
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
//宏、常量定义
#define FALSE               0
#define TRUE                1
#define LOBYTE(w)           ((BYTE)(WORD)(w))
#define HIBYTE(w)           ((BYTE)((WORD)(w) >> 8))
#define MINBAUD             2400L
#define MAXBAUD             115200L
#define FOSC                11059200L                   //主控芯片工作频率
#define BR(n)               (65536 - FOSC/4/(n))        //主控芯片串口波特率计算公式
#define T1MS                (65536 - FOSC/1000)         //主控芯片1ms定时初值
#define FUSER               24000000L                   //15系列目标芯片工作频率
#define RL(n)               (65536 - FUSER/4/(n))       //15系列目标芯片串口波特率计算公式
//SFR定义
sfr AUXR = 0x8e;
//变量定义
BOOL f1ms;                                              //1ms标志位
BOOL UartBusy;                                          //串口发送忙标志位
BOOL UartReceived;                                      //串口数据接收完成标志位
BYTE UartRecvStep;                                      //串口数据接收控制
BYTE TimeOut;                                           //串口通讯超时计数器
BYTE xdata TxBuffer[256];                               //串口数据发送缓冲区
BYTE xdata RxBuffer[256];                               //串口数据接收缓冲区
char code DEMO[256];                                    //演示代码数据
//函数声明
void Initial(void);
void DelayXms(WORD x);
BYTE UartSend(BYTE dat);
void CommInit(void);
void CommSend(BYTE size);
BOOL Download(BYTE *pdat, long size);
//主函数入口
void main(void)
{
    while (1)
    {
        Initial();
        if (Download(DEMO, 0x0100))
        {
            //下载成功
            P3 = 0xff;
            DelayXms(500);
            P3 = 0x00;
            DelayXms(500);
            P3 = 0xff;
            DelayXms(500);
            P3 = 0x00;
            DelayXms(500);
            P3 = 0xff;
            DelayXms(500);
            P3 = 0x00;
            DelayXms(500);
            P3 = 0xff;
        }
        else
        {
            //下载失败
            P3 = 0xff;
            DelayXms(500);
            P3 = 0xf3;
            DelayXms(500);
            P3 = 0xff;
            DelayXms(500);
            P3 = 0xf3;
            DelayXms(500);
            P3 = 0xff;
            DelayXms(500);
            P3 = 0xf3;
            DelayXms(500);
            P3 = 0xff;
        }
    }
}
//1ms定时器中断服务程序
void tm0(void) interrupt 1 using 1
{
    static BYTE Counter100;
   
    f1ms = TRUE;
    if (Counter100-- == 0)
    {
        Counter100 = 100;
        if (TimeOut) TimeOut--;
    }
}
//串口中断服务程序
void uart(void) interrupt 4 using 1
{
    static WORD RecvSum;
    static BYTE RecvIndex;
    static BYTE RecvCount;
    BYTE dat;
    if (TI)
    {   
        TI = 0;
        UartBusy = FALSE;
    }
   
    if (RI)
    {
        RI = 0;
        dat = SBUF;
        switch (UartRecvStep)
        {
        case 1:
            if (dat != 0xb9) goto L_CheckFirst;
            UartRecvStep++;
            break;
        case 2:
            if (dat != 0x68) goto L_CheckFirst;
            UartRecvStep++;
            break;
        case 3:
            if (dat != 0x00) goto L_CheckFirst;
            UartRecvStep++;
            break;
        case 4:
            RecvSum = 0x68 + dat;
            RecvCount = dat - 6;
            RecvIndex = 0;
            UartRecvStep++;
            break;
        case 5:
            RecvSum += dat;
            RxBuffer[RecvIndex++] = dat;
            if (RecvIndex == RecvCount) UartRecvStep++;
            break;
        case 6:
            if (dat != HIBYTE(RecvSum)) goto L_CheckFirst;
            UartRecvStep++;
            break;
        case 7:
            if (dat != LOBYTE(RecvSum)) goto L_CheckFirst;
            UartRecvStep++;
            break;
        case 8:
            if (dat != 0x16) goto L_CheckFirst;
            UartReceived = TRUE;
            UartRecvStep++;
            break;
L_CheckFirst:
        case 0:
        default:
            CommInit();
            UartRecvStep = (dat == 0x46 ? 1 : 0);
            break;
        }
    }
}
//系统初始化
void Initial(void)
{
    UartBusy = FALSE;
    SCON = 0xd0;                    //串口数据模式必须为8位数据+1位偶检验
    AUXR = 0xc0;
    TMOD = 0x00;
    TH0 = HIBYTE(T1MS);
    TL0 = LOBYTE(T1MS);
    TR0 = 1;
    TH1 = HIBYTE(BR(MINBAUD));
    TL1 = LOBYTE(BR(MINBAUD));
    TR1 = 1;
    ET0 = 1;
    ES = 1;
    EA = 1;
}
//Xms延时程序
void DelayXms(WORD x)
{
    do
    {
        f1ms = FALSE;
        while (!f1ms);
    } while (x--);
}
//串口数据发送程序
BYTE UartSend(BYTE dat)
{
    while (UartBusy);
   
    UartBusy = TRUE;
    ACC = dat;
    TB8 = P;
    SBUF = ACC;
   
    return dat;
}
//串口通讯初始化
void CommInit(void)
{
    UartRecvStep = 0;
    TimeOut = 20;
    UartReceived = FALSE;
}
//发送串口通讯数据包
void CommSend(BYTE size)
{
WORD sum;
    BYTE i;
   
    UartSend(0x46);
    UartSend(0xb9);
    UartSend(0x6a);
    UartSend(0x00);
    sum = size + 6 + 0x6a;
    UartSend(size + 6);
    for (i=0; i<size; i++)
    {
        sum += UartSend(TxBuffer);
    }
    UartSend(HIBYTE(sum));
    UartSend(LOBYTE(sum));
    UartSend(0x16);
    while (UartBusy);
    CommInit();
}
//对STC15系列的芯片进行数据下载程序
BOOL Download(BYTE *pdat, long size)
{
    BYTE arg;
    BYTE cnt;
    WORD addr;
   
    //握手
    CommInit();
    while (1)
    {
        if (UartRecvStep == 0)
        {
            UartSend(0x7f);
            DelayXms(10);
        }
        if (UartReceived)
        {
            arg = RxBuffer[4];
            if (RxBuffer[0] == 0x50) break;
            return FALSE;
        }
    }
    //设置参数
    TxBuffer[0] = 0x01;
    TxBuffer[1] = arg;
    TxBuffer[2] = 0x40;
TxBuffer[3] = HIBYTE(RL(MAXBAUD));
TxBuffer[4] = LOBYTE(RL(MAXBAUD));
TxBuffer[5] = 0x00;
TxBuffer[6] = 0x00;
TxBuffer[7] = 0xc3;
    CommSend(8);
while (1)
{
        if (TimeOut == 0) return FALSE;
        if (UartReceived)
        {
            if (RxBuffer[0] == 0x01) break;
            return FALSE;
        }
}
    //准备
    TH1 = HIBYTE(BR(MAXBAUD));
    TL1 = LOBYTE(BR(MAXBAUD));
    DelayXms(10);
TxBuffer[0] = 0x05;
CommSend(1);
while (1)
{
        if (TimeOut == 0) return FALSE;
        if (UartReceived)
        {
            if (RxBuffer[0] == 0x05) break;
            return FALSE;
        }
}
   
    //擦除
    DelayXms(10);
TxBuffer[0] = 0x03;
TxBuffer[1] = 0x00;
CommSend(2);
    TimeOut = 100;
    while (1)
{
        if (TimeOut == 0) return FALSE;
        if (UartReceived)
        {
            if (RxBuffer[0] == 0x03) break;
            return FALSE;
        }
}
    //写用户代码
    DelayXms(10);
    addr = 0;
TxBuffer[0] = 0x22;
while (addr < size)
{
        TxBuffer[1] = HIBYTE(addr);
        TxBuffer[2] = LOBYTE(addr);
        cnt = 0;
        while (addr < size)
        {
            TxBuffer[cnt+3] = pdat[addr];
            addr++;
            cnt++;
            if (cnt >= 128) break;
        }
        CommSend(cnt + 3);
  while (1)
  {
            if (TimeOut == 0) return FALSE;
            if (UartReceived)
            {
                if ((RxBuffer[0] == 0x02) && (RxBuffer[1] == 'T')) break;
                return FALSE;
            }
  }
  TxBuffer[0] = 0x02;
}
    //写硬件选项(如果不需要修改硬件选项,此步骤可直接跳过)
    DelayXms(10);
    for (cnt=0; cnt<128; cnt++)
    {
        TxBuffer[cnt] = 0xff;
}
    TxBuffer[0] = 0x04;
TxBuffer[1] = 0x00;
TxBuffer[2] = 0x00;
TxBuffer[34] = 0xfd;
TxBuffer[62] = arg;
TxBuffer[63] = 0x7f;
TxBuffer[64] = 0xf7;
TxBuffer[65] = 0x7b;
TxBuffer[66] = 0x1f;
CommSend(67);
while (1)
{
        if (TimeOut == 0) return FALSE;
        if (UartReceived)
        {
            if ((RxBuffer[0] == 0x04) && (RxBuffer[1] == 'T')) break;
            return FALSE;
        }
}
    //下载完成
    return TRUE;
}
char code DEMO[256] =
{
    0x02,0x00,0x5E,0x12,0x00,0x4B,0x75,0xB0,
    0xEF,0x12,0x00,0x2C,0x75,0xB0,0xDF,0x12,
    0x00,0x2C,0x75,0xB0,0xFE,0x12,0x00,0x2C,
    0x75,0xB0,0xFD,0x12,0x00,0x2C,0x75,0xB0,
    0xFB,0x12,0x00,0x2C,0x75,0xB0,0xF7,0x12,
    0x00,0x2C,0x80,0xDA,0xE4,0xFF,0xFE,0xE4,
    0xFD,0xFC,0x0D,0xBD,0x00,0x01,0x0C,0xBC,
    0x01,0xF8,0xBD,0xF4,0xF5,0x0F,0xBF,0x00,
    0x01,0x0E,0xBE,0x03,0xEA,0xBF,0xE8,0xE7,
    0x02,0x00,0x4B,0x75,0x80,0xFF,0x75,0x90,
    0xFF,0x75,0xA0,0xFF,0x75,0xB0,0xFF,0x75,
    0xC0,0xFF,0x75,0xC8,0xFF,0x22,0x78,0x7F,
    0xE4,0xF6,0xD8,0xFD,0x75,0x81,0x07,0x02,
    0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};


摘自STC-ISP V6.67:
http://www.****ducst/STCISP/stc-isp-15xx-v6.67.exe
http://www.****ducst/STCISP/stc-isp-15xx-v6.67.exe
STC-ISP Ver6.67 (2014-3-13)
  1. 修正STC15W408AS系列的低压检测电压和Cpu-Core内核工作电压参数
  2. 增加STC15F207A/STC15L207A型号,固件版本: 7.1.4R
  3. 增加STC608AD-5/STC608AD-3型号,固件版本: 6.6G
  4. 添加型号到Keil中失败时,给出错误提示
  5. 发布项目时,支持自定义图标
  6. 不限制发布项目中自动增量的长度
  7. 发布项目的界面可任意放大缩小
  8. 增加示例代码(使用其它MCU对STC15系列单片机进行ISP下载)
Ver6.66B (2014-3-5)
  1. 增加STC15W408AS系列的型号
  2. 脱机下载板(U7、U7-S1)固件更新为v1.13
     (将P1.1设置为强推挽,P1.0设置为高阻输入)
Ver6.66 (2014-2-24)
  1. 修正STC15W408S系列的低压检测电压和Cpu-Core内核工作电压参数
  2. 开放STC15F104W/STC15L104W系列的低压检测电压较低电压值
  3. 增加读取掉电唤醒定时器频率和内部BandGap电压值的范例代码




stc-isp-15xx-v6.67.rar (507.52 KB)



相关帖子

沙发
myxiaonia| | 2014-3-18 07:06 | 只看该作者
等于开放了isp下载协议了,以前老是有人想**,不用亲自动手了

使用特权

评论回复
板凳
coody| | 2014-3-18 11:58 | 只看该作者
开放了部分协议,这个好,以后可以自己做一拖8的下载器了

使用特权

评论回复
地板
mcuisp| | 2014-3-18 12:50 | 只看该作者
这不是给我找事情做了;P
好多客户要我支持stc,我都以厂家没公开协议来推托了。

使用特权

评论回复
5
coody| | 2014-3-18 16:28 | 只看该作者
楼上,有免费的MCUISP支持串口下载STM32F051不?

使用特权

评论回复
6
mcuisp| | 2014-3-19 01:47 | 只看该作者
coody 发表于 2014-3-18 16:28
楼上,有免费的MCUISP支持串口下载STM32F051不?

还没更新,都忙着弄脱机烧录器EP968了:$

使用特权

评论回复
7
coody| | 2014-3-19 14:51 | 只看该作者
理解。。。。:)

使用特权

评论回复
8
autopccopy|  楼主 | 2014-3-20 21:12 | 只看该作者
mcuisp 发表于 2014-3-19 01:47
还没更新,都忙着弄脱机烧录器EP968了

@McuPlayer 你也可以自己做个STC的独立脱机烧写工具和独立的升级上位机了!:)

(110)

使用特权

评论回复
9
mcuisp| | 2014-3-20 23:08 | 只看该作者
autopccopy 发表于 2014-3-20 21:12
@McuPlayer 你也可以自己做个STC的独立脱机烧写工具和独立的升级上位机了!

(110)  ...

对我来说,只是写个固件 就行了。

使用特权

评论回复
10
rgwan| | 2014-4-10 22:42 | 只看该作者
早不折腾STC了。。。
最近都转投GD32和LGT了。STC又没啥亮点。。。

使用特权

评论回复
11
automationwang| | 2014-11-19 16:55 | 只看该作者
autopccopy 发表于 2014-3-20 21:12
@McuPlayer 你也可以自己做个STC的独立脱机烧写工具和独立的升级上位机了!

(110)  ...

您好,请教您一个用其他MCU对STC15单片机进行ISP下载的问题,我用arm给单片机下程序,流程如下:arm给单片机发送7F,单片机上电,arm可以收到单片机的回复:
if (UartReceived)
        {
            arg = RxBuffer[4];
            if ([color=Red]RxBuffer[0] == 0x50[/color]) break;
            return FALSE;
        }
然后arm给单片机发送:
  //设置参数
    TxBuffer[0] = 0x01;
    TxBuffer[1] = arg;
    TxBuffer[2] = 0x40;
TxBuffer[3] = HIBYTE(RL(MAXBAUD));
TxBuffer[4] = LOBYTE(RL(MAXBAUD));
TxBuffer[5] = 0x00;
TxBuffer[6] = 0x00;
TxBuffer[7] = 0xc3;
    CommSend(8);
arm发送完以后收不到单片机的下一个回复,
      if (UartReceived)
        {
            if (RxBuffer[0] == 0x01) break;
            return FALSE;
        }
arm和单片机的波特率都是9600,单片机型号是STC15L2k60S2。
望指点,是怎么回事,非常感谢。
我QQ1067636403

使用特权

评论回复
12
automationwang| | 2014-11-19 16:55 | 只看该作者
您好,请教您一个用其他MCU对STC15单片机进行ISP下载的问题,我用arm给单片机下程序,流程如下:arm给单片机发送7F,单片机上电,arm可以收到单片机的回复:
if (UartReceived)
        {
            arg = RxBuffer[4];
            if ([color=Red]RxBuffer[0] == 0x50[/color]) break;
            return FALSE;
        }
然后arm给单片机发送:
  //设置参数
    TxBuffer[0] = 0x01;
    TxBuffer[1] = arg;
    TxBuffer[2] = 0x40;
TxBuffer[3] = HIBYTE(RL(MAXBAUD));
TxBuffer[4] = LOBYTE(RL(MAXBAUD));
TxBuffer[5] = 0x00;
TxBuffer[6] = 0x00;
TxBuffer[7] = 0xc3;
    CommSend(8);
arm发送完以后收不到单片机的下一个回复,
      if (UartReceived)
        {
            if (RxBuffer[0] == 0x01) break;
            return FALSE;
        }
arm和单片机的波特率都是9600,单片机型号是STC15L2k60S2。
望指点,是怎么回事,非常感谢。
我QQ1067636403

使用特权

评论回复
13
autopccopy|  楼主 | 2014-11-19 17:57 | 只看该作者
automationwang 发表于 2014-11-19 16:55
您好,请教您一个用其他MCU对STC15单片机进行ISP下载的问题,我用arm给单片机下程序,流程如下:arm给单片 ...

建议咨询厂家(技术支持QQ:   800003751) 或本坛的  @**NT018 :)

使用特权

评论回复
14
automationwang| | 2014-11-20 09:25 | 只看该作者
autopccopy 发表于 2014-11-19 17:57
建议咨询厂家(技术支持QQ:   800003751) 或本坛的  @**NT018

好的,谢谢

使用特权

评论回复
15
老唐学电子| | 2022-8-23 19:26 | 只看该作者
myxiaonia 发表于 2014-3-18 07:06
等于开放了isp下载协议了,以前老是有人想**,不用亲自动手了

请问最后有使用STC的这个下载函数了吗?我用了跟楼下有个兄弟一样,同样的地方出现不应答

使用特权

评论回复
16
老唐学电子| | 2022-8-23 19:27 | 只看该作者
automationwang 发表于 2014-11-19 16:55
您好,请教您一个用其他MCU对STC15单片机进行ISP下载的问题,我用arm给单片机下程序,流程如下:arm给单 ...

最后解决了吗?

使用特权

评论回复
17
wen496785487| | 2022-10-17 17:48 | 只看该作者

没能成功,多半是由于串口奇偶校验位不对,前面的可以用无校验,后面的就不行了,必须要是偶校验的
人家的例程都是有这个的,所以用别的单片机搞,容易忘记这里。

SCON = 0xd0;                    //串口数据模式必须为8位数据+1位偶检验

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:---人活着就是要改变世界! ----51单片机,单片机中的拖拉机!

153

主题

2861

帖子

15

粉丝