购物车0种商品
IC邮购网-IC电子元件采购商城
单片机C语言编译器
(2011/10/26 9:04:00)

跟大家分享一个我做的单片机C语言编译器。它的功能和keil软件差不多,能把C语言
转换成单片机的汇编程序。不过目前还不完善,只支持MCS51系列的单片机,等以后有时间
我会把这个编译器移植到AVR和PIC系列的单片机上。虽然C语言很流行,但我个人感觉C的一些
细微地方并不适合单片机,因此在设计这个编译器时,有些语法和标准C有区别。例如,
这个编译器扩展了移位运算,移位时可以指定空出的位是用0还是1填充,也可以循环移位,
分别用 <<- <<+ <<< 等运算表示,还提供了一种扩展的控制语句: loop 。使用时
就像下面这样:
loop( 8 )
{
语句a
}
表示执行8次语句a。实际是用djnz指令实现的,所以效率比for语句高。
对于变量类型则不再用标准C的char short long int 等名称,而是int+数字或uint+数字形式,
分别表示相应长度的有符号数和无符号数。例如下面的定义:
uint8 a = 0b00001111;//定义8位(一个字节)的无符号数,可以用二进制
int16 b = 12345;//定义16位(两个字节)有符号数
bit c = high;//定义位变量,赋值为1
bool 游戏结束 = true;//定义布尔类型变量
(标识符、文件名和文件夹等可以任意取名,这个编译器非常支持中文 ^_^)
另外增加了一个特别的类型--“元件类型”,例如这样定义一个元件类型:
box s24c256 [uint16*8]
{
interface void set( uint16 addr, uint8 data )
{
...
}
interface uint8 get( uint16 addr )
{
...
}
}
其中set函数用来把一个字节变量data通过IIC总线写入24c256中,而get函数用来读取
地址为addr的那个存储单元的数据。只要定义了这个元件,就可以在外部的24c256中
定义变量和数组、结构体等,例如:
s24c256 uint8 data = 0b00001111;//在24c256中定义8位无符号数data并赋值15。
data可以像一般变量那样参与运算。当运算中需要读取data的值时,编译器会自动调用
get函数获取值,当运算中需要改变data的值时(如赋值运算data = 34 )编译器会
自动调用set函数把34写入到24c256中,用法和普通的变量完全一致。非常方便。
实际上只要一个电子元件中可以存放数据,你就可以在那里定义数据,如把一个数组定义
到一个128*64液晶屏显存中,那对这个数组操作时屏幕会有相应的变化,甚至可以在
另一个单片机中定义一个数组,只要用set和get封装了串口通信程序,就可以在其他单片机
中读取和修改这个数组的各元素,很有意思吧!
一个源程序由若干个这样的元件类型组成,每个元件中都可以定义静态变量、函数和接口等,
每个成员都可以带有public或private修饰符,当为public类型时表明这个函数或静态变量
可以在任意地方访问,当为private类型时只能被同一元件中的函数访问。
实际上这种新增的元件类型作用非常大,通过它还能实现位变量的数组定义等。目前
我正在想办法把元件类型用于库函数的配置,因为下一步我正在打算为这个编译器添加
库函数集合,这里的库函数不是通常的编译系统自带的字符串操作、各种浮点运算等函数,
而是其他电子元件的驱动程序,如24c系列的读写函数、温度检测ds18b20的读写函数、
ds1302计时芯片的读写和液晶屏1602、128*64等接口函数。但现在有一个问题是这些函数
都不是用#include包含之后就可以直接使用的,都要先进行配置,如24c系列存储器
函数需定义SCK和SDA对应单片机的哪两个引脚,液晶1602的数据线怎样和单片机连接等。
而这些配置应在用户程序中实现,而不是进入库函数文件夹修改库函数。我打算这样实现:
库函数由若干个元件定义如液晶屏元件,ds18b20元件等组成,当需要使用哪个元件时
用#include包含进来,而每个元件的配置变量分别用一个“配置元件”定义,当然这个定义
是由用户编写的,也就是说库函数会反向访问用户的程序和数据。完整方式如下:
文件 test.c:
#include "AT24C256.h";
box main
{
void main()
{
AT24c256 uint16 data = 34;//在24c256中定义一个16位无符号数
while( true ) {}
}
}
box AT24c256_port //配置元件名称应为主元件名 + port
{
public bit SCK = &P1_0;
public bit SDA = &P1_1;
}
预计过年后给大家提供的下一个版本将会实现这种带库函数的编译器,因为库函数会反向访问
用户函数和数据,所以库函数将会以源代码的方式存放,而不像传统编译器那样以obj形式存放。
这样将会非常方便,代价仅仅是稍微增加了编译时间而已。
到目前为止,这个编译器还有些其他语法尚未实现,生成的hex代码也没有进行任何优化,
现在只是从“概念”上实现这种编程语言,至于优化则是以后的事情了。其他说明都在
编译器文件夹中,大家可以下载了看看。注意这个编译器是用C#设计的,本身不需要安装,
随便复制到哪个文件夹下都行,但运行需要微软的.NET环境,需要在网上搜一个netframework
安装之后编译器才能用(估计vista和win7的已经内置.NET 就不需安装了,不过没试过)。
希望各位高手有时间可以帮我测试一下,另外在语法方面我都想的头疼了,大家应该集思广益嘛,有好的建议可以邮箱联系:xbd2048@qq.com。让我们共同设计一个单片机专用的编程语言.
顺便再给大家拜个年 ^_^

