通过第三方程序实现对STC单片机的程序下载,可以方便进行现场的调试和更新。特别是对于设计远程程序更新、无线程序下载与调试等功能有帮助。

本文给出了下载相关的一些程序设计。

STC单片机ISP下载协议

在手边并没有成文的对STC单片机ISP下载协议,仅仅在STC官方网站的STC8G,8H,8A单片机手册中给出了“使用第三方MCU对STC8G,8H, 8A”系列的但潘辰进行ISP下载的范例程序。参考这些程序,可以完成对STC8G系列的单片机内部的FLASH程序的更新。

▲ STC8G技术手册中的下载协议

对于STC单片机内部的“硬件选项”,手册建议还是使用官方的原来的STC-ISP下载程序完成配置,这比较可靠。

▲ STC单片机的硬件选项

STC的ISP下载程序

下面给出了使用STC8G1K17单片机中,C语言实现的ISP程序。

下面给出单片机借助的外部资源以及相应的源码。

1. UART2

程序使用了STC8G1k的UART2完成对下载MCU发送相关的指令。需要注意的是,在ISP通信过程UART2需要设置为9bit的工作模式,这在开始的我并没有注意,造成前期的调试受阻。

为了避免串口线对被调试单片机反向供电,特别是在外部单片机掉电进行冷启动的过程中,由于串口的电压可能仍然能够满足被下载单片机的工作电源需要,通过对UART2对应的输出管脚置为高阻状态来避免反向供电。这一点,并没有像STC8G1K08手册中推荐的使用电阻和二极管来进行电源个的的方案。

▲ STC单片机数据手册中推荐的串口电源隔离方案

2. CCP2

使用了STC8G1K08的CCP2产生PWM波形来整流出高压(2VC≈2×5V≈10V2V_C \approx 2 \times 5V \approx 10V2VC​≈2×5V≈10V)来驱动MOS管。详细的方案可以参见博文如何利用单片机IO口产生两倍的电源电压中的描述。

在对被下载单片机电源控制的同时,也需要改变UART2的RXD,TXD管脚的输出状态。在关闭电源的时候,将RXD,TXD设置为INPUT的高阻模式,可以避免对ISP单片机端口供电。下面代码显示了这里的控制。

//------------------------------------------------------------------------------
void ispPowerOn(void) {P10V_ON;PM_BIDIR(RXD2_PIN);PM_PP(TXD2_PIN);
}void ispPowerOff(void) {PM_INPUT(RXD2_PIN);PM_INPUT(TXD2_PIN);P10V_OFF;
}

3. 完整的源码

程序的其它部分可以参见数据手册中的范例程序进行阅读。由于没有正式的问题,在这里也就不再对下载的协议反向解释了。

程序的头文件。

