在Linux上快速搭建8051开发环境(2018-7-2)

0. 写在开始之前

实验操作系统环境: Ubuntu 16.04

编译器: sdcc

SDCC - Small Device C Compiler是一个开源的编译器,可以去官网查看它的详细信息。sdcc提供包括linux, Windows, Mac OS X的版本。

stcflash是一个开源python烧录脚本,可以非常好的支持STC系列的单片机,由于没有其他品牌的单片机所以无法保证所有51内核的单片机都可以使用。

因为这个脚本是python编写的所以windows需要安装python环境,而linux系统一般都自带python。Python版本必须高于2.6。

由于Python没有自带pySerial模块,但是烧录工具需要使用这个模块所以需要手动安装,在Ubuntu可以使用apt安装:

$ sudo apt-get install python-serial

1. 编译器安装

源码编译(可选)

若有兴趣,精力,时间可以选择源码编译安装,本咸鱼在此不多阐述。

下载二进制包

根据具体情况下载,64位linux系统可以下载Linux on AMD64 Sempron(amd64-unknown-linux2.5)

解压到合适的目录(/opt/)

解压到自己满意地方,我比较中意/opt目录:

$ sudo tar -xjvf sdcc-snapshot-amd64-unknown-linux2.5-20180701-10463.tar.bz2 -C /opt/

添加环境变量

如果不添加环境变量,每次编译器的时候都需要输入绝对路径比较麻烦。

修改~/.bashrc来添加环境变量:

$ echo "export PATH=/opt/sdcc/bin:$PATH" >> ~/.bashrc

!PATH中的路径应该是自己解压二进制包的地方。

刷新bash:

$ source ~/.bashrc

检查是否安装成功:

$ sdcc --version

SDCC : mcs51/z80/z180/r2k/r3ka/gbz80/tlcs90/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8 3.7.1 #10463 (Linux)

published under GNU General Public License (GPL)

如果有以上信息提示,则表明安装完成。

2. 编写测试代码

在/sdcc/share/sdcc/include/mcs51有很多定义好的头文件,我们使用8052.h可以满足一般的需要了。

8052.h

/*-------------------------------------------------------------------------

8052.h: Register Declarations for the Intel 8052 Processor

Copyright (C) 2000, Bela Torok / bela.torok@kssg.ch

This library is free software; you can redistribute it and/or modify it

under the terms of the GNU General Public License as published by the

Free Software Foundation; either version 2, or (at your option) any

later version.

This library is distributed in the hope that it will be useful,

but WITHOUT ANY WARRANTY; without even the implied warranty of

MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

GNU General Public License for more details.

You should have received a copy of the GNU General Public License

along with this library; see the file COPYING. If not, write to the

Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,

MA 02110-1301, USA.

As a special exception, if you link this library with other files,

some of which are compiled with SDCC, to produce an executable,

this library does not by itself cause the resulting executable to

be covered by the GNU General Public License. This exception does

not however invalidate any other reasons why the executable file

might be covered by the GNU General Public License.

-------------------------------------------------------------------------*/

#ifndef REG8052_H

#define REG8052_H

#include <8051.h> /* load definitions for the 8051 core */

#ifdef REG8051_H

#undef REG8051_H

#endif

/* define 8052 specific registers only */

/* T2CON */

__sfr __at (0xC8) T2CON ;

/* RCAP2 L & H */

__sfr __at (0xCA) RCAP2L ;

__sfr __at (0xCB) RCAP2H ;

__sfr __at (0xCC) TL2 ;

__sfr __at (0xCD) TH2 ;

/* IE */

__sbit __at (0xAD) ET2 ; /* Enable timer2 interrupt */

/* IP */

__sbit __at (0xBD) PT2 ; /* T2 interrupt priority bit */

/* T2CON bits */

__sbit __at (0xC8) T2CON_0 ;

__sbit __at (0xC9) T2CON_1 ;

__sbit __at (0xCA) T2CON_2 ;

__sbit __at (0xCB) T2CON_3 ;

__sbit __at (0xCC) T2CON_4 ;

__sbit __at (0xCD) T2CON_5 ;