网友评论:拍块砖,C语言编译器这东西,想做到很实用,难,做得差不多时,宜争取商业赞助,方能做大做强。

网友评论:
to 23楼 HWN: 我也知道这种语言其实很难得到大家的认可,但这个编译器和相应的语法我会一直开发下去.
0xCC 发表于 2010-1-26 11:01
做C编译器没问题,随着新的CPU的出现还会诞生很多针对某CPU的编译器。你的问题是“创造新的C”,由于标准具有唯一性(否则就不是标准了),这就把你自己放在了一个非常不合时宜的位置。如果那玩意儿早诞生几十年,也许标准就是你的了。

建议你改个名字,如C!什么的都行,至于那玩意儿能否成为标准,这就看你的造化了,不是没那可能。

网友评论:终于看到了传说中的牛,膜拜一下

我觉得楼主做的至少对自己来说很有意义,做一个编译器可不是那么简单,词法分析,就这一条就够搞的了。当然,这不是重点。

支持一个!

网友评论:
TO computer00:在keil中是,不过我设计的这个编译器控制语句中的表达式必须返回布尔类型, 所以目前还不能那样写.呵呵
0xCC 发表于 2010-1-26 10:27
那我改成
i=9;
while(--i!=0)
{
}


网友评论:
那我改成
i=9;
while(--i!=0)
{
}

lxyppc 发表于 2010-1-26 12:40
呵呵,真是不好意思,我的语法中禁止改变操作数的运算有返回值,所以++i和--i还有赋值语句都只能单独使用了,但这样处理之后基本就杜绝了标准C语言的边际效应,变量不会在运算中被莫名其妙的改变,提高了代码的安全性.

网友评论:跟着标准好,能做51就能做别的,你按标准做,市场就大,换句话说,容易找到新MCU厂家来买你的代码,

据说微软从前就是这样发家的

或者,可以考虑一下,自动生成代码,也是一个好的发展方向

网友评论:23#

我建议你现在立马停止写了。

主要弄弄大方向!
看看你的非标准有没有市场价值

如果你慎重考虑觉得你的非标准有市场价值 ,然后再继续写。
如果觉得没有市场价值,就按照标准重新写!

网友评论:肯定有用!
支持楼主,支持!支持!

网友评论:牛!

网友评论:楼主真牛!

