零基础 Ubuntu 20.04.01 下搭建51单片机开发环境[开源编译器SDCC]

这篇具有很好参考价值的文章主要介绍了零基础 Ubuntu 20.04.01 下搭建51单片机开发环境[开源编译器SDCC]。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

原创首发于CSDN,转载请注明出处,谢谢!



为何会在Linux下开发单片机

个人初步学习51单片机的时,所能接触到的教程基本都是在Windows环境下使用Keil开发。诚然,Keil确实是一款强大的开发软件,但博主个人受限于以下因素:

  • 个人使用的是苹果电脑 MacBook Air;
  • 所装的VM虚拟机里已经安装了 Ubuntu 20.04.01。

加之其他琐碎的原因,博主终是走上了适配在Linux环境下的开源编译器SDCC来开发单片机这条路【不止是现在的C51单片机,还有以后的STM32,统一在Linux环境下进行开发 】。其实两者在抛开系统环境、编译软件的差异,大体上都是一样的:①【SDCC、Keil】编译生成hex文件;②【stcgal、stc-isp】启动烧录软件烧录程序。

在Ubuntu系统下搭建51单片机开发环境全过程里,出乎预料的反而是察觉了个人对于Linux系统的 文件架构软硬链接软链接的“漂移”环境变量 等几个方面的认识不足,惹出了几个无厘头的“bug”。 故才有了“参考资料”一节内那几篇环境变量、系统变量的博文,对于这几个主题的研究,以后也会出几篇相关内容的博文。


个人系统环境与所用开发板

  • 电脑:MacBook Air
  • 虚拟机:VMWare Fusion 12
  • Linux系统:Ubuntu 20.04.01
  • 开发板:普中HC6800V2.0 (开发板实物请跳转到“单片机效果展示”一节。)

安装开源编译器 sdcc

终端输入指令 sudo -i 进入根目录 /,再次输入指令 sudo apt-get install sdcc 。安装完毕,全程无报错。终端输入指令 sdcc -v 验证编译器是否安装成功:
零基础 Ubuntu 20.04.01 下搭建51单片机开发环境[开源编译器SDCC]