__sbit __at (0xCE) T2CON_6 ;

__sbit __at (0xCF) T2CON_7 ;

__sbit __at (0xC8) CP_RL2 ;

__sbit __at (0xC9) C_T2 ;

__sbit __at (0xCA) TR2 ;

__sbit __at (0xCB) EXEN2 ;

__sbit __at (0xCC) TCLK ;

__sbit __at (0xCD) RCLK ;

__sbit __at (0xCE) EXF2 ;

__sbit __at (0xCF) TF2 ;

#endif

LED程序

我们可以编写自己的LED程序了。

在任意地方创建test目录并进入,然后创建main.c文件:

main.c

#include "8052.h"

#define LED P1_0

void main()

{

LED = 0; // or LED = 1

while (1) {

}

}

sdcc和keil编译器不同,所以定义的语法有些差别,在中断调用方面也有细微的差别,可以从官方文档了解具体信息。

编译

确保在test目录下:

$ sdcc main.c

$ ls

main.asm main.ihx main.lst main.mem main.rst

main.c main.lk main.map main.rel main.sym

编译完成后会生成很多文件,其中main.ihx是我们需要的。

3. 烧写程序

下载python脚本,并安装好依赖,

或者可以直接复制脚本代码。

在test目录下创建stcflash.py:

#!/usr/bin/env python

# stcflash Copyright (C) 2013 laborer (laborer@126.com)

# This program is free software: you can redistribute it and/or modify

# it under the terms of the GNU General Public License as published by

# the Free Software Foundation, either version 3 of the License, or

# (at your option) any later version.

# This program is distributed in the hope that it will be useful, but

# WITHOUT ANY WARRANTY; without even the implied warranty of

# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU

# General Public License for more details.

# You should have received a copy of the GNU General Public License

# along with this program. If not, see .

import time

import logging

import sys

import serial

import os.path

import binascii

import struct

import argparse

PROTOCOL_89 = "89"

PROTOCOL_12C5A = "12c5a"

PROTOCOL_12C52 = "12c52"

PROTOCOL_12Cx052 = "12cx052"

PROTOSET_89 = [PROTOCOL_89]

PROTOSET_12 = [PROTOCOL_12C5A, PROTOCOL_12C52, PROTOCOL_12Cx052]

PROTOSET_12B = [PROTOCOL_12C52, PROTOCOL_12Cx052]

PROTOSET_PARITY = [PROTOCOL_12C5A, PROTOCOL_12C52]

class Programmer:

def __init__(self, conn, protocol=None):

self.conn = conn

self.protocol = protocol

self.conn.timeout = 0.05

if self.protocol in PROTOSET_PARITY:

self.conn.parity = serial.PARITY_EVEN

else:

self.conn.parity = serial.PARITY_NONE

self.chkmode = 0

def __conn_read(self, size):

buf = bytearray()

while len(buf) < size:

s = bytearray(self.conn.read(size - len(buf)))

buf += s

logging.debug("recv: " + " ".join(["%02X" % i for i in s]))

if len(s) == 0:

raise IOError()

return list(buf)

def __conn_write(self, s):

logging.debug("send: " + " ".join(["%02X" % i for i in s]))

self.conn.write(bytearray(s))

def __conn_baudrate(self, baud, flush=True):

logging.debug("baud: %d" % baud)

if flush:

self.conn.flush()

time.sleep(0.2)

self.conn.baudrate = baud

def __model_database(self, model):