网友评论:
23# HWM

我建议你现在立马停止写了。

主要弄弄大方向!
看看你的非标准有没有市场价值

如果你慎重考虑觉得你的非标准有市场价值 ,然后再继续写。
如果觉得没有市场价值,就按照标准重新写! ...
xlsbz 发表于 2010-1-26 13:14
把非标准改成标准的应该很容易了,直接修改语法树部分就行.但现在问题是
一边是标准语法,另一边是实用语法,就比如补1移位,补0移位和循环移位,这在单片机
开发中非常有用吧,而且很容易实现,但为了标准就必须全用算术移位 >> << 实现,
感觉有点别扭. 至少目前来说,不想放弃这些非标准语法

网友评论:36#

现在感觉改起来容易!

盖迪拜大厦,还没有开始盖,建筑图纸 你想怎么改都行。

等住上人了,怎么改都不行!那就晚啦

现在你觉得 ...在开发中有用,等两年可能就觉得自己考虑的太肤浅了。

尽管真理有时会掌握在少数人手里,但大多数情况并不如此。

网友评论:
呵呵,真是不好意思,我的语法中禁止改变操作数的运算有返回值,所以++i和--i还有赋值语句都只能单独使用了,但这样处理之后基本就杜绝了标准C语言的边际效应,变量不会在运算中被莫名其妙的改变,提高了代码的安全性. ...
0xCC 发表于 2010-1-26 12:52
那我再改成
i=9;
while(i!=0)
{
i--;
}


网友评论:楼主绝对牛人,赞一个,可是这不是标准呀,只能自己想玩的时候玩一下。。。

网友评论:强人,在21第一次看到这样的强人。。。。

网友评论:"标准"的写法:
i=9;
while( i != 0 )
{
i--;
}
或是
loop(8)
{
}
延时一秒可以这样写:
loop( 250 ) loop( 250 ) {}
其实我主要不是为了争论这个loop, 如果有时间不妨看看其中相对于C语言新增的"元件类型",我认为那才是这个编译器的最重要功能.

网友评论:
"标准"的写法:
其实我主要不是为了争论这个loop, 如果有时间不妨看看其中相对于C语言新增的"元件类型",我认 ...
0xCC 发表于 2010-1-26 14:15
我也不是在争这个loop的写法
我只是想确认一下一些现有的代码能不能用你的这个编译器来编译
因为我认为这才是这个编译器重要的功能

网友评论:不能啊,只能修改代码了. 不过我想,如果编译器能移植到AVR和PIC上,那么代码将不必进行任何改动(或仅修改端口)就能正常工作,这样也不错.

网友评论:
不能啊,只能修改代码了. 不过我想,如果编译器能移植到AVR和PIC上,那么代码将不必进行任何改动(或仅修改端口)就能正常工作,这样也不错.
0xCC 发表于 2010-1-26 14:30
呵呵,当年C++出来都不敢这么说啊
楼主可要想清楚了

网友评论:电脑和单片机编程是两回事么. 对于移植性,我是这么考虑的, 即所有类型都有固定的长度,如uint8是8位无符号数,
int16是16位无符号数,通过编译器不论在哪种单片机上都有相同的结果. 实际上编程时就好像在一个虚拟的单片机上运行一样,换成另一种单片机时,只要编译器提供了相同的变量类型和语法,源程序就不需改动了. 而标准C变量类型的长度不是确定的,就不太好移植.

网友评论:但是你的编译器还是不能编译现有代码啊
像我比较懒,要写什么程序的时候先去几大芯片厂的网站看看有没有现成的AppNote
有的话直接就拿过来用了,一般只需要改改配置什么的

网友评论:我会在下一版本中增加一个功能齐全的函数库,其中包含24c256,ds18b20等常见芯片的驱动程序.
而且会提供一种专门的语法来处理库函数的配置问题

网友评论:记住 不要玩!!
开发国产编译器的大任就降落在楼主的身上了!!______同意17楼的意见。

