使用单片机对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波形来整流出高压( 2 V C ≈ 2 × 5 V ≈ 10 V 2V_C \approx 2 \times 5V \approx 10V 2VC≈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;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
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 :ms
STCISP_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 0
typedef 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 0x81
unsigned 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__
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
程序的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 communication
else 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,8H
nMS10 = (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 IC
WaitTime(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
//------------------------------------------------------------------------------
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
文章来源: zhuoqing.blog.csdn.net,作者:卓晴,版权归原作者所有,如需转载,请联系作者。
原文链接:zhuoqing.blog.csdn.net/article/details/105907433
- 点赞
- 收藏
- 关注作者
评论(0)