modelmap = {0xE0: ("12", 1, {(0x00, 0x1F): ("C54", ""),

(0x60, 0x7F): ("C54", "AD"),

(0x80, 0x9F): ("LE54", ""),

(0xE0, 0xFF): ("LE54", "AD"),

}),

0xE1: ("12", 1, {(0x00, 0x1F): ("C52", ""),

(0x20, 0x3F): ("C52", "PWM"),

(0x60, 0x7F): ("C52", "AD"),

(0x80, 0x9F): ("LE52", ""),

(0xA0, 0xBF): ("LE52", "PWM"),

(0xE0, 0xFF): ("LE52", "AD"),

}),

0xE2: ("11", 1, {(0x00, 0x1F): ("F", ""),

(0x20, 0x3F): ("F", "E"),

(0x70, 0x7F): ("F", ""),

(0x80, 0x9F): ("L", ""),

(0xA0, 0xBF): ("L", "E"),

(0xF0, 0xFF): ("L", ""),

}),

0xE6: ("12", 1, {(0x00, 0x1F): ("C56", ""),

(0x60, 0x7F): ("C56", "AD"),

(0x80, 0x9F): ("LE56", ""),

(0xE0, 0xFF): ("LE56", "AD"),

}),

0xD1: ("12", 2, {(0x20, 0x3F): ("C5A", "CCP"),

(0x40, 0x5F): ("C5A", "AD"),

(0x60, 0x7F): ("C5A", "S2"),

(0xA0, 0xBF): ("LE5A", "CCP"),

(0xC0, 0xDF): ("LE5A", "AD"),

(0xE0, 0xFF): ("LE5A", "S2"),

}),

0xD2: ("10", 1, {(0x00, 0x0F): ("F", ""),

(0x60, 0x6F): ("F", "XE"),

(0x70, 0x7F): ("F", "X"),

(0xA0, 0xAF): ("L", ""),

(0xE0, 0xEF): ("L", "XE"),

(0xF0, 0xFF): ("L", "X"),

}),

0xD3: ("11", 2, {(0x00, 0x1F): ("F", ""),

(0x40, 0x5F): ("F", "X"),

(0x60, 0x7F): ("F", "XE"),

(0xA0, 0xBF): ("L", ""),

(0xC0, 0xDF): ("L", "X"),

(0xE0, 0xFF): ("L", "XE"),

}),

0xF0: ("89", 4, {(0x00, 0x10): ("C5", "RC"),

(0x20, 0x30): ("C5", "RC"), #STC90C5xRC

}),

0xF1: ("89", 4, {(0x00, 0x10): ("C5", "RD+"),

(0x20, 0x30): ("C5", "RD+"), #STC90C5xRD+

}),

0xF2: ("12", 1, {(0x00, 0x0F): ("C", "052"),

(0x10, 0x1F): ("C", "052AD"),

(0x20, 0x2F): ("LE", "052"),

(0x30, 0x3F): ("LE", "052AD"),

}),

}

iapmcu = ((0xD1, 0x3F), (0xD1, 0x5F), (0xD1, 0x7F),

(0xD2, 0x7E), (0xD2, 0xFE),

(0xD3, 0x5F), (0xD3, 0xDF),

(0xE2, 0x76), (0xE2, 0xF6),

)

try:

model = tuple(model)

prefix, romratio, fixmap = modelmap[model[0]]

if model[0] in (0xF0, 0xF1) and 0x20 <= model[1] <= 0x30:

prefix = "90"

for key, value in fixmap.items():

if key[0] <= model[1] <= key[1]:

break

else:

raise KeyError()

infix, postfix = value

romsize = romratio * (model[1] - key[0])

try:

romsize = {(0xF0, 0x03): 13}[model]

except KeyError:

pass

if model[0] in (0xF0, 0xF1):

romfix = str(model[1] - key[0])

elif model[0] in (0xF2,):

romfix = str(romsize)

else:

romfix = "%02d" % romsize

name = "IAP" if model in iapmcu else "STC"

name += prefix + infix + romfix + postfix

return (name, romsize)

except KeyError:

return ("Unknown %02X %02X" % model, None)

def recv(self, timeout = 1, start = [0x46, 0xB9, 0x68]):

timeout += time.time()

while time.time() < timeout:

try:

if self.__conn_read(len(start)) == start:

break

except IOError:

continue

else:

logging.debug("recv(..): Timeout")

raise IOError()

chksum = start[-1]

s = self.__conn_read(2)

n = s[0] * 256 + s[1]

if n > 64:

logging.debug("recv(..): Incorrect packet size")

raise IOError()

chksum += sum(s)

s = self.__conn_read(n - 3)

if s[n - 4] != 0x16:

logging.debug("recv(..): Missing terminal symbol")

raise IOError()

chksum += sum(s[:-(1+self.chkmode)])