网友评论:唉……
看来还是得继续用keil
楼主努力啊!

网友评论:现在语言有那么多种.你还是看看发展史吧.

还有国外代码的层次架构.

啥优势都想占,往往是什么都占不到.

网友评论:还是先完成至少能编译像UCOSII那样的源码,并且测试正常之后再考虑新的扩展功能。

网友评论:还是严格支持C的标准好,因为到后面会发觉,自定义的东西很难推广开。

早几年前我写FinC就碰到了类似的问题,所以到了RT-Thread里的finsh shell,就严格使用C的方式。编译器方面,前端语法实际上是非常小非常小的一方面,优化是功力所在,然后是各种各样的后端支持。

网友评论:学习了

网友评论:楼主做的尝试不错。
只是,现在C语言编译器不少呵,就算只玩C51,多数人也就算个大众化的IDE直接弄了。
随便提的建议:
要是整成这样:图形化编程,最好能和别的软件做接口,比方Matlab/Simulink,弄个框图,一编译,直接下载到MCU运行。这种“硬件在回路”的东西现在还是有些市场的,至少专门做控制算法的一些人能用得上。国外这东西现在卖得爆贵。。呵呵。

网友评论:
楼主做的尝试不错。
只是,现在C语言编译器不少呵,就算只玩C51,多数人也就算个大众化的IDE直接弄了。

cauhorse 发表于 2010-1-26 18:31
呵呵,我的目标是设计一个和任何单片机无关的编译器,也就是说编译器的语法对于每种单片机都是完全一致的,这样一种单片机上的程序有可能不做改动就能在另一种单片机上运行,例如在MCS51上编了个俄罗斯方块,只要编译器移植到AVR上,那么这个俄罗斯方块程序不用修改就可以在AVR中运行.多好啊!以后就向着这个方向努力!

网友评论:

不错,强人很多...
用什么打开呢?

网友评论:楼主做得很不错。

网友评论:21里面确实藏龙卧虎,以后要多逛逛

网友评论:好样的,我们也在做编译器,我们聊聊。QQ563996855

网友评论:牛人啊,写编译器需要很高深的理论基础吧

网友评论:
呵呵,我的目标是设计一个和任何单片机无关的编译器,也就是说编译器的语法对于每种单片机都是完全一致的,这样一种单片机上的程序有可能不做改动就能在另一种单片机上运行,例如在MCS51上编了个俄罗斯方块,只要编译器 ...
0xCC 发表于 2010-1-26 18:47
你说的这个和当年JAVA初衷是一样的,所以后面多了个JAVA的虚拟机,你不会也来个虚拟机吧。

网友评论:绝对不会. 我是说同一个程序既可以编译到MCS51上,也可以不做修改的编译到AVR和PIC上. 所以我这里设计的语法是和任何单片机无关的语法,然后编译器力争在每种单片机中都实现这些语法,这样就可以实现我的目标了.

网友评论:顶LZ

网友评论:LZ是出于兴趣还是出于什么做这个编译器呢?
坦率得说,如果是PIC,除非能嵌到MPLAB IDE,否则是没几个人会去用的。MLAB IDE的接口文档,MCHP是不会随便开放的。
HI-TECH的IDE,中国大陆区根本没人用,悲剧啊,虽然C编译器实际用户很多。
在可以嵌入MPLAB IDE的前提下,C编译器要懂得在DEBUG的时候规避掉ICD模块占用的资源。麻烦事还是挺多的。

网友评论:看了这么多,感觉lz对单片机编程不很熟悉,编译器要做到retargetable,是比较麻烦的,JAVA虚拟机的思路不适合嵌入式系统编译器

