SDCC编译器简明使用教程

先前翻译了SDCC编译器手册第一章的内容,尝试过去翻译其他章节,不过难度似乎比我预计的要大,在google的帮助下也完成不了,现在只能结合自己的使用写点了.

本文以SDCC手册第三章内容为基础!

这里不介绍SDCC的安装过程,作为电气工程专业或者计算机嵌入式方向的学生这不是什么困难的事!安装后把SDCC的bin目录添加到path环境变量使得你能在任何目录下使用SDCC,使用archlinux和debian系统的没有这一步,安装时已经自动配置好了!我平时很少使用集成开发工具(IDE)写代码,所以编辑源代码你可以使用你最拿手的工具,任何文本编辑器都可以,我使用的是vim!

源代码与Keil C的稍许不同

对于已经习惯使用Keil C的用户需要注意一下,SDCC的源代码和Keil C有所不同,需要做一点调整才能编译通过.SDCC比较多的使用像8051.h这样的头文件(include/mcs51目录下也有reg51.h这样的头文件).

对于一些非ANSI C的关键字,SDCC均采用双下滑线开头的方式定义,如__code,__idata,__sbit......对于单片机引脚的定义SDCC采用了__at关键字和十六进制地址(用户对底层地址信息要弄清楚,不过我觉得__at关键字是一个比较有特色的改进),如下:

//SDCC                                      Keil C
__sbit __at 0x94 blackLineLeft;         sbit blackLineLeft=P1^4;
__sbit __at 0x95 blackLineRight;        sbit blackLineRight=P1^5;
__sbit __at 0x80 in1;                   sbit in1=P1^0;
__sbit __at 0x81 in2;                   sbit in2=P1^1;
__sbit __at 0x82 in3                    sbit in3=P1^2;
__sbit __at 0x83 in4;                   sbit in4=P1^3;

更多的地址信息可以查看附录

对于内嵌汇编代码,SDCC使用__asm和__endasm两个关键字,参考代码如下:

void delay0_1(uint n) {
    for(i=0;i<n;++i) {
        for(j=0;j<10000;++j) {
            __asm
              nop
              __endasm;
        }
    }
}

源代码编译

单文件项目

对于单源文件8051项目的编译过程非常简单.用下面的命令编译你的程序

SDCC sourcefile.c

这一步将完成编译,汇编和链接的源文件.输出文件如下:

  • sourcefile.asm - 程序的汇编文件
  • sourcefile.lst - 程序的列表文件
  • sourcefile.rst - 被链接器更新的列表文件
  • sourcefile.sym - 由链接器生成的符号清单
  • sourcefile.rel - 由汇编器生成的对象文件,提供给链接器使用
  • sourcefile.map - 被链接器更新的最终存储器映射
  • sourcefile.mem - 内存的使用情况摘要
  • sourcefile.ihx - 用于生成Intel Hex格式文件模块

可能还有一些其他文件,查看SDCC手册可以了解更多!

在大多数情况下,下面这一步不是必须的,但是由SDCC的产生Intel HEX文件可能包括不同长度的行,并且该文件中的地址不保证是严格递增.如果您的工具链或引导器不支持这个,你可以使用packihx命令,这是SDCC的一部分:

packihx sourcefile.ihx >sourcefile.hex

然后烧录就可以了.

多文件项目

SDCC并不支持同时编译多个源代码文件,所以多文件项目的编译需要分步进行.假如你的项目包含foo1.c foo2.c main.c三个文件,那么编译过程如下:

sdcc -c foo1.c
sdcc -c foo2.c
sdcc main.c foo1.rel foo2.rel

还可以使用以下方式编译:

sdcc -c main.c
sdcc main.rel foo1.rel foo2.rel

最后处理一下ihx文件就可以了.对于多文件项目最好是写一个makefile文件用make维护或者写一个批处理文件.

结束了,对于初次使用SDCC这些应该够用了.高手不要见笑,新手就凑合着看看,我也是新手.欢迎大家留言,交流使人共同进步!

附录include/mcs51/8051.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 */
» 本博客采用署名 2.5 中国大陆许可协议进行许可,本文版权归作者所有,欢迎转载,但必须在明显位置给出原文连接。
anyShare分享到:
发表评论?

1 条评论。

  1. 好人啊,

发表评论

注意 - 你可以用以下 HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>