if self.chkmode > 0 and chksum & 0xFF != s[-2]:

logging.debug("recv(..): Incorrect checksum[0]")

raise IOError()

elif self.chkmode > 1 and (chksum >> 8) & 0xFF != s[-3]:

logging.debug("recv(..): Incorrect checksum[1]")

raise IOError()

return (s[0], s[1:-(1+self.chkmode)])

def send(self, cmd, dat):

buf = [0x46, 0xB9, 0x6A]

n = 1 + 2 + 1 + len(dat) + self.chkmode + 1

buf += [n >> 8, n & 0xFF, cmd]

buf += dat

chksum = sum(buf[2:])

if self.chkmode > 1:

buf += [(chksum >> 8) & 0xFF]

buf += [chksum & 0xFF, 0x16]

self.__conn_write(buf)

def detect(self):

for i in range(1000):

try:

self.__conn_write([0x7F, 0x7F])

cmd, dat = self.recv(0.015, [0x68])

break

except IOError:

pass

else:

raise IOError()

self.fosc = (float(sum(dat[0:16:2]) * 256 + sum(dat[1:16:2])) / 8

* self.conn.baudrate / 580974)

self.info = dat[16:]

self.version = "%d.%d%c" % (self.info[0] >> 4,

self.info[0] & 0x0F,

self.info[1])

self.model = self.info[3:5]

self.name, self.romsize = self.__model_database(self.model)

logging.info("Model ID: %02X %02X" % tuple(self.model))

logging.info("Model name: %s" % self.name)

logging.info("ROM size: %s" % self.romsize)

if self.protocol is None:

try:

self.protocol = {0xF0: PROTOCOL_89, #STC89/90C5xRC

0xF1: PROTOCOL_89, #STC89/90C5xRD+

0xF2: PROTOCOL_12Cx052, #STC12Cx052

0xD1: PROTOCOL_12C5A, #STC12C5Ax

0xD2: PROTOCOL_12C5A, #STC10Fx

0xE1: PROTOCOL_12C52, #STC12C52x

0xE2: PROTOCOL_12C5A, #STC11Fx

0xE6: PROTOCOL_12C52, #STC12C56x

}[self.model[0]]

except KeyError:

pass

if self.protocol in PROTOSET_PARITY:

self.chkmode = 2

self.conn.parity = serial.PARITY_EVEN

else:

self.chkmode = 1

self.conn.parity = serial.PARITY_NONE

if self.protocol is not None:

del self.info[-self.chkmode:]

logging.info("Protocol ID: %s" % self.protocol)

logging.info("Checksum mode: %d" % self.chkmode)

logging.info("UART Parity: %s"

% {serial.PARITY_NONE: "NONE",

serial.PARITY_EVEN: "EVEN",

}[self.conn.parity])

for i in range(0, len(self.info), 16):

logging.info("Info string [%d]: %s"

% (i // 16,

" ".join(["%02X" % j for j in self.info[i:i+16]])))

def print_info(self):

print(" FOSC: %.3fMHz" % self.fosc)

print(" Model: %s (ver%s) " % (self.name, self.version))

if self.romsize is not None:

print(" ROM: %dKB" % self.romsize)

if self.protocol == PROTOCOL_89:

switches = [( 2, 0x80, "Reset stops watchdog"),

( 2, 0x40, "Internal XRAM"),

( 2, 0x20, "Normal ALE pin"),

( 2, 0x10, "Full gain oscillator"),

( 2, 0x08, "Not erase data EEPROM"),

( 2, 0x04, "Download regardless of P1"),

( 2, 0x01, "12T mode")]

elif self.protocol == PROTOCOL_12C5A:

switches = [( 6, 0x40, "Disable reset2 low level detect"),

( 6, 0x01, "Reset pin not use as I/O port"),

( 7, 0x80, "Disable long power-on-reset latency"),

( 7, 0x40, "Oscillator high gain"),

( 7, 0x02, "External system clock source"),

( 8, 0x20, "WDT disable after power-on-reset"),

( 8, 0x04, "WDT count in idle mode"),

(10, 0x02, "Not erase data EEPROM"),

(10, 0x01, "Download regardless of P1")]