网友评论:
看了这么多,感觉lz对单片机编程不很熟悉,编译器要做到retargetable,是比较麻烦的,JAVA虚拟机的思路不适合嵌入式系统编译器
wwwq 发表于 2010-1-28 17:35
不是啊, 我不可能在单片机上搞个虚拟机出来. 我的意思相当于让51系列的KEIL 和AVR的IAR 以及凌阳的SUNPLUSE IDE等有一个完全相同的语法,因为每个编译器都有点自己的扩展语法. 但这是不可能的,所以才尝试着做这个编译器, 我希望它能实现真正的高级语言,能屏蔽不同类型单片机之间的差异, 虽然目前没能实现. 但我正在努力的做.
MY QQ:910360201 不过经常不上线, 呵呵

网友评论:定LZ,,, 以前不是还有个哥们做了个海尔的C编译器么?后面怎么没消息了

网友评论:支持顶一下!

网友评论:牛人!顶一下!

网友评论:

LZ牛人
我在一家IC公司做单片机编译器,LZ的想法固然好,也是广大单片机用户所希望的,但难度不小啊
51、PIC、AVR等单片机指令集都不一样,且硬件资源也不一样,Windows下编程我们很少关心CPU的硬件资源,但单片机就不一样了

网友评论:niejinbo
这位是明白人,lz的勇气可嘉,但路线不清,不过能有做这个东西的勇气也比不少高校教授要强得多了,我曾经问过多个学校的计算机专业的老师,一个最深刻的是说:我们专业的都不搞,你们是无知者无畏。不过我们搞出来了。这里路太长,lz还是别搞了,学生的精力有限。

网友评论:LZ有空可研究下LCC,LCC可以针对不同的目标机器产生不同的代码,当然需要配置一下

网友评论:继续关注中

网友评论:做个编译器不容易,做得通用和用户认可的更难!

网友评论:顶起

网友评论:
不是啊, 我不可能在单片机上搞个虚拟机出来. 我的意思相当于让51系列的KEIL 和AVR的IAR 以及凌阳的SUNPLUSE IDE等有一个完全相同的语法,因为每个编译器都有点自己的扩展语法. 但这是不可能的,所以才尝试着做这个编 ...
0xCC 发表于 2010-1-28 17:58
那你不是做了一个扩展语法而已吗,和其他的编译器有何区别,比如IAR,不过是添加自己的扩展语法而已。人家还支持标准C,你倒来了完全自己的语法,连标准C都不完全支持了,呵呵~~

网友评论:精神上支持;不过最好还是弄成与标准兼容的,方便移植;
楼主有这份精力,还不如把比较难的模块;做成自动生成代码的;这个可以参考飞思卡尔的processor expert;我觉得做得不错,但就是生成的注释太多了。文件本来可以整合成一个的它就要分两个;造成文件太多,找起来不易。
如果楼主能把AVR PIC 51 等芯片也做成与飞思卡尔的一样,相信比你这个仿keil的编译器会成功得多。

网友评论:能写编译器,比较牛了

网友评论:支持楼主,加油!

网友评论:hao,非常的好。
http://www.minyantech.com

网友评论:不说好与坏,楼主钻研的精神就值得小弟学习了~~

网友评论:我在linux下,没装rar解压器,故对LZ的编程思路也不慎了解。

但是正统思路应该是 bison Yacc 之类,不要再自己做轮子了。

如果我记得没错,IBM上还有篇教你用yacc做简单编译器的小文章。建议LZ看看。



估计LZ是自己写代码分析的,做这种事,应该先查查资料

网友评论:又不了解又要教导别人。。
乐子大了

网友评论:顶一下楼主。我也做了一个编译器,已经用到一个产品中,有时间交流一下。呵呵。我已经加你QQ了

网友评论:酱油打完了

网友评论:谢谢楼主!

浏览:(1701)| 评论( 0 )
博文评论

  • 昵 称:
  • 内 容:10~250个字符
  • 验证码: 验证码看不清楚?请点击刷新验证码
  •                      
  • 博文分类

    热点博文

    最新博文

    最新评论

    IC电子元件查询
    IC邮购网电子元件品质保障