使用单片机对STC8G,8H,8A进行ISP下载程序
通过第三方程序实现对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下载程序相关推荐
- arduino uno r3单片机封装图_【arduino】arduino ISP下载程序方法,用arduino uno给arduino nano下载程序...
微信关注 "DLGG创客DIY"设为"星标",重磅干货,第一时间送达. 最近用arduino nano,老版的那种miniUSB的接口,得用miniUSB的数据 ...
- 【arduino】arduino ISP下载程序方法,用arduino uno给M5 Module DC MOTOR下载程序
微信关注 "DLGG创客DIY" 设为"星标",重磅干货,第一时间送达. 今天用arduino uno给M5的Module DC motor下载程序,别的就不多 ...
- 【arduino】arduino ISP下载程序方法,用arduino uno给arduino nano下载程序
微信关注 "DLGG创客DIY" 设为"星标",重磅干货,第一时间送达. 最近用arduino nano,老版的那种miniUSB的接口,得用miniUSB的数 ...
- LPC1758串口ISP下载程序
最近手上拿到一块人家公司做的3D打印机的板子,用的核心芯片是LPC1758,板上引出了ISP下载接口.那接口共4个引出脚,如下图所示: 其中ME_EN引脚又连接到了芯片的P2[10]引脚,那个引脚 ...
- STM32 ISP 下载程序, C源码,
鉴于flymcu下载时有点慢,flash_loader.exe容易卡死的原因,所以决定自己写个串口编程和控制台程序.然后写成bat文件,再整合到Visual studio的外部工具里,实现一键下载. ...
- 单片机重启或拔电依旧不能下载程序
问题描述 51单片机第一次成功下载,但第二次下载的时候发现下载不了!资料上都说掉电下载可以让单片机从isp区启动,然我拔掉供电电源n次都不能下载! 原因分析: 资料上说的并没有错,掉电下载是可以让程序 ...
- STM32F103C6T6使用FLYMCU ISP下载程序注意事项
前言:为什么要用STM32F103C6T6 因为它大哥C8T6太贵了,无他.无力吐槽糟糕的芯片狂涨价,两倍也就算了,TMD的8倍是什么意思,这是一个如此荒谬的时代. 第一步:准备USB转TTL USB ...
- STC51系列单片机不断电自动下载程序
以前在进行单片机编程时比较烦恼的时每次下载程序都需要断电,点击下载,再上电才能将程序下载到单片机,如果偶尔一两次这样操作可以忍受,但是往往我们都是需要调试代码,多次进行下载操作,不断的断电上电无疑对单 ...
- stc单片机自动下载程序原理和代码实现
1/stc单片机下载程序的原理 首先我们要理解stc单片机下载程序的原理.在stc单片机中有两个程序区:用户程序区和ISP监控程序区. 这是stc89c52单片机数据手册中的内容. 根据数据手册,我们 ...
最新文章
- Android studio Day02-1
- 0字符串 if mapper test_mybatis的if判断条件将字符串解析成了数字
- 自学python需要多长时间-零基础学习Python开发需要多长时间?
- reflow 和 repaint
- C#组件开发 -- 索引器
- IOS-百度地图API用点生成线路、导航、自定义标注 2013年11月更新
- 《Java程序设计》第五周学习总结
- C++ primer 第14章 操作重载与类型转换
- java 枚举迭代_Java中的枚举和迭代器之间的区别
- win7 java jna找不到_java – 资源路径中找不到JNA本机支持(/com/sun/jna/linux-arm/libjnidispatch.so)...
- CCNA2.0笔记_TCP/IP概述
- java接口深入理解_深入理解Java的接口和抽象类
- java实现在线预览word(docx)功能
- 关于Vmware workstation的软驱功能
- html 画excel表格边框,只需五分钟!用Excel做出美观的表格
- 饼状图显示以及出现问题处理
- Java多线程+IO流+网络编程+MySQL+JDBC编程实现多人联机版坦克大战
- qq手机邮箱服务器设置方法,手机qq邮箱imap设置图文教程
- Flask框架之模板继承与案例05
- 去处word红色波浪线