print(" WDT prescal: %d" % 2**((self.info[8] & 0x07) + 1))

elif self.protocol in PROTOSET_12B:

switches = [(8, 0x02, "Not erase data EEPROM")]

else:

switches = []

for pos, bit, desc in switches:

print(" [%c] %s" % ("X" if self.info[pos] & bit else " ", desc))

def handshake(self):

baud0 = self.conn.baudrate

for baud in [115200, 57600, 38400, 28800, 19200,

14400, 9600, 4800, 2400, 1200]:

t = self.fosc * 1000000 / baud / 32

if self.protocol not in PROTOSET_89:

t *= 2

if abs(round(t) - t) / t > 0.03:

continue

if self.protocol in PROTOSET_89:

tcfg = 0x10000 - int(t + 0.5)

else:

if t > 0xFF:

continue

tcfg = 0xC000 + 0x100 - int(t + 0.5)

baudstr = [tcfg >> 8,

tcfg & 0xFF,

0xFF - (tcfg >> 8),

min((256 - (tcfg & 0xFF)) * 2, 0xFE),

int(baud0 / 60)]

logging.info("Test baudrate %d (accuracy %0.4f) using config %s"

% (baud,

abs(round(t) - t) / t,

" ".join(["%02X" % i for i in baudstr])))

if self.protocol in PROTOSET_89:

freqlist = (40, 20, 10, 5)

else:

freqlist = (30, 24, 20, 12, 6, 3, 2, 1)

for twait in range(0, len(freqlist)):

if self.fosc > freqlist[twait]:

break

logging.info("Waiting time config %02X" % (0x80 + twait))

self.send(0x8F, baudstr + [0x80 + twait])

try:

self.__conn_baudrate(baud)

cmd, dat = self.recv()

break

except Exception:

logging.info("Cannot use baudrate %d" % baud)

time.sleep(0.2)

self.conn.flushInput()

finally:

self.__conn_baudrate(baud0, False)

else:

raise IOError()

logging.info("Change baudrate to %d" % baud)

self.send(0x8E, baudstr)

self.__conn_baudrate(baud)

self.baudrate = baud

cmd, dat = self.recv()

def erase(self):

if self.protocol in PROTOSET_89:

self.send(0x84, [0x01, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33])

cmd, dat = self.recv(10)

assert cmd == 0x80

else:

self.send(0x84, ([0x00, 0x00, self.romsize * 4,

0x00, 0x00, self.romsize * 4]

+ [0x00] * 12

+ [i for i in range(0x80, 0x0D, -1)]))

cmd, dat = self.recv(10)

if dat:

logging.info("Serial number: "

+ " ".join(["%02X" % j for j in dat]))

def flash(self, code):

code = list(code) + [0x00] * (511 - (len(code) - 1) % 512)

for i in range(0, len(code), 128):

logging.info("Flash code region (%04X, %04X)" % (i, i + 127))

addr = [0, 0, i >> 8, i & 0xFF, 0, 128]

self.send(0x00, addr + code[i:i+128])

cmd, dat = self.recv()

assert dat[0] == sum(code[i:i+128]) % 256

yield (i + 128.0) / len(code)

def options(self, **kwargs):

erase_eeprom = kwargs.get("erase_eeprom", None)

dat = []

fosc = list(bytearray(struct.pack(">I", int(self.fosc * 1000000))))

if self.protocol == PROTOCOL_89:

if erase_eeprom is not None:

self.info[2] &= 0xF7

self.info[2] |= 0x00 if erase_eeprom else 0x08

dat = self.info[2:3] + [0xFF]*3

elif self.protocol == PROTOCOL_12C5A:

if erase_eeprom is not None:

self.info[10] &= 0xFD

self.info[10] |= 0x00 if erase_eeprom else 0x02

dat = (self.info[6:9] + [0xFF]*5 + self.info[10:11]

+ [0xFF]*6 + fosc)

elif self.protocol in PROTOSET_12B:

if erase_eeprom is not None:

self.info[8] &= 0xFD

self.info[8] |= 0x00 if erase_eeprom else 0x02

