這學期有51單片機課程,平時除錯代碼不用windows,查閱了一些資料,不太能用,現在將51單片機在ubuntu下(Linux通用)開發和下載說明一下:需要用到SDCC和stcgal,
已測驗Linux通用,Ubuntu16.04,18.04.20.04均可,
資源下載:https://download.csdn.net/download/ZhangRelay/12820423
什么是SDCC?
SDCC是可重定目標的,優化的標準C(ANSI C89,ISO C99,ISO C11)編譯器套件,針對的是基于Intel MCS51的微處理器(8031、8032、8051、8052 等), Maxim(以前為Dallas),DS80C390, 飛思卡爾(以前基于Motorola)基于HC08 (hc08,s08), 基于Zilog Z80的MCU (z80,z180,gbz80,Rabbit 2000/3000,Rabbit 3000A,TLCS-90),Padauk(pdk14,pdk15)和 STMicroelectronics STM8,支持Padauk(pdk13),Microchip PIC16和PIC18 目標的作業正在進行中 ,可以將其重新定位為其他微處理器,
SDCC套件是從具有不同FOSS許可證的不同來源派生的幾個組件的集合,SDCC編譯器套件包括:
- SDAS和sdld,一個retargettable匯編程式和連接,基于ASXXXX,由Alan鮑德溫寫入; (GPL),
- sdcpp 前處理器,基于GCC cpp ; (GPL),
- ucsim 模擬器,最初由Daniel Drotos撰寫;(GPL),
- sdcdb 源代碼級除錯器,最初由Sandeep Dutta撰寫;(GPL),
- sdbinutils 庫歸檔實用程式,包括從GNU Binutils派生的sdar,sdranlib和sdnm;(GPL)
- SDCC運行時庫;(GPL + LE),Pic設備庫和頭檔案來自Microchip頭檔案(.inc)和鏈接程式腳本(.lkr)檔案,Microchip要求“頭檔案應宣告它們僅可與可靠的Microchip設備一起使用”,這使它們與GPL不兼容,
- gcc-test 回歸測驗,源自 gcc-testsuite;(未明確指定許可,但由于它是GCC的一部分,因此可能是GPL許可)
- packihx ; (公共區域)
- makebin ; (zlib / libpng許可證)
- sdcc C編譯器,最初由Sandeep Dutta撰寫;(GPL),一些功能包括:
- 廣泛的MCU特定語言擴展,可有效利用基礎硬體,
- 一系列標準優化,例如全域子運算式消除,回圈優化(回圈不變式,歸納變數的強度降低和回圈反轉),恒定折疊和傳播,復制傳播,死代碼消除以及“ switch”陳述句的跳轉表,
- MCU特定的優化,包括全域暫存器分配器,
- 適用于MCU的自適應后端,應該非常適合其他8位MCU
- 基于獨立規則的窺視孔優化器,
- 完整的資料型別范圍:char(8位,1位元組),short(16位,2位元組), int(16位,2位元組),long(32位,4位元組),long long(64位,8位元組),浮點數(IEEE 4位元組)和 _Bool / bool,
- 在函式中任何地方添加行內匯編代碼的能力,
- 報告功能復雜性的能力,以幫助確定應在匯編器中重寫的內容,
- 很好的自動回歸測驗選擇,
SDCC最初由Sandeep Dutta撰寫,并根據GPL許可發布,自最初發布以來,已經進行了許多錯誤修復和改進,自1999年12月起,代碼已移至SourceForge,所有“用戶都變成開發者”都可以訪問同一源樹,SDCC會不斷更新所有用戶和開發人員的輸入,
安裝
簡要介紹一下吧:
解壓sdcc壓縮檔案(這里使用最新4.0.0版本),全部檔案在sdcc-4.0.0/share/sdcc/doc,
cd sdcc-4.0.0
cp -r * /usr/local

