在Mac电脑编译c51程序

如果不是Seven问起来,我以为C51这种东西已经属于历史遗迹了。不过简单搜索了一下,发现c51老而弥坚,仍然茁壮的生长着。原因据说,一方面是有很大的用户群和既有的软硬件资源,另外一方面,的确在很多的高校教学中仍然占有一席之地。其实个人感觉,高校课程的更新真的是需要再加快了。
不过不管如何,作为入门类的单片机,c51还好啦,这些学习的经历,并不会浪费,学生能够很快的转化到其它平台上去。
Seven碰到的情况是这样,c51开发工具目前基本以windows为主,在mac上无法工作,总不能为了学习c51就换一台电脑。我搜索了一下,发现了sdcc这个工具,于是来尝试一下,首先是安装sdcc:
brew install sdcc
找一个呼吸灯程序源码,来测试一下编译是否正常:
#include <8051.h>

//  延时函数
//  参数  in 为延时的时间长度(单位时间很短,大约一条指令的时间)
void delay(unsigned int in)
{
    unsigned int i;
    for(i=0;i<10*in;i++) {;}
}
//  由暗变亮的子函数
//  参数 ledn 为点第几位的灯
void off_on(unsigned char ledn)
{
    unsigned int i,j;
    for(i=0;i<100;i++)
    {
        for(j=0;j<100;j++)
        {
            if(i<=j)
            {    //    模拟pwm的低电平输出
                P0 = 0;
            }
            else
            {    //    模拟PWM的高电平输出
                P0 = 1<<ledn;
            }
            delay(10);      //  这里的延时 根据灯的情况自己调整
        }
    }
}
//  由亮变暗的子函数
//  参数 ledn 为点第几位的灯
void on_off(unsigned char ledn)
{
    unsigned int i,j;
    for(i=100;i>1;i--)
    {
        for(j=0;j<100;j++)
        {
            if(i<=j)
            {        //    模拟pwm的低电平输出
                P0 = 0;
            }
            else
            {        //    模拟PWM的高电平输出
                P0 = 1<<ledn;
            }
            delay(10);                 //  这里的延时 根据灯的情况自己调整
        }
    }
}
//  主程序开始
void main()
{
    unsigned char ledn;
    while(1)
    {
        for(ledn=0;ledn<8;ledn++)
        {
            off_on(ledn);            
            on_off(ledn);
        }
    }
}
brew cask install textmate来安装。)
上面的源代码我们保存到比如test.c文件,接下来编译一下:
#编译命令,后面的test.c就是我们的源码,可以替换成你需要的名字:
sdcc test.c
#编译成功会生成多个文件:
test.asm test.ihx test.lk  test.lst test.map test.mem test.rel test.rst test.sym
这些文件中其实只有test.ihx文件是我们需要的输出文件。其它文件都是工作过程中的临时文件,一般没有用处,可以删除,但在大型系统中查错、分析可能会用得到。在windows工作惯了的同学们可能更习惯.hex输出文件,把.ihx转换为.hex的命令是:
packihx test.ihx > test.hex
还有可能会需要.bin文件,转换方法是:
sdobjcopy -I ihex -O binary test.ihx test.bin
#-I指定的是输入格式,-O指定的是输出格式
#最后两个参数分别是输入、输出的文件名
#sdobjcopy不带任何参数执行有更详细的帮助可以参考
.hex/.bin文件,并非是必须的,特别是在mac上工作,只是交流的时候如果需要,可以用上面的方法转换出来。
一般在学习的情况下,知道上面这些就够用了。在正式的开发过程中,特别是项目比较大,有多个模块,你可能还需要知道下面这些用法。
sdcc -c test.c
sdcc test.rel
这里大多初学者会有一个疑问,既然最终都是要.ihx文件,为啥还要编译成.rel文件呢?原因很多,常见的如下:
  • 当一个工程很大的时候,会分成多个.c程序来写,这就需要分别编译。而如果很多个.c文件,这编译也是很慢的,所以通行的做法是哪个文件被修改了,就仅编译改变了的文件。这时候使用.rel文件就会快很多,因为从.c文件到.rel文件,编译做了大多工作,只是没有做最后的拼装。一个大工程编译仅修改过的文件到.rel,然后把所有的.rel拼装在一起成为.ihx文件,速度会很快。
  • 还有的时候,比如你编写了一个模块,这个模块是通用的,可以供很多人使用,但你不希望别人看到源码或者避免别人修改搞乱了源码。你可以只给对方.rel文件和函数描述的.h文件,对方把你的模块放到自己的项目中而不去关心源代码是怎样的。
  • 继续我们的话题。单片机为了提高效率,还经常会用到汇编语言,汇编语言在sdcc软件包中是分cpu来实现的,一般默认提供这些cpu的汇编器:
    sdas390    sdas6808   sdas8051   sdasgb     sdasrab    sdasstm8   sdastlcs90 sdasz80
    这些汇编器统一的命名规则是sdasxxxx,xxxx是指cpu的型号,比如8051的cpu就使用sdas8051,z80的cpu就使用sdasz80。汇编器使用的方法是(以8051为例):
    sdas8051 -ols filename.asm
    汇编结果输出.rel文件以及一些其它的过程文件。重要:使用sdcc编译单片机程序,跟windows下面keil的c代码是有一些差别的,列表如下:   Mac sdcc Windows Keil c 头文件 8051.h/8052.h reg51.h/reg52.h IO端口 P2_0 P2^0 IO口定义 #define LED P2_0 sbit LED = P2^0 中断函数 void INT0_ISR() __interrupt 0 void INT0_ISR() interrupt 0 可以看到,这个差别是非常小的。对于初学者来说,一般就是引用头文件的时候要注意别用错。其它的内容,碰到了就注意用对应的语法,碰不到就不用管。————————————————————————————————————————————有了编译的结果,还要烧录到51单片机上来测试结果,烧录这个词是行业内的“黑话”,表达同样意思的常用说法还有“刷机”、“烧机”、“烧写”、“下载到单片机”等,当然”下载到单片机”其实是最正式的说法。
    烧录需要有一个烧录软件,mac上可以这样安装:51单片机都是通过串口跟电脑连接的,当前的电脑一般都没有串口,所以都是使用usb串口卡,mac电脑一定要安装对应的mac版本电脑驱动程序。这时候51单片机通过串口插到电脑上之后,在/dev/目录会看到这个串口设备,设备的名字根据串口卡厂商的不同而不同,比如叫:/dev/tty.usbserial 。
    刚才下载的这个烧写软件支持.ihx文件和.bin文件,也就是说我们刚才编译的.ihx文件直接就可以烧录到51单片机上,烧录的命令是:
    stcflash.py test.ihx
    文章看起来似乎比较复杂,其实包含了才开始搭建环境以及你需要知道的所有入门型知识,只需要折腾这一次,以后的使用,应当能感觉到在mac更加的迅速、高效。
    sdcc官网:http://sdcc.sourceforge.net/,建议以官方文档为主。
    sdcc简单说明:,因版本问题,此文档中有一些错误,请甄别性的阅读。
    使用SDCC在Linux/macOS上开发51单片机程序:https://lonord.name/article/580cb1f67240257ec13293fb
    烧录软件:https://github.com/laborer/stcflash

    相关内容推荐