sdcc的一个简单的示例
首先编写一个源文件假设为main.c,内容如下:
[cpp] view plaincopyprint?
#include <at89x52.h>#define led1 P2_0void delayms(unsigned int ms){ unsigned int x, y; for (y = ms; y > 0; y--) { for (x = 227; x > 0; x--); }}void main(void){ while (1) { led1 = 0; delayms(1000); led1 = 1; delayms(1000); }}
#include <at89x52.h>#define led1 P2_0void delayms(unsigned int ms){ unsigned int x, y; for (y = ms; y > 0; y--) { for (x = 227; x > 0; x--); }}void main(void){ while (1) { led1 = 0; delayms(1000); led1 = 1; delayms(1000); }}
之后,当然是编译这个源文件,使用命令:
$ sdcc main.c
编译完成之后将生成一堆的文件,不管它,只需要其中的main.ihx,最后当然是将它转换成我们需要的hex文件,命令如下:
$ packihx main.ihx > main.hex
hex文件生成之后,当然是下载进去看看最终的结果是否正确,为此,为了方便使用STC提供的STC-ISP软件来下载(板子为圈圈教你玩USB提供的板子,CPU为STC89C52RC),可是下载进去之后,LED并没有闪烁起来。最开始怀疑板子难道坏了,因为很久都没有用过它了,无奈,下载了一个圈圈教你玩USB提供的一个示例程序进去,能够运行起来,证明板子是没有问题的。又怀疑sdcc编译是否有问题,必须是否要加上一些编译选项之类的,为此,又不得不下载keil软件,同样的程序,下载进去之后居然能够运行起来,更加怀疑是自己没有编译好,又在网上参考了很多资料,也没有发现编译哪个地方出现了问题,还下了个proteus仿真软件,加载hex文件之后可以运行。好吧,现在又怀疑下载软件的问题,也许是STC-ISP只支持keil软件编译的呢,然后又尝试找一个Linux下的下载软件,找到了gSTCISP,可是呢,我为了图方便,就 直接使用了网上编译好的一个,一运行总是提示libvte.so.9没有找到,以为是我自己的Linux环境的问题,中间还把桌面环境给删掉了,好不容易才恢复回来,差一点就重装系统了。最后呢,还是从网上下载gSTCISP的源码包,老老实实的./configure make sudo make install来安装,gSTCISP需要到是bin文件,使用命令:
$ objcopy -I ihex -O binary main.hex main.bin运行gSTCISP也没有出现问题,只是下载不是那么好下载,老是停在这里:
We are trying to connect to your MCU ...反正下载不是那么顺利,但是好歹证明编译是没有问题的,以后就可以使用sdcc来开发单片机程序了。
其实呢中间还测试了一下,下载了sdcc的IDE环境来编译上面的那个程序,编译之后使用STC提供的ISP软件下载进去之后仍然没有运行起来,如果说使用命令行的sdcc编译有可能有问题的话,那么使用IDE应该没有问题了吧,更加坚信是下载软件的问题了,可以从这里下载sdcc IDE:http://mcu8051ide.sourceforge.net/
这里直接就有提供的ubuntu下的安装包,当然你可以直接使用命令
:
sudo apt-get install mcu8051ide来安装。
sdcc和Makefile的例子
分类: 单片机 2014-01-11 22:02 227人阅读 评论(0) 收藏 举报
还是前面的main.c[cpp] view plaincopyprint?
#include <at89x52.h>#define led1 P2_0void delayms(unsigned int ms){ unsigned int x, y; for (y = ms; y > 0; y--) { for (x = 227; x > 0; x--); }}void main(void){ while (1) { led1 = 0; delayms(1000); led1 = 1; delayms(1000); }}
#include <at89x52.h>#define led1 P2_0void delayms(unsigned int ms){ unsigned int x, y; for (y = ms; y > 0; y--) { for (x = 227; x > 0; x--); }}void main(void){ while (1) { led1 = 0; delayms(1000); led1 = 1; delayms(1000); }}编译这个程序的Makefile如下:[plain] view plaincopyprint?
CC = sdccall:led.binled.bin:led.hex objcopy -I ihex -O binary led.hex led.binled.hex:main.ihx packihx main.ihx > led.hexmain.ihx:main.c $(CC) main.c.PHONY:cleanclean: -rm led.bin led.hex main.asm main.ihx main.lk main.lst\ main.map main.mem main.rel main.rst main.sym
CC = sdccall:led.binled.bin:led.hex objcopy -I ihex -O binary led.hex led.binled.hex:main.ihx packihx main.ihx > led.hexmain.ihx:main.c $(CC) main.c.PHONY:cleanclean: -rm led.bin led.hex main.asm main.ihx main.lk main.lst\ main.map main.mem main.rel main.rst main.sym 当然也可以直接将ihx文件转换成bin文件,Makefile如下:
[plain] view plaincopyprint?
CC = sdccall:led.bin#led.bin:led.hex# objcopy -I ihex -O binary led.hex led.bin#led.hex:main.ihx# packihx main.ihx > led.hexled.bin:main.ihx makebin main.ihx led.binmain.ihx:main.c $(CC) main.c.PHONY:cleanclean: -rm led.bin main.asm main.ihx main.lk main.lst\ main.map main.mem main.rel main.rst main.sym
CC = sdccall:led.bin#led.bin:led.hex# objcopy -I ihex -O binary led.hex led.bin#led.hex:main.ihx# packihx main.ihx > led.hexled.bin:main.ihx makebin main.ihx led.binmain.ihx:main.c $(CC) main.c.PHONY:cleanclean: -rm led.bin main.asm main.ihx main.lk main.lst\ main.map main.mem main.rel main.rst main.sym
注:使用makebin产生的bin文件会很大。
sdcc多文件的编译
分类: 单片机 2014-01-13 14:58 150人阅读 评论(0) 收藏 举报
还是前面的main.c,分割成两个源文件,main.c如下:[cpp] view plaincopyprint?
#include <at89x52.h>#include &quot;delay.h&quot;#define led1 P2_0void main(void){ while (1) { led1 = 0; delayms(1000); led1 = 1; delayms(1000); }}
#include <at89x52.h>#include &quot;delay.h&quot;#define led1 P2_0void main(void){ while (1) { led1 = 0; delayms(1000); led1 = 1; delayms(1000); }}delay.c和delay.h分别如下:[cpp] view plaincopyprint?
void delayms(unsigned int ms){ unsigned int x, y; for (y = ms; y > 0; y--) { for (x = 227; x > 0; x--); }}
void delayms(unsigned int ms){ unsigned int x, y; for (y = ms; y > 0; y--) { for (x = 227; x > 0; x--); }}
[cpp] view plaincopyprint?
#ifndef __DELAY_H#define __DELAY_Hextern void delayms(unsigned int ms);#endif /* __DELAY_H */
#ifndef __DELAY_H#define __DELAY_Hextern void delayms(unsigned int ms);#endif /* __DELAY_H */编译时可以使用以下的命令:
$ sdcc -c main.c$ sdcc -c delay.c$ sdcc main.rel delay.rel需要注意的是,在sdcc中,编译的目标文件后缀名为.rel,而不是Linux下常见的.o。sdcc -c为编译步骤生成目标文件,最终链接成所需要的.ihx文件main.ihx,Makefile如下:[plain] view plaincopyprint?
CC = sdccall:led.bin#led.bin:led.hex# objcopy -I ihex -O binary led.hex led.bin#led.hex:main.ihx# packihx main.ihx > led.hexled.bin:main.ihx makebin main.ihx led.binmain.ihx:main.rel delay.rel $(CC) main.rel delay.relmain.rel:main.c delay.h $(CC) -c main.cdelay.rel:delay.c $(CC) -c delay.c.PHONY:cleanclean: -rm led.bin main.asm main.ihx main.lk main.lst\ main.map main.mem main.rel main.rst main.sym -rm delay.asm delay.lst delay.rel delay.rst delay.sym 多Makefile的例子 分类: 单片机 2014-01-13 22:11 112人阅读 评论(0) 收藏 举报
还是以前面的例子,通常我们并不将所有的源代码和Makefile放在同一个目录下,尤其对比较大的工程而言。在这里假设有led这个工程,在led这个工程目录下有个main目录,main目录下的文件为前面的main.c、delay.c和delay.h,main目录下的Makefile如下:[plain] view plaincopyprint?
CC = sdccall:delay.rel main.reldelay.rel:delay.c $(CC) -c delay.cmain.rel:main.c delay.h $(CC) -c main.c.PHONY:cleanclean: -rm delay.asm delay.lst delay.rel delay.sym delay.rst\ main.asm main.lst main.rel main.sym main.rst
CC = sdccall:delay.rel main.reldelay.rel:delay.c $(CC) -c delay.cmain.rel:main.c delay.h $(CC) -c main.c.PHONY:cleanclean: -rm delay.asm delay.lst delay.rel delay.sym delay.rst\ main.asm main.lst main.rel main.sym main.rst在main目录,只是对.c文件做编译,不进行最后的链接,而在上一个层的工程根目录下做最后的链接,Makefile如下:[plain] view plaincopyprint?
CC = sdccall:led.binled.bin:led.ihx makebin led.ihx led.binled.ihx:main/delay.rel main/main.rel $(CC) -o led.ihx main/delay.rel main/main.relmain/delay.rel main/main.rel: cd main && make.PHONY:cleanclean: -rm led.bin led.ihx led.lk led.map led.mem cd main && make clean
CC = sdccall:led.binled.bin:led.ihx makebin led.ihx led.binled.ihx:main/delay.rel main/main.rel $(CC) -o led.ihx main/delay.rel main/main.relmain/delay.rel main/main.rel: cd main && make.PHONY:cleanclean: -rm led.bin led.ihx led.lk led.map led.mem cd main && make clean
整个工程可以从这里下载:http://download.csdn.net/detail/mcgrady_tracy/6845081
sdcc 中断使用中的一个问题
分类: 单片机 2014-04-01 14:19 107人阅读 评论(0) 收藏 举报
在sdcc中,中断处理函数使用关键字__interrupt标识,后面跟上中断号,8051中断号列表如下:
Interrupt # Description Vector Address 0 External 0 0x0003 1 Timer 0 0x000b 2 External 1 0x0013 3 Timer 1 0x001b 4 Serial 0x0023 5 Timer 2 (8052) 0x002b
虽然看上去很简单,但是在使用过程中还出现了一个小问题,由于我将程序分成了两个部分,main.c和timer.c,而在timer.c中的定时器中断处理函数timer0_isr始终是不能被执行,检查程序呢也未发现什么原因,通过查看sdcc中的源代码和上网查找timer部分代码,也未发现timer0初始化有任何问题,顿时就郁闷了。但是也发现两个一个不同之处,就是在main函数之前对中断处理函数做了一个声明,于是我就在我的程序中加上了这个声明,程序终于调用了中断处理函数,特此记录一下。完整的程序如下:
[cpp] view plaincopyprint?
/* timer.c */#include <at89x52.h>#define OSC_FREQ 12000000UL#define TIMER_MODE0 0x00#define TIMER_MODE1 0x01#define TIMER_MODE2 0x02#define TIMER_MODE3 0x03volatile unsigned int count = 0;void timer0_isr(void) __interrupt 1{ count++; TH0 = (65536-1000*(OSC_FREQ/12000000)) >> 8; TL0 = (65536-1000*(OSC_FREQ/12000000)) & 0x00FF;}void timer0_init(void){ TMOD &= 0xF0; TMOD |= TIMER_MODE1; /* Timer 0 work on 16-bit timer mode */ TH0 = (65536-1000*(OSC_FREQ/12000000)) >> 8; TL0 = (65536-1000*(OSC_FREQ/12000000)) & 0x00FF; ET0 = 1; /* Enable timer 0 interrupt */ EA = 1; TR0 = 1; /* Turn on timer 0 */}void delayms(unsigned int n){ while (count <= n); count = 0;}
/* timer.c */#include <at89x52.h>#define OSC_FREQ 12000000UL#define TIMER_MODE0 0x00#define TIMER_MODE1 0x01#define TIMER_MODE2 0x02#define TIMER_MODE3 0x03volatile unsigned int count = 0;void timer0_isr(void) __interrupt 1{ count++; TH0 = (65536-1000*(OSC_FREQ/12000000)) >> 8; TL0 = (65536-1000*(OSC_FREQ/12000000)) & 0x00FF;}void timer0_init(void){ TMOD &= 0xF0; TMOD |= TIMER_MODE1; /* Timer 0 work on 16-bit timer mode */ TH0 = (65536-1000*(OSC_FREQ/12000000)) >> 8; TL0 = (65536-1000*(OSC_FREQ/12000000)) & 0x00FF; ET0 = 1; /* Enable timer 0 interrupt */ EA = 1; TR0 = 1; /* Turn on timer 0 */}void delayms(unsigned int n){ while (count <= n); count = 0;}
[cpp] view plaincopyprint?
/* timer.h */#ifndef __TIMER_H#define __TIMER_Hextern void timer0_init(void);extern void delayms(unsigned int n);#endif /* __TIMER_H */
/* timer.h */#ifndef __TIMER_H#define __TIMER_Hextern void timer0_init(void);extern void delayms(unsigned int n);#endif /* __TIMER_H */
[cpp] view plaincopyprint?
/* main.c */#include <at89x52.h>#include &quot;timer.h&quot;#define led1 P2_0void timer0_isr(void) __interrupt 1;void main(void){ timer0_init(); while (1) { led1 = 0; delayms(1000); led1 = 1; delayms(1000); }}
/* main.c */#include <at89x52.h>#include &quot;timer.h&quot;#define led1 P2_0void timer0_isr(void) __interrupt 1;void main(void){ timer0_init(); while (1) { led1 = 0; delayms(1000); led1 = 1; delayms(1000); }}
注:经验证,在Keil中未出现该问题。 |