編譯
sdcc -mmcs51 xxx.c
最簡單安裝方法:
sudo apt install sdcc
stcgal-STC MCU ISP閃存工具
stcgal是用于STC MCU Ltd的命令列閃存編程工具,8051兼容的微控制器,
STC微控制器具有基于UART/USB的引導加載程式(BSL),它利用基于資料包的協議通過串行鏈路重繪代碼存盤器和IAP存盤器,這稱為系統內編程(ISP),BSL還用于配置各種(類似保險絲的)設備選項,不幸的是,該協議沒有公開記錄,STC僅提供(粗略的)Windows GUI應用程式進行編程,
stcgal是STC的Windows軟體的功能全面的開源替代品;它支持多種MCU,非常便攜,適合自動化,
特征
- 支持STC 89/90/10/11/12/15/8系列
- UART和USB BSL支持
- 顯示零件資訊
- 確定作業頻率
- 程式閃存
- 程式IAP / EEPROM
- 設定設備選項
- 讀取唯一的設備ID(STC 10/11/12/15/8)
- 修整RC振蕩器頻率(STC 15/8)
- 使用DTR切換鍵或自定義Shell命令自動重啟電源
- 自動UART協議檢測
快速開始
安裝stcgal(可能需要root /管理員權限):
pip3 install stcgal
Collecting stcgal
Downloading https://files.pythonhosted.org/packages/b0/68/4924bd584b9e47639b28a1900cbced4e90deac7905fd996108ee2fcf975c/stcgal-1.6-py3-none-any.whl
Collecting tqdm>=4.0.0 (from stcgal)
Downloading https://files.pythonhosted.org/packages/28/7e/281edb5bc3274dfb894d90f4dbacfceaca381c2435ec6187a2c6f329aed7/tqdm-4.48.2-py2.py3-none-any.whl (68kB)
100% |████████████████████████████████| 71kB 754kB/s
Collecting pyserial>=3.0 (from stcgal)
Using cached https://files.pythonhosted.org/packages/0d/e4/2a744dd9e3be04a0c0907414e2a01a7c88bb3915cbe3c8cc06e209f59c30/pyserial-3.4-py2.py3-none-any.whl
Installing collected packages: tqdm, pyserial, stcgal
Successfully installed pyserial-3.4 stcgal-1.6 tqdm-4.48.2
如果網路問題,請嘗試如下命令:
pip3 install stcgal -i http://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.com

呼叫stcgal并顯示用法:
stcgal -h
usage: stcgal [-h] [-a] [-r RESETCMD]
[-P {stc89,stc12a,stc12b,stc12,stc15a,stc15,stc8,usb15,auto}]
[-p PORT] [-b BAUD] [-l HANDSHAKE] [-o OPTION] [-t TRIM] [-D]
[-V]
[code_image] [eeprom_image]
stcgal 1.6 - an STC MCU ISP flash tool
(C) 2014-2018 Grigori Goronzy and others
https://github.com/grigorig/stcgal
positional arguments:
code_image code segment file to flash (BIN/HEX)
eeprom_image eeprom segment file to flash (BIN/HEX)
optional arguments:
-h, --help show this help message and exit
-a, --autoreset cycle power automatically by asserting DTR
-r RESETCMD, --resetcmd RESETCMD
shell command for board power-cycling (instead of DTR
assertion)
-P {stc89,stc12a,stc12b,stc12,stc15a,stc15,stc8,usb15,auto}, --protocol {stc89,stc12a,stc12b,stc12,stc15a,stc15,stc8,usb15,auto}
protocol version (default: auto)
-p PORT, --port PORT serial port device
-b BAUD, --baud BAUD transfer baud rate (default: 19200)
-l HANDSHAKE, --handshake HANDSHAKE
handshake baud rate (default: 2400)
-o OPTION, --option OPTION
set option (can be used multiple times, see
documentation)
-t TRIM, --trim TRIM RC oscillator frequency in kHz (STC15+ series only)
-D, --debug enable debug output
-V, --version print version info and exit
stcgal -P stc89 xxx.ihx
程式需要做一些修改的,以LED燈為例吧:
#include <reg52.h> //52系列單片機頭檔案
sbit LSA = P1^5; //LED位選譯碼地址引腳A
sbit LSB = P1^6; //LED位選譯碼地址引腳B
sbit LSC = P1^7; //LED位選譯碼地址引腳C
int main(void)
{
while(1) //主程式中設定死回圈程式,保證周而復始運行
{
//使LED燈的總開關三極管Q6導通,+5V加到LED燈組
LSA = 0;
LSB = 0;
LSC = 0;
P0 = 0xfe; //點亮一個發光二極管
}
}
在sdcc下需修改為:
#include <8052.h>
#define LSA P1_5
#define LSB P1_6
#define LSC P1_7
int main(void)
{
while(1)
{
LSA = 0;
LSB = 0;
LSC = 0;
P0 = 0xfe;
}
}
Linux下無需安裝驅動!!!
sdcc -mmcs51 led.c
stcgal -P stc89 led.ihx