dat = (self.info[6:11] + fosc + self.info[12:16] + [0xFF]*4

+ self.info[8:9] + [0xFF]*7 + fosc + [0xFF]*3)

elif erase_eeprom is not None:

logging.info("Modifying options is not supported for this target")

return False

if dat:

self.send(0x8D, dat)

cmd, dat = self.recv()

return True

def terminate(self):

logging.info("Send termination command")

self.send(0x82, [])

self.conn.flush()

time.sleep(0.2)

def unknown_packet_1(self):

if self.protocol in PROTOSET_PARITY:

logging.info("Send unknown packet (50 00 00 36 01 ...)")

self.send(0x50, [0x00, 0x00, 0x36, 0x01] + self.model)

cmd, dat = self.recv()

assert cmd == 0x8F and not dat

def unknown_packet_2(self):

if self.protocol not in PROTOSET_PARITY:

for i in range(5):

logging.info("Send unknown packet (80 00 00 36 01 ...)")

self.send(0x80, [0x00, 0x00, 0x36, 0x01] + self.model)

cmd, dat = self.recv()

assert cmd == 0x80 and not dat

def unknown_packet_3(self):

if self.protocol in PROTOSET_PARITY:

logging.info("Send unknown packet (69 00 00 36 01 ...)")

self.send(0x69, [0x00, 0x00, 0x36, 0x01] + self.model)

cmd, dat = self.recv()

assert cmd == 0x8D and not dat

def autoisp(conn, baud, magic):

if not magic:

return

bak = conn.baudrate

conn.baudrate = baud

conn.write(bytearray(ord(i) for i in magic))

conn.flush()

time.sleep(0.5)

conn.baudrate = bak

def program(prog, code, erase_eeprom=None):

sys.stdout.write("Detecting target...")

sys.stdout.flush()

prog.detect()

print(" done")

prog.print_info()

if prog.protocol is None:

raise IOError("Unsupported target")

if code is None:

return

prog.unknown_packet_1()

sys.stdout.write("Baudrate: ")

sys.stdout.flush()

prog.handshake()

print(prog.baudrate)

prog.unknown_packet_2()

sys.stdout.write("Erasing target...")

sys.stdout.flush()

prog.erase()

print(" done")

print("Size of the binary: %d" % len(code))

# print("Programming: ", end="", flush=True)

sys.stdout.write("Programming: ")

sys.stdout.flush()

oldbar = 0

for progress in prog.flash(code):

bar = int(progress * 20)

sys.stdout.write("#" * (bar - oldbar))

sys.stdout.flush()

oldbar = bar

print(" done")

prog.unknown_packet_3()

sys.stdout.write("Setting options...")

sys.stdout.flush()

if prog.options(erase_eeprom=erase_eeprom):

print(" done")

else:

print(" failed")

prog.terminate()

# Convert Intel HEX code to binary format

def hex2bin(code):

buf = bytearray()

base = 0

line = 0

for rec in code.splitlines():

# Calculate the line number of the current record

line += 1

try:

# bytes(...) is to support python<=2.6

# bytearray(...) is to support python<=2.7

n = bytearray(binascii.a2b_hex(bytes(rec[1:3])))[0]

dat = bytearray(binascii.a2b_hex(bytes(rec[1:n*2+11])))

except:

raise Exception("Line %d: Invalid format" % line)

if rec[0] != ord(":"):

raise Exception("Line %d: Missing start code \":\"" % line)

if sum(dat) & 0xFF != 0:

raise Exception("Line %d: Incorrect checksum" % line)

if dat[3] == 0: # Data record

addr = base + (dat[1] << 8) + dat[2]

# Allocate memory space and fill it with 0xFF

buf[len(buf):] = [0xFF] * (addr + n - len(buf))

# Copy data to the buffer

buf[addr:addr+n] = dat[4:-1]

elif dat[3] == 1: # EOF record

if n != 0:

raise Exception("Line %d: Incorrect data length" % line)

elif dat[3] == 2: # Extended segment address record

if n != 2:

raise Exception("Line %d: Incorrect data length" % line)

base = ((dat[4] << 8) + dat[5]) << 4