/*
**==============================================================================
** STCISP.H:            -- by Dr. ZhuoQing, 2020-04-30
**
**  Description:
**
**==============================================================================
*/
#ifndef __STCISP__
#define __STCISP__
//------------------------------------------------------------------------------
#ifdef STCISP_GLOBALS#define STCISP_EXT
#else#define STCISP_EXT extern
#endif // STCISP_GLOBALS
//------------------------------------------------------------------------------
//==============================================================================#define PWM_PIN                 3, 7
#define P5V_PIN                 3, 6                                                                #define RXD2_PIN                1, 0
#define TXD2_PIN                1, 1//------------------------------------------------------------------------------
#define P10V_ON                 ON(P5V_PIN), PWM3SetPWM(0x7f)
#define P10V_OFF                OFF(P5V_PIN), PWM3SetPWM(0xff)//------------------------------------------------------------------------------void ispInit(unsigned long lnBaud);void ispPowerOn(void);
void ispPowerOff(void);#define ISP_POWEROFF_TIME      200         // unit :msSTCISP_EXT unsigned int g_nIspPowerOffTime;void ispSetBaud(unsigned long lnBaud, unsigned char uc9BitFlag);// uc9BitFlag: 1 : Set UART2 as 9bit mode//             0 : as 8 bit mode//------------------------------------------------------------------------------
STCISP_EXT unsigned int g_nispReceiveSum;
STCISP_EXT unsigned char g_ucispReceiveIndex, g_ucispReceiveCount, g_ucispReceiveStep;
STCISP_EXT unsigned char xdata g_ucispRxBuffer[64], g_ucispTxBuffer[150];
STCISP_EXT unsigned char g_ucispReceiveFlag;//------------------------------------------------------------------------------
STCISP_EXT unsigned int g_nispProgramStart;
STCISP_EXT unsigned char g_ucispProgramLength;#define ISP_PROGRAM_BUFFER          256
STCISP_EXT unsigned char xdata g_ucispProgramBuffer[ISP_PROGRAM_BUFFER];//------------------------------------------------------------------------------void ispProcChar(void);
void ispCommunicationInit(void);
unsigned char ispSendChar(unsigned char ucChar);
void ispCommandSend(unsigned char ucSize);
void ispRun(unsigned long lnBaud, unsigned int nTime);//------------------------------------------------------------------------------
void ispShowRxBuffer(void);//------------------------------------------------------------------------------
#define FALSE                       1
#define TRUE                        0typedef bit                         BOOL;
typedef unsigned char               BYTE;
typedef unsigned short              WORD;#define LOBYTE(w)                   ((BYTE)(WORD)(w))
#define HIBYTE(w)                   ((BYTE)((WORD)(w) >> 8))#define FUSER                       35000000L
#define RL(n)                       (0x10000 - FUSER/4/(n))#define ISP_DOWNLOAD_CHECKLOOP      100
#define ISP_DOWNLOAD_BAUD           115200L
#define ISP_DOWNLOAD_TIMEOUT        2000
#define ISP_DOWNLOAD_TIMEOUT_ERASE  2000
#define ISP_DOWNLOAD_PAGESIZE       128//------------------------------------------------------------------------------
#define ISP_ARG7_8H                 0x97
#define ISP_ARG7_8G                 0x97
#define ISP_ARG7_8A                 0x81unsigned char ispEnterISP(unsigned long lnStartBaud, unsigned long lnBaud, unsigned char ucArg7, unsigned long lnFosc);unsigned char ispEraseMCU(void);
unsigned char ispDownloadCode(unsigned char * pucCode, unsigned int nSize, unsigned int nStartAddress);//------------------------------------------------------------------------------//==============================================================================
//             END OF THE FILE : STCISP.H
//------------------------------------------------------------------------------
#endif // __STCISP__

程序的C语言文件。

