打印

sdcc入门教程网络摘抄

[复制链接]
185|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
第十代火影|  楼主 | 2018-9-29 14:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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 "delay.h"#define led1 P2_0void main(void){        while (1) {                led1 = 0;                delayms(1000);                led1 = 1;                delayms(1000);        }}



#include <at89x52.h>#include "delay.h"#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 "timer.h"#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 "timer.h"#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中未出现该问题。

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

363

主题

363

帖子

0

粉丝