elif dat[3] == 4: # Extended linear address record

if n != 2:

raise Exception("Line %d: Incorrect data length" % line)

base = ((dat[4] << 8) + dat[5]) << 16

else:

raise Exception("Line %d: Unsupported record type" % line)

return buf

def main():

if sys.platform == "win32":

port = "COM3"

elif sys.platform == "darwin":

port = "/dev/tty.usbserial"

else:

port = "/dev/ttyUSB0"

parser = argparse.ArgumentParser(

description=("Stcflash, a command line programmer for "

+ "STC 8051 microcontroller.\n"

+ "https://github.com/laborer/stcflash"))

parser.add_argument("image",

help="code image (bin/hex)",

type=argparse.FileType("rb"), nargs='?')

parser.add_argument("-p", "--port",

help="serial port device (default: %s)" % port,

default=port)

parser.add_argument("-l", "--lowbaud",

help="initial baud rate (default: 2400)",

type=int,

default=2400)

parser.add_argument("-r", "--protocol",

help="protocol to use for programming",

choices=["89", "12c5a", "12c52", "12cx052", "auto"],

default="auto")

parser.add_argument("-a", "--aispbaud",

help="baud rate for AutoISP (default: 4800)",

type=int,

default=4800)

parser.add_argument("-m", "--aispmagic",

help="magic word for AutoISP")

parser.add_argument("-v", "--verbose",

help="be verbose",

default=0,

action="count")

parser.add_argument("-e", "--erase_eeprom",

help=("erase data eeprom during next download"

+"(experimental)"),

action="store_true")

parser.add_argument("-ne", "--not_erase_eeprom",

help=("do not erase data eeprom next download"

+"(experimental)"),

action="store_true")

opts = parser.parse_args()

opts.loglevel = (logging.CRITICAL,

logging.INFO,

logging.DEBUG)[min(2, opts.verbose)]

opts.protocol = {'89': PROTOCOL_89,

'12c5a': PROTOCOL_12C5A,

'12c52': PROTOCOL_12C52,

'12cx052': PROTOCOL_12Cx052,

'auto': None}[opts.protocol]

if not opts.erase_eeprom and not opts.not_erase_eeprom:

opts.erase_eeprom = None

logging.basicConfig(format=("%(levelname)s: "

+ "[%(relativeCreated)d] "

+ "%(message)s"),

level=opts.loglevel)

if opts.image:

code = bytearray(opts.image.read())

opts.image.close()

if os.path.splitext(opts.image.name)[1] in (".hex", ".ihx"):

code = hex2bin(code)

else:

code = None

print("Connect to %s at baudrate %d" % (opts.port, opts.lowbaud))

with serial.Serial(port=opts.port,

baudrate=opts.lowbaud,

parity=serial.PARITY_NONE) as conn:

if opts.aispmagic:

autoisp(conn, opts.aispbaud, opts.aispmagic)

program(Programmer(conn, opts.protocol), code, opts.erase_eeprom)

if __name__ == "__main__":

main()

生成hex文件

$ packihx main.ihx > main.hex

packihx: read 12 lines, wrote 14: OK.

$ ls main.hex

main.hex

烧录

$ python stcflash.py main.hex

4. 多个源文件编译

不想往下写了,最后一次写51的程序,以后再也不会碰了!!!