閃爍:
#include <8052.h>
#define LSA P1_5 //LED位選譯碼地址引腳A
#define LSB P1_6 //LED位選譯碼地址引腳B
#define LSC P1_7 //LED位選譯碼地址引腳C
#define Led10 P0_7 //定義P0.7名字為led10
int main(void)
{
unsigned int a; //定義無符號的整型變數a
while(1)
{
//使LED燈的總開關三極管Q6導通,+5V加到LED燈組
LSA = 0;
LSB = 0;
LSC = 0;
Led10 = 0; //點亮LED10
a = 50000;
while(a--); //50000次的回圈,通過消耗時間以達到延時的目的
Led10 = 1;; //熄滅LED10
a = 50000;
while(a--); //延時
}
}
呼吸燈:
#include <8052.h>
#define LSA P1_5 //LED位選譯碼地址引腳A
#define LSB P1_6 //LED位選譯碼地址引腳B
#define LSC P1_7 //LED位選譯碼地址引腳C
#define Led10 P0_7 //定義P0.7名字為led10
int atime=64;
void delay(unsigned int pms) //延時函式
{
unsigned int x;
unsigned int y;
for(x=pms;x>0;x--)
for(y=11;y>0;y--)
;
}
void ledfade(unsigned int i) //呼吸燈
{
Led10 = 0;
delay(i);
Led10 = 1;
delay(atime-i);
}
int main(void)
{
int a; //定義無符號的整型變數a
while(1)
{
//使LED燈的總開關三極管Q6導通,+5V加到LED燈組
LSA = 0;
LSB = 0;
LSC = 0;
for(a=0;a<atime;a++)
{
ledfade(a);
}
for(a=atime;a>0;a--)
{
ledfade(a);
}
}
}
呼吸跑馬燈???(需改進優化哦!)
#include <8052.h>
#define LSA P1_5 //LED位選譯碼地址引腳A
#define LSB P1_6 //LED位選譯碼地址引腳B
#define LSC P1_7 //LED位選譯碼地址引腳C
#define Led10 P0_0 //定義P0.0名字為led10
#define Led11 P0_1 //定義P0.0名字為led11
#define Led12 P0_2 //定義P0.0名字為led12
#define Led13 P0_3 //定義P0.0名字為led13
#define Led14 P0_4 //定義P0.0名字為led14
#define Led15 P0_5 //定義P0.0名字為led15
#define Led16 P0_6 //定義P0.0名字為led16
#define Led17 P0_7 //定義P0.0名字為led17
int atime=64;
void delay(unsigned int pms) //延時函式
{
unsigned int x;
unsigned int y;
for(x=pms;x>0;x--)
for(y=11;y>0;y--)
;
}
void ledfade0(unsigned int i) //呼吸燈
{
Led10 = 0;
delay(i);
Led10 = 1;
delay(atime-i);
}
void ledfade1(unsigned int i) //呼吸燈
{
Led11 = 0;
delay(i);
Led11 = 1;
delay(atime-i);
}
void ledfade2(unsigned int i) //呼吸燈
{
Led12 = 0;
delay(i);
Led12 = 1;
delay(atime-i);
}
void ledfade3(unsigned int i) //呼吸燈
{
Led13 = 0;
delay(i);
Led13 = 1;
delay(atime-i);
}
void ledfade4(unsigned int i) //呼吸燈
{
Led14 = 0;
delay(i);
Led14 = 1;
delay(atime-i);
}
void ledfade5(unsigned int i) //呼吸燈
{
Led15 = 0;
delay(i);
Led15 = 1;
delay(atime-i);
}
void ledfade6(unsigned int i) //呼吸燈
{
Led16 = 0;
delay(i);
Led16 = 1;
delay(atime-i);
}
void ledfade7(unsigned int i) //呼吸燈
{
Led17 = 0;
delay(i);
Led17 = 1;
delay(atime-i);
}
int main(void)
{
int a; //定義無符號的整型變數a
while(1)
{
//使LED燈的總開關三極管Q6導通,+5V加到LED燈組
LSA = 0;
LSB = 0;
LSC = 0;
for(a=0;a<atime;a++)
{
ledfade0(a);
}
for(a=atime;a>0;a--)
{
ledfade0(a);
}
for(a=0;a<atime;a++)
{
ledfade1(a);
}
for(a=atime;a>0;a--)
{
ledfade1(a);
}
for(a=0;a<atime;a++)
{
ledfade2(a);
}
for(a=atime;a>0;a--)
{
ledfade2(a);
}
for(a=0;a<atime;a++)
{
ledfade3(a);
}
for(a=atime;a>0;a--)
{
ledfade3(a);
}
for(a=0;a<atime;a++)
{
ledfade4(a);
}
for(a=atime;a>0;a--)
{
ledfade4(a);
}
for(a=0;a<atime;a++)
{
ledfade5(a);
}
for(a=atime;a>0;a--)
{
ledfade5(a);
}
for(a=0;a<atime;a++)
{
ledfade6(a);
}
for(a=atime;a>0;a--)
{
ledfade6(a);
}
for(a=0;a<atime;a++)
{
ledfade7(a);
}
for(a=atime;a>0;a--)
{
ledfade7(a);
}
}
}
如果需要將51接入機器人作業系統ROS,可以參考:
- http://wjwwood.io/serial/
CSDN認證博客專家
不合格高校講師
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/1586.html
標籤:其他
