Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1170359
  • 博文数量: 173
  • 博客积分: 4048
  • 博客等级:
  • 技术积分: 2679
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-12 18:53
文章分类

全部博文(173)

文章存档

2018年(1)

2016年(1)

2013年(1)

2012年(118)

2011年(52)

分类: C/C++

2012-01-31 09:15:51

先前翻译了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 */
阅读(22854) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~