/*
**==============================================================================
** STCISP.C:             -- by Dr. ZhuoQing, 2020-04-30
**
**==============================================================================
*///------------------------------------------------------------------------------
#define STCISP_GLOBALS        1              // Define the global variables
#include "STCISP.H"
#include "STC8G.H"
#include "C51BASIC.H"
#include <STDIO.H>//------------------------------------------------------------------------------void ispInit(unsigned long lnBaud) {//--------------------------------------------------------------------------    ispSetBaud(lnBaud, 0);//--------------------------------------------------------------------------ispCommunicationInit();//--------------------------------------------------------------------------PM_PP(PWM_PIN);PM_PP(P5V_PIN);P10V_ON;  g_nIspPowerOffTime = ISP_POWEROFF_TIME;}//------------------------------------------------------------------------------
void ispRun(unsigned long lnBaud, unsigned int nTime) {ispPowerOff();WaitTime(nTime);ispPowerOn();ispSetBaud(lnBaud, 0);UART2_CLEAR;
}//------------------------------------------------------------------------------
void ispPowerOn(void) {P10V_ON;PM_BIDIR(RXD2_PIN);PM_PP(TXD2_PIN);
}void ispPowerOff(void) {PM_INPUT(RXD2_PIN);PM_INPUT(TXD2_PIN);P10V_OFF;
}void ispSetBaud(unsigned long lnBaud, unsigned char uc9BitFlag) {unsigned int nNumber;nNumber = Baud2TimeReload(lnBaud, 35000000L);if(uc9BitFlag)    S2CON |= 0x80;                          // Enable bit9 communicationelse S2CON &= ~0x80;T2H = nNumber >> 8;T2L = nNumber;
}void ispCommunicationInit(void) {unsigned int i;for(i = 0; i < sizeof(g_ucispRxBuffer); i ++)g_ucispRxBuffer[i] = 0;g_nispReceiveSum = 0;g_ucispReceiveIndex = g_ucispReceiveCount = g_ucispReceiveStep = 0;g_ucispReceiveFlag = 0;}//------------------------------------------------------------------------------
void ispProcChar(void) {unsigned char ucChar;if(!UART2_CANRECE) return;    UART2ReceChar(&ucChar);//--------------------------------------------------------------------------
//    printf("%bx ", ucChar);//------------------------------------------------------------------------        switch(g_ucispReceiveStep) {case 1:if(ucChar != 0xb9) goto L_CheckFirst;g_ucispReceiveStep ++;break;case 2:if(ucChar != 0x68) goto L_CheckFirst;g_ucispReceiveStep ++;break;case 3:if(ucChar != 0x0) goto L_CheckFirst;g_ucispReceiveStep ++;break;case 4:g_nispReceiveSum = 0x68 + ucChar;g_ucispReceiveCount = ucChar - 6;g_ucispReceiveIndex = 0;g_ucispReceiveStep ++;break;case 5:g_nispReceiveSum += ucChar;g_ucispRxBuffer[g_ucispReceiveIndex ++] = ucChar;if(g_ucispReceiveIndex == g_ucispReceiveCount)g_ucispReceiveStep ++;break;case 6:if(ucChar != (unsigned char)(g_nispReceiveSum >> 8))goto L_CheckFirst;g_ucispReceiveStep ++;break;case 7:if(ucChar != (unsigned char)(g_nispReceiveSum & 0xff))goto L_CheckFirst;g_ucispReceiveStep ++;break;case 8:if(ucChar != 0x16) goto L_CheckFirst;g_ucispReceiveFlag = 1;g_ucispReceiveStep ++;break;L_CheckFirst:case 0:default:ispCommunicationInit();if(ucChar == 0x46) g_ucispReceiveStep = 1;else g_ucispReceiveStep = 0;break;}
}//------------------------------------------------------------------------------
/*
void ispShowRxBuffer(void) {unsigned int i;printf("Count:%bd\r\n", g_ucispReceiveCount);for(i = 0; i < g_ucispReceiveCount; i ++) printf("%bx ", g_ucispRxBuffer[i]);printf("\r\n");
}
*///------------------------------------------------------------------------------
unsigned char ispSendChar(unsigned char ucChar) {g_ucUART2IntFlag = 0;ACC = ucChar;S2CON &= ~0x8;if(P) S2CON |= 0x8;S2BUF = ACC;while(1) {if(g_ucUART2IntFlag) break;}return ucChar;
}//------------------------------------------------------------------------------
void ispCommandSend(unsigned char ucSize) {unsigned int nSum;unsigned char i, c;ispSendChar(0x46);ispSendChar(0xb9);ispSendChar(0x6a);ispSendChar(0x00);nSum = ucSize + 6 + 0x6a;ispSendChar(ucSize + 6);for(i = 0; i < ucSize; i ++) {c = g_ucispTxBuffer[i];nSum += c;ispSendChar(c);}ispSendChar((unsigned char)(nSum >> 8));ispSendChar((unsigned char)(nSum & 0xff));ispSendChar(0x16);ispCommunicationInit();}//------------------------------------------------------------------------------
unsigned char ispEnterISP(unsigned long lnStartBaud, unsigned long lnBaud, unsigned char ucArg7, unsigned long lnFosc) {unsigned char ucArg;unsigned int nCheckLoop;unsigned int nMS10;unsigned int nBaudTimeReload;//----------------------------------------------------------------------            ispCommunicationInit();ispSetBaud(lnStartBaud, 1);//    printf("Set baud:%ld\r\n", lnStartBaud);//--------------------------------------------------------------------------ispPowerOff();WaitTime(g_nIspPowerOffTime);ispPowerOn();nMS10 = (unsigned int)(GetClickMS() + 10);nCheckLoop = 0;for(nCheckLoop = 0; nCheckLoop < ISP_DOWNLOAD_CHECKLOOP;) {ispProcChar();        if(g_ucispReceiveStep == 0) {if(GetClickMS() == nMS10) {ispSendChar(0x7f);nMS10 = (unsigned int)(GetClickMS() + 10);nCheckLoop ++;}           }if(g_ucispReceiveFlag) {ucArg = g_ucispRxBuffer[4];if(g_ucispRxBuffer[0] == 0x50)break;return 1;                       // return error }}if(nCheckLoop >= ISP_DOWNLOAD_CHECKLOOP) return 2;//--------------------------------------------------------------------------// Set new baud
//    printf("\r\nSet new Buad:%ld/%d\r\n", lnBaud, nCheckLoop);nBaudTimeReload = Baud2TimeReload(lnBaud, lnFosc);
//    printf("%x\r\n", nBaudTimeReload);ucArg = g_ucispRxBuffer[4];g_ucispTxBuffer[0] = 0x01;g_ucispTxBuffer[1] = ucArg;g_ucispTxBuffer[2] = 0x40;g_ucispTxBuffer[3] = HIBYTE(nBaudTimeReload);g_ucispTxBuffer[4] = LOBYTE(nBaudTimeReload);g_ucispTxBuffer[5] = 0x00;g_ucispTxBuffer[6] = 0x00;g_ucispTxBuffer[7] = ucArg7;//0x97;//0x81;//0x97;                // 0x81: STC8A// 0x97: STC8G,8HnMS10 = (unsigned int)(GetClickMS() + ISP_DOWNLOAD_TIMEOUT);ispCommandSend(8);for(;;) {ispProcChar();if(g_ucispReceiveFlag) {if(g_ucispRxBuffer[0] == 0x01) break;return 3;}if(GetClickMS() == nMS10) return 4;}//----------------------------------------------------------------------// Prepare the new download baud    ispSetBaud(lnBaud, 1);//    WaitTime(10);g_ucispTxBuffer[0] = 0x05;g_ucispTxBuffer[1] = 0x00;g_ucispTxBuffer[2] = 0x00;g_ucispTxBuffer[3] = 0x5a;g_ucispTxBuffer[4] = 0xa5;nMS10 = (unsigned int)(GetClickMS() + ISP_DOWNLOAD_TIMEOUT);ispCommandSend(5);for(;;) {ispProcChar();if(g_ucispReceiveFlag) {if(g_ucispRxBuffer[0] == 0x05) break;return 5;}if(GetClickMS() == nMS10) return 6;}return 0;}//------------------------------------------------------------------------------
unsigned char ispEraseMCU(void) {unsigned int nMS10;//----------------------------------------------------------------------    // Erase the ICWaitTime(10);g_ucispTxBuffer[0] = 0x03;g_ucispTxBuffer[1] = 0x00;g_ucispTxBuffer[2] = 0x00;g_ucispTxBuffer[3] = 0x5a;g_ucispTxBuffer[4] = 0xa5;nMS10 = (unsigned int)(GetClickMS() + ISP_DOWNLOAD_TIMEOUT_ERASE);ispCommandSend(5);for(;;) {ispProcChar();if(g_ucispReceiveFlag) {if(g_ucispRxBuffer[0] == 0x03) break;return 1;}if(GetClickMS() == nMS10) return 2;}return 0;                               // OK}//------------------------------------------------------------------------------s
unsigned char ispDownloadCode(unsigned char * pucCode, unsigned int nSize, unsigned int nStartAddress) {unsigned int i, nStep, nLength, j;unsigned int nDownloadAddress, nStart, nEnd, nOffset;unsigned int nPoint;unsigned int nMS10;nStep = (int)((nSize + ISP_DOWNLOAD_PAGESIZE - 1) / ISP_DOWNLOAD_PAGESIZE);g_ucispTxBuffer[0] = 0x22;g_ucispTxBuffer[3] = 0x5a;g_ucispTxBuffer[4] = 0xa5;nOffset = 5;nPoint = 0;for(i = 0; i < nStep; i ++) {nStart = i * ISP_DOWNLOAD_PAGESIZE;nEnd = nStart + ISP_DOWNLOAD_PAGESIZE;if(nEnd > nSize) nEnd = nSize;nLength = nEnd - nStart;nDownloadAddress = nStartAddress + nStart;g_ucispTxBuffer[1] = HIBYTE(nDownloadAddress);g_ucispTxBuffer[2] = LOBYTE(nDownloadAddress);for(j = 0; j < nLength; j ++) {g_ucispTxBuffer[nOffset + j] = *(pucCode + nPoint);nPoint ++;        }nMS10 = (unsigned int)(GetClickMS() + ISP_DOWNLOAD_TIMEOUT);ispCommandSend(nLength + nOffset);for(;;) {ispProcChar();if(g_ucispReceiveFlag) {if(g_ucispRxBuffer[0] == 0x2 &&g_ucispRxBuffer[1] == 'T') break;return 1;                   }if(GetClickMS() == nMS10) return 2;}g_ucispTxBuffer[0] = 0x02;}return 0;}//==============================================================================
//                END OF THE FILE : STCISP.C
//------------------------------------------------------------------------------

使用单片机对STC8G,8H,8A进行ISP下载程序相关推荐

  1. arduino uno r3单片机封装图_【arduino】arduino ISP下载程序方法,用arduino uno给arduino nano下载程序...

    微信关注 "DLGG创客DIY"设为"星标",重磅干货,第一时间送达. 最近用arduino nano,老版的那种miniUSB的接口,得用miniUSB的数据 ...

  2. 【arduino】arduino ISP下载程序方法,用arduino uno给M5 Module DC MOTOR下载程序

    微信关注 "DLGG创客DIY" 设为"星标",重磅干货,第一时间送达. 今天用arduino uno给M5的Module DC motor下载程序,别的就不多 ...

  3. 【arduino】arduino ISP下载程序方法,用arduino uno给arduino nano下载程序

    微信关注 "DLGG创客DIY" 设为"星标",重磅干货,第一时间送达. 最近用arduino nano,老版的那种miniUSB的接口,得用miniUSB的数 ...

  4. LPC1758串口ISP下载程序

    最近手上拿到一块人家公司做的3D打印机的板子,用的核心芯片是LPC1758,板上引出了ISP下载接口.那接口共4个引出脚,如下图所示:   其中ME_EN引脚又连接到了芯片的P2[10]引脚,那个引脚 ...

  5. STM32 ISP 下载程序, C源码,

    鉴于flymcu下载时有点慢,flash_loader.exe容易卡死的原因,所以决定自己写个串口编程和控制台程序.然后写成bat文件,再整合到Visual studio的外部工具里,实现一键下载. ...

  6. 单片机重启或拔电依旧不能下载程序

    问题描述 51单片机第一次成功下载,但第二次下载的时候发现下载不了!资料上都说掉电下载可以让单片机从isp区启动,然我拔掉供电电源n次都不能下载! 原因分析: 资料上说的并没有错,掉电下载是可以让程序 ...

  7. STM32F103C6T6使用FLYMCU ISP下载程序注意事项

    前言:为什么要用STM32F103C6T6 因为它大哥C8T6太贵了,无他.无力吐槽糟糕的芯片狂涨价,两倍也就算了,TMD的8倍是什么意思,这是一个如此荒谬的时代. 第一步:准备USB转TTL USB ...

  8. STC51系列单片机不断电自动下载程序

    以前在进行单片机编程时比较烦恼的时每次下载程序都需要断电,点击下载,再上电才能将程序下载到单片机,如果偶尔一两次这样操作可以忍受,但是往往我们都是需要调试代码,多次进行下载操作,不断的断电上电无疑对单 ...

  9. stc单片机自动下载程序原理和代码实现

    1/stc单片机下载程序的原理 首先我们要理解stc单片机下载程序的原理.在stc单片机中有两个程序区:用户程序区和ISP监控程序区. 这是stc89c52单片机数据手册中的内容. 根据数据手册,我们 ...

最新文章

  1. Android studio Day02-1
  2. 0字符串 if mapper test_mybatis的if判断条件将字符串解析成了数字
  3. 自学python需要多长时间-零基础学习Python开发需要多长时间?
  4. reflow 和 repaint
  5. C#组件开发 -- 索引器
  6. IOS-百度地图API用点生成线路、导航、自定义标注 2013年11月更新
  7. 《Java程序设计》第五周学习总结
  8. C++ primer 第14章 操作重载与类型转换
  9. java 枚举迭代_Java中的枚举和迭代器之间的区别
  10. win7 java jna找不到_java – 资源路径中找不到JNA本机支持(/com/sun/jna/linux-arm/libjnidispatch.so)...
  11. CCNA2.0笔记_TCP/IP概述
  12. java接口深入理解_深入理解Java的接口和抽象类
  13. java实现在线预览word(docx)功能
  14. 关于Vmware workstation的软驱功能
  15. html 画excel表格边框,只需五分钟!用Excel做出美观的表格
  16. 饼状图显示以及出现问题处理
  17. Java多线程+IO流+网络编程+MySQL+JDBC编程实现多人联机版坦克大战
  18. qq手机邮箱服务器设置方法,手机qq邮箱imap设置图文教程
  19. Flask框架之模板继承与案例05
  20. 去处word红色波浪线

热门文章

  1. linux c++编写访问mysql程序,访问数据库出错,解决方法
  2. iOS开发火了九年,这些错误你还在犯嘛?
  3. [转载]去除文件中的^M
  4. element-ui upload组件上传图片时限制图片宽高
  5. Jenkins构建Docker容器
  6. 模拟Web 服务器磁盘满故障深入解析
  7. hdu1501 dp:两个字符串能否组成新串,状态表示能,不能。
  8. Redis中Value使用hash类型的效率是普通String的两倍
  9. Knockout 新版应用开发教程之visible绑定
  10. .NET项目修改文件夹