linux开发 stc_在Linux上快速搭建8051开发环境相关推荐

  1. linux hudson svn,Hudson Maven SVN快速搭建持续集成环境

    Maven 跨平台的项目管理工具 Apache组织中颇为成功的开源项目 服务于Java平台的项目构建,依赖管理和项目信息管理 持续集成 快速 高频率 自动 构建 所有源码 反馈 目前最流行的开源持续集 ...

  2. Windows7/10上快速搭建Tesseract-OCR开发环境操作步骤

    之前在https://blog.csdn.net/fengbingchun/article/details/51628957 中描述过如何在Windows上搭建Tesseract-OCR开发环境,那时 ...

  3. linux stm32 ide,一文教你如何在ubuntu上快速搭建STM32 CubeIDE环境(图文超详细+文末有附件)...

    在快速ubuntu上安装cubeide你值得拥有:适合对linux系统还不是很熟悉的同学: 1 下载 cubeide 登陆官网,下载链接不知道是否有效,如果无效,需要提交自己的邮箱地址,ST官方会将下 ...

  4. Linux上快速搭建Jenkins服务器 实现持续集成开发

    http://my.oschina.net/long0419/blog/183299 简介: 持续集成是一种软件开发实践,对于提高软件开发效率并保障软件开发质量提供了理论基础.Jenkins 是一个开 ...

  5. linux下测试个人主页,一键建站集成软件包,Linux上快速搭建测试个人网站

    原标题:一键建站集成软件包,Linux上快速搭建测试个人网站 来自:Linux迷 https://www.linuxmi.com/ubuntu-20-0-linux-xampp.html 在Ubunt ...

  6. linux的建站安装包,一键建站集成软件包,Linux上快速搭建测试个人网站

    原标题:一键建站集成软件包,Linux上快速搭建测试个人网站 来自:Linux迷 https://www.linuxmi.com/ubuntu-20-0-linux-xampp.html 在Ubunt ...

  7. 【腾讯云 Finops Crane 集训营】 如何在Windows上快速搭建一个Kubernetes+Crane 环境及应用

    一.前言 个人主页: ζ小菜鸡 大家好我是ζ小菜鸡,让我们一起学习在 Windows 如何快速搭建一个Kubernetes+Crane 环境及应用. 如果文章对你有帮助.欢迎关注.点赞.收藏(一键三连 ...

  8. SpringMVC学习(二)——快速搭建SpringMVC开发环境(注解方式)

    文章目录 说明 1.工程搭建 2.注解配置 2.1.context:annotation-config说明 2.2.context:component-scan配置说明 2.3.mvc:annotat ...

  9. mybatis注解开发_快速搭建MyBatis开发环境(配置版+注解版)

    下面我们搭建一下MyBaits的开发环境,也就是一个用MyBaits框架访问数据库的例子. 1.项目结构如下 这里搭建的是一个maven项目. 2.引入依赖pom.xml 4.0.0com.suibi ...

最新文章

  1. 无预测 不零售 | SAP统一需求预测平台
  2. 不用任何软件,让电脑不中***
  3. bd3.2 Python高级
  4. 什么是用户与计算机硬件之间的桥梁,计算机应用基础简答题(附答案)
  5. java项目怎样提高性能_Java程序员成长之路(如何提高Java程序性能?)
  6. 条件注释判断浏览器版本!--[if lt IE 9](转载)
  7. 牛客网 【每日一题】5月11日题目精讲 Moovie Mooving
  8. Android 多线程实现异步执行demo,线程池使用demo
  9. java 平均分配算法_java 分配算法
  10. Kafka Streams简介: 让流处理变得更简单
  11. sql返回刚添加的数据的自增id
  12. DBCP,C3P0,druid,HiKariCP连接池配置使用
  13. Spring(三)之自动装配、表达式
  14. 使用spring的JdbcTemplate进行查询的三种回调方式的比较
  15. MapReduce 规划 系列十 采用HashPartitioner调整Reducer计算负荷
  16. html加载gif动画效果,html – 使用CSS动画加载图像VS使用GIF图像加载
  17. 【JavaScript】运算符及其优先级
  18. 3D线激光成像数学模型简析
  19. 【李沐精读GNN论文总结】A Gentle Introduction to Graph Neural Networks
  20. 系统无忧 Ghost XP SP3 快速装机版V2011.07

热门文章

  1. easypr解析(六)
  2. 总结MySQL和Oracle的语法区别
  3. 成为数据分析师所需的数据分析技能
  4. kitti数据集链接
  5. 【CUDA】学习笔记(1)JetsonNano+Ubuntu+Eclipse
  6. 趋势▍ NLP将迎来黄金十年
  7. 计算机网络基础3--TCP/IP协议栈
  8. error in include chain(stm32f10x.h)
  9. html大马源码,php大马源码:【百家号】脸书百科,分析 PHP大马-php_mof SHELL Web程序...
  10. 使用IDEA打包项目并在tomcat上运行