∗ \ast 小贴士:SDCC的全称是Small Device C Compiler,即“小型设备C语言编译器”。根据官网(http://sdcc.sourceforge.net/)的说法,SDCC是一个可重定向目标的、优化的标准C编译器套件(支持ANSI C89、ISO C99和ISO C11),支持基于英特尔MCS51(8031、8032、8051、8052等)、Maxim(原Dallas)的DS80C390系列、Freescale(原摩托罗拉)的HC08系列(hc08、s08)、Zilog的Z80系列(z80、z180、gbz80、Rabbit 2000/3000、Rabbit 3000A、TLCS-90)、Padauk(pdk14、pdk15)和意法半导体的STM8。

图片里打框的MCS51就是我们常说的51单片机,在根目录里进入路径 usr/share/sdcc/include/mcs51 输入 ls,会显示出一堆不同型号的51单片机芯片的适配头文件。至此,编译器SDCC的安装大功告成。

零基础 Ubuntu 20.04.01 下搭建51单片机开发环境[开源编译器SDCC]


STC MCU ISP 闪存工具 stcgal 的安装

在根目录 / 下输入指令 pip3 install stcgal(系统没有安装 pip3 就自己下载安装),安装的同时会下载两个软件 tqdm-4.64.1pyserial-3.5 。前者显示文件 main.hex 的烧录进度条,后者则是串口通信软件。(记住了,不管安装什么软件,在安装之前必须要好好查一查其具体的功能是什么。

零基础 Ubuntu 20.04.01 下搭建51单片机开发环境[开源编译器SDCC]


单片机代码的编译与测试

|编写主代码 main.c

#include <mcs51/8051.h>

void Delay(unsigned int ms);

void main(){
        while(1){
        		//自行对照开发板引脚图。
                P1_1 = 0;   
                Delay(500);
                P1_1 = 1;
                //led灯以一秒为一个周期闪烁。
                Delay(500); 
        }
}

void Delay(unsigned int ms){
        unsigned int a, b;
        for(a = ms; a > 0; a--){
                for(b = 100; b > 0; b--);
        }
}

|使用 sdcc 编译

在终端前后输入以下两条指令,经过sdcc的编译,测试文件夹内会多出一堆的文件,我们需要的主文件是 main.hex

	sdcc main.c 
	//sdcc默认生成的文件后缀不是hex而是ihx,需要使用packihx转换。
	packihx main.ihx > main.hex && ls

搜索相关资料的时候发现了第三条指令:makebin (makebin main.ihx > main.bin)。原来与 ∗ \ast .hex 格式文件相比, ∗ \ast .bin 格式有文件三个方面的差异(请自行验证):

  • HEX文件是包括地址信息的,而BIN文件格式只包括了数据本身。 在烧写/下载HEX文件时一般不需要用户指定地址,因为HEX文件内部信息已经包括了地址,而烧写BIN文件时,用户必须指定地址信息;
  • BIN文件。对二进制文件而言,没有格式,文件只是纯粹的二进制数据。
  • HEX文件使用ASCII来表示二进制的数值。 如一般的8-BIT的二进制数值0x3F,用ASCII来表示就需要表示字符‘3’和字符‘F’,每个字符需要一个BYTE,所以 HEX文件需要大于BIN文件2倍的内存空间

|闪存烧录 stcgal

用USB线连接电脑将与单片机(请自行安装与系统版本对应的CH341驱动,无头绪的读者请参考下列第二篇博文《搭建Ubuntu的51单片机开发环境(学习记录)》里对应的驱动安装一节),输入指令 ls /dev/tty ∗ \ast 确认USB接入后在终端输入指令

stcgal -P stc89 -p /dev/ttyUSB0 main.hex

或者直接输入

stcgal main.hex 

笔者在烧录程序时直接用第二条,在上文里代码头文件已经选择了51单片机类型为 8051 #include <mcs51/8051.h>,个人认为 stcgal 运行时默认 port 为 /dev/ttyUSB0,故使用时直接运行,无需手动指定端口和波特率。

零基础 Ubuntu 20.04.01 下搭建51单片机开发环境[开源编译器SDCC]


单片机效果展示

单片机的LED灯模块,右边数第一个LED灯以一秒为一个周期闪烁。

零基础 Ubuntu 20.04.01 下搭建51单片机开发环境[开源编译器SDCC]
零基础 Ubuntu 20.04.01 下搭建51单片机开发环境[开源编译器SDCC]


拓展1⃣️:使用SDCC进行单片机程序编写的不同点

SDCC支持的C语言与Keil的差异:

  • 包含自定义的头文件时必须使用双引号。 某个项目中有个名为tm1638.h 的文件,在Keil写成 #include <tm1638.h> ,但在SDCC中必须写成 #include “tm1638.h” ;
  • sdcc编译51单片机代码文件的头文件(引脚定义文件)名字不一样。 Keil中为 #include <reg52.h>,而在SDCC中需要写成 #include <mcs51/8051.h>;
  • Keil中的特殊类型 sbit 和 sfr 在SDCC中为 __sbit和 __sfr 。 如Keil中的代码 sfr P0 = 0x80、sbit P0_1 = P0 ^ 1。在SDCC中就要写成:__sfr __at (0x80) P0、__sbit __at (0x81) P0_1 。但在8051.h 中已经定义了常用的端口,需要使用哪个端口时,直接使用P0、P1、P2_1之类的宏即可;
  • Keil中的code关键字(用于将数据放入代码段)在SDCC中应该写成__code。 在Keil中的代码unsigned char code sevenseg_hex[] = { … },在SDCC中应该这样写:__code unsigned char sevenseg_hex[] = { … };
  • Keil中的 interrupt 关键字在SDCC中应该写成 __interrupt。 定义中断处理函数的代码在SDCC中应该写成:void timer0() __interrupt 1 { … } 。

< 请读者自行验证以上,同时欢迎在评论区补充不同的差异点。>

拓展2⃣️:附头文件 8051.h 文本

/*-------------------------------------------------------------------------
   8051.h: Register Declarations for the Intel 8051 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 REG8051_H
#define REG8051_H

/*  BYTE Register  */
__sfr __at (0x80) P0   ;
__sfr __at (0x81) SP   ;
__sfr __at (0x82) DPL  ;
__sfr __at (0x83) DPH  ;
__sfr __at (0x87) PCON ;
__sfr __at (0x88) TCON ;
__sfr __at (0x89) TMOD ;
__sfr __at (0x8A) TL0  ;
__sfr __at (0x8B) TL1  ;
__sfr __at (0x8C) TH0  ;
__sfr __at (0x8D) TH1  ;
__sfr __at (0x90) P1   ;
__sfr __at (0x98) SCON ;
__sfr __at (0x99) SBUF ;
__sfr __at (0xA0) P2   ;
__sfr __at (0xA8) IE   ;
__sfr __at (0xB0) P3   ;
__sfr __at (0xB8) IP   ;
__sfr __at (0xD0) PSW  ;
__sfr __at (0xE0) ACC  ;
__sfr __at (0xF0) B    ;


/*  BIT Register  */
/* P0 */
__sbit __at (0x80) P0_0 ;
__sbit __at (0x81) P0_1 ;
__sbit __at (0x82) P0_2 ;
__sbit __at (0x83) P0_3 ;
__sbit __at (0x84) P0_4 ;
__sbit __at (0x85) P0_5 ;
__sbit __at (0x86) P0_6 ;
__sbit __at (0x87) P0_7 ;

/*  TCON  */
__sbit __at (0x88) IT0  ;
__sbit __at (0x89) IE0  ;
__sbit __at (0x8A) IT1  ;
__sbit __at (0x8B) IE1  ;
__sbit __at (0x8C) TR0  ;
__sbit __at (0x8D) TF0  ;
__sbit __at (0x8E) TR1  ;
__sbit __at (0x8F) TF1  ;

/* P1 */
__sbit __at (0x90) P1_0 ;
__sbit __at (0x91) P1_1 ;
__sbit __at (0x92) P1_2 ;
__sbit __at (0x93) P1_3 ;
__sbit __at (0x94) P1_4 ;
__sbit __at (0x95) P1_5 ;
__sbit __at (0x96) P1_6 ;
__sbit __at (0x97) P1_7 ;

/*  SCON  */
__sbit __at (0x98) RI   ;
__sbit __at (0x99) TI   ;
__sbit __at (0x9A) RB8  ;
__sbit __at (0x9B) TB8  ;
__sbit __at (0x9C) REN  ;
__sbit __at (0x9D) SM2  ;
__sbit __at (0x9E) SM1  ;
__sbit __at (0x9F) SM0  ;

/* P2 */
__sbit __at (0xA0) P2_0 ;
__sbit __at (0xA1) P2_1 ;
__sbit __at (0xA2) P2_2 ;
__sbit __at (0xA3) P2_3 ;
__sbit __at (0xA4) P2_4 ;
__sbit __at (0xA5) P2_5 ;
__sbit __at (0xA6) P2_6 ;
__sbit __at (0xA7) P2_7 ;

/*  IE   */
__sbit __at (0xA8) EX0  ;
__sbit __at (0xA9) ET0  ;
__sbit __at (0xAA) EX1  ;
__sbit __at (0xAB) ET1  ;
__sbit __at (0xAC) ES   ;
__sbit __at (0xAF) EA   ;

/*  P3  */
__sbit __at (0xB0) P3_0 ;
__sbit __at (0xB1) P3_1 ;
__sbit __at (0xB2) P3_2 ;
__sbit __at (0xB3) P3_3 ;
__sbit __at (0xB4) P3_4 ;
__sbit __at (0xB5) P3_5 ;
__sbit __at (0xB6) P3_6 ;
__sbit __at (0xB7) P3_7 ;

__sbit __at (0xB0) RXD  ;
__sbit __at (0xB1) TXD  ;
__sbit __at (0xB2) INT0 ;
__sbit __at (0xB3) INT1 ;
__sbit __at (0xB4) T0   ;
__sbit __at (0xB5) T1   ;
__sbit __at (0xB6) WR   ;
__sbit __at (0xB7) RD   ;

/*  IP   */
__sbit __at (0xB8) PX0  ;
__sbit __at (0xB9) PT0  ;
__sbit __at (0xBA) PX1  ;
__sbit __at (0xBB) PT1  ;
__sbit __at (0xBC) PS   ;

/*  PSW   */
__sbit __at (0xD0) P    ;
__sbit __at (0xD1) F1   ;
__sbit __at (0xD2) OV   ;
__sbit __at (0xD3) RS0  ;
__sbit __at (0xD4) RS1  ;
__sbit __at (0xD5) F0   ;
__sbit __at (0xD6) AC   ;
__sbit __at (0xD7) CY   ;

/* BIT definitions for bits that are not directly accessible */
/* PCON bits */
#define IDL             0x01
#define PD              0x02
#define GF0             0x04
#define GF1             0x08
#define SMOD            0x80

/* TMOD bits */
#define T0_M0           0x01
#define T0_M1           0x02
#define T0_CT           0x04
#define T0_GATE         0x08
#define T1_M0           0x10
#define T1_M1           0x20
#define T1_CT           0x40
#define T1_GATE         0x80

#define T0_MASK         0x0F
#define T1_MASK         0xF0

/* Interrupt numbers: address = (number * 8) + 3 */
#define IE0_VECTOR      0       /* 0x03 external interrupt 0 */
#define TF0_VECTOR      1       /* 0x0b timer 0 */
#define IE1_VECTOR      2       /* 0x13 external interrupt 1 */
#define TF1_VECTOR      3       /* 0x1b timer 1 */
#define SI0_VECTOR      4       /* 0x23 serial port 0 */

#endif

参考资料

  • 《Mac版下实现51单片机进行开发的环境搭建》,CSDN博主:熺子,时间:2022年3月29日;
  • 《搭建Ubuntu的51单片机开发环境(学习记录)》,CSDN博主:横着望的猫,时间:2021年12月20日;
  • 《Linux(Ubuntu)下51单片机的开发环境的配置及详细的操作步骤》,CSDN博主:逗比小憨憨,时间:2021年2月4日;
  • 《如何在Linux下进行51单片机的开发》,微信公众号:我的一九九三,时间:2021年12月16日;
  • 《还在用keil做51单片机开发马?快来试试开源的SDCC吧》,微信公众号:STEM创造家,时间:2021年12月10日;
  • 《CentOS7设置环境变量》(该篇博文在哔哩哔哩里有博主配套的视频讲解,强烈推荐观看!),博主:C语言技术网-码农有道,时间:2020年3月27日;
  • 《一文带你学会Linux系统的变量》,微信公众号:生信喵实验柴,时间:2021年12月14日;
  • 《如何设置与查看Linux系统中的环境变量》,微信公众号:良许,时间:2020年8月17日;
  • 《Linux目录详解,软件应该安装到哪个目录》,博主:Deshun,时间:2019年6月13日。

文章更新时间记录

  • 文章框架搭好;「2023.2.2.19 19:10」
  • 九篇参考博文打列完毕;「2023.2.19 19:26」
  • “安装开源编译器SDCC”一节完毕。「2023.2.19 21:07」
  • “STC MCU ISP闪存工具 stcgal 的安装”一节完毕。「2023.2.19 21:25」
  • “单片机代码的编译与测试”一节里的三小节完毕。「2023.2.20 13:33」
  • “使用SDCC进行单片机程序编写的不同点”一节完成。「2023.2.20 13:53」
  • “单片机效果展示”一节完成。「2023.2.20 18:43」
  • “使用sdcc编译”该小节内增加了BIN文件相关内容。「2023.2.20 19:45」
  • 文章首次发布于CSDN。「2023.2.21 12:20」

P.S.1 2022年12月下旬在别人的同类型的博文下了留言,如今自己在两个月也写了一篇。两个月,两个月,两年,两年,唉。「2023.2.20 19:47」文章来源地址https://www.toymoban.com/news/detail-423581.html

到了这里,关于零基础 Ubuntu 20.04.01 下搭建51单片机开发环境[开源编译器SDCC]的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • AltiumDesigner20绘制51单片机最小系统原理图详细流程

    概述: 所用软件:AltiumDesigner 20; 绘制STC89C51最小系统(仅能够实现单片机的运行); 前言(可忽略):   本来想着是直接上绘制流程,但是想了想还是决定说几句。在AD中无论是绘制什么电路原理图,我对于新手的建议是不要仅仅停留在依样画葫芦,相反地我们更应该先去

    2024年02月12日
    浏览(27)
  • 基于51单片机的DS18B20温度显示

    本讲内容:       了解温度传感器DS18B20的使用,并通过一个例程展示温度传感器DS18B20测温过程。 DS18B20简介:       DS18B20 是单线数字温度传感器,即“一线器件”,其具有独特的优点:     (1)采用单总线的接口方式 与微处理器连接时 仅需要一条口线即可实现微处理器

    2024年02月12日
    浏览(35)
  • 51单片机温度传感器DS18B20

    实现功能 插上DS18B20温度传感器,数码管显示检测的温度值 单片机型号:STC89C52 DS18B20介绍 1、DS18B20简介 DS18B20 是由 DALLAS 半导体公司推出的一种的“一线总线(单总线)”接口的温度传感器。与传统的热敏电阻等测温元件相比,它是一种新型的体积小、 适用电压宽、与微处理

    2024年02月01日
    浏览(35)
  • 51单片机(十三)DS18B20温度传感器

    ❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 :适用于想要从零基础开始学习入门单片机,且有一定C语言基础的的童鞋

    2024年02月11日
    浏览(29)
  • 51单片机读取DS18B20温度传感器

    1 .首先我们知道DS18B20是 单总线协议 ,只有一根数据线。所以Data数据线即使发送端又是接收端,同时DS18B20内部接了弱上拉电阻(如图一所示),数据线默认为高电平。有了这些概念,我们就能进行下一步。                                                图一 (截取

    2024年02月08日
    浏览(26)
  • 51单片机DS18B20测温LCD1602显示

    主函数 自定义头文件 LCD1602函数 DS18B20 共用函数

    2024年02月11日
    浏览(26)
  • 51单片机的基础知识——单片机简介

    仅用于学习交流!!! 仅用于学习交流!!! 仅用于学习交流!!! 单片机,即单片微型计算器,简称为单片机。用专业术语来讲单片机就是在一块硅片上集成了微处理器、存储器以及各种输入/输出(I/O,I指的是input,O指的是output)口的芯片。通俗点讲,单片机是一块集

    2024年02月03日
    浏览(42)
  • MCU-51:单片机DS18B20温度报警器

    DS18B20是一种常见的数字温度传感器,其控制命令和数据都是以数字信号的方式输入输出,相比较于模拟温度传感器,具有功能强大、硬件简单、易扩展、抗干扰性强等特点 测温范围:-55°C 到 +125°C 通信接口:1-Wire(单总线) 其它特征:可形成总线结构、内置温度报警功能、

    2024年02月02日
    浏览(42)
  • 51单片机学习--DS18B20温度读取&温度报警器

    需要先编写OneWire模块,再在DS18B20模块中调用OneWire模块的函数 先根据原理图做好端口的声明: 接下来像之前一样把时序结构用代码模拟出来: 至此,OneWire模块就写好了,接下来在DS18B20模块中模拟数据帧: 之后只需要在main中调用即可 接下来进行一些综合的应用:温度报警

    2024年02月14日
    浏览(35)
  • 基于51单片机多路温度检测proteus仿真 ds18b20

    本设计是基于51单片机多路温度检测proteus仿真_ds18b20(仿真+程序+原理图) 仿真图proteus 7.8 程序编译器:keil 4/keil 5 编程语言:C语言 设计编号:C0042 功能说明: 通过对多路DS18B20温度传感器的数据采集,实现8路/4路温度采集并将数值显示在LCD显示屏上; 通过按键设置温度报警

    2024年02月12日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包