单片机编程keilc51使用教程里面,UART #1不输出”hello world”。

近几年,车联网一直占据热搜榜居高不下,随着BAT大佬们的……
电力改变了世界,也造福了我们的生产生活。电力安全大于……
近日尼吉康在北京召开了关于锂离子二次电池的新品发布会……
1968年大众在汽车上使用了一个ECU,用于发动机的电子燃油……
以&极致突破创新&为主题,在7月26日的吹田……
演讲人:Jim时间: 10:00:00
演讲人:李思齐时间: 10:00:00
演讲人:张厚新时间: 10:00:00
预算:¥10000预算:¥10000
上海市上海市
Labview串口的使用
[导读]串行通讯终端与计算机之间或者计算机与计算机之间进行交换信息时,除了采用并行通讯方式之外,还经常采用串行通讯方式。并行通讯是指数据的各位同时进行传送,其有点是传送数据速度快,缺点是有多少位数据就需要多少
串行通讯终端与计算机之间或者计算机与计算机之间进行交换信息时,除了采用并行通讯方式之外,还经常采用串行通讯方式。并行通讯是指数据的各位同时进行传送,其有点是传送数据速度快,缺点是有多少位数据就需要多少根传输线,这在数据位数较多,传送距离较远时就不宜采用。串行通讯是指数据一位一位地按顺序传送,其突出优点是只需一根传输线,特别适应于远距离传输,缺点是传送速度较慢。本文引用地址: 在微机测量,控制系统中,目前串行数据的传输大多采用异步通讯的方式。同步通讯和异步通讯串行通讯分为同步传送和异步传送两种方式。? 同步传送方式要求通信双方以相同的速率进行,而且要准确地协调。它通过共享一个单个时钟或定时脉冲源以保证发送方和接受方准确同步。其特点是允许连续发送一组字符序列(而非单个字符),每个字符数据位数相同,没有起始位和停止位,效率高。? 异步传送方式不要求通信双方同步,发送方和接受方可以有各自的时钟源。为了能够实现通信,双方必须都遵循异步通信协议。在异步通信中,通信双方必须规定两件事:一是字符格式,即规定字符各部分所占的位数,是否采用奇偶校验,以及校验的方式;二是采用的波特率,以及时钟率与波特率之间的比例关系。由此可见,异步通信方式的传输效率比同步通信方式低,但它对通信双方的同步要求大大降低,因而成本也比同步通信方式低。DTE和DCE在串行通讯中,用于发送和接收数据的设备称为数据终端设备(Data Terminal Equipment 简写为DTE)。DTE既可以是一台计算机,也可以是一台只接收数据的打印机。用于连接DTE与数据通信网络的设备称为数据通信设备(Data Communications Equipment 简写为DCE),或称为数据电路终接设备。DCE既可以是一个调制解调器,也可以是简单的线路驱动器。波特率在串行通讯中还有一个重要的指标&&波特率(又称调制速率)。波特率定义为每秒钟传送二进制数码的位数,以位/秒(bit/s)为单位,亦称&波特&。在异步通讯中,波特率为每秒传送的字符数和每个字符位数的乘积,例如每秒传送的速率为120字符/秒,而每个字符又包含10位(1位起始位,7位数据位,1位奇偶校验位,1位停止位),则波特率为:120字符/秒&10位/字符=1200位/秒=1200波特注意:波特率与时钟频率不是一回事,时钟频率比波特率要高得多,通常在高16倍或64倍。由于异步通讯双方各用自己的时钟源采用较高频率的时钟,在一位数据内就有16位或64个时钟,捕捉正确的信号就可以得到保证,若时钟频率就是波特率,则频率稍有偏差就会发生接收错误。LabVIEW中的串行通讯选板安装完labVIEW8.2后,还需要安装VISA的驱动程序才能使用串口,驱动程序的下载地址为:ftp://ftp.ni.com/support/visa/drivers/win32/4.0/visa400full.exeLabVIEW中有关串口的函数选板如图,它位于函数&仪器I/O&串口下面举一个例子来说明串口是如何进行通讯的例:双机通讯1. 功能描述双机通信是在两台计算机之间进行串口通讯。一台计算机作为服务器,通过RS-232串口向外发送数据;另一台计算机作为客户机,接收由服务器发送来的数据。2. 串口引脚连接两台计算机的串口之间通过一根RS-232电缆线连接起来,串口电缆线采用三线制,它只使用发送数据(TxD),接收数据(RxD)和信号地(SG)三根信号线。3. 服务器程序设计其程序设计如下:㈠新建一个VI,在前面板上放置4个输入控件:&端口号&,&波特率&,&数据比特&和&停止位&。另外,放置一个字符串输入控件,在其内部输入向外发送的字符串数据。添加程序文本标签&串口服务器&。㈡在程序框图中放置一个层叠式顺序结构,创建两个分支。在第0分支中,放置一个&Serial Port Init.vi&函数,并添加一个顺序局部变量;在第1分支中,放置一个&Serial Port Write.vi&函数,它们位于labVIEW8.2&vi.lib&Instr&serial。连线如图:前面板如图:4.客户机程序设计与服务器程序类似,其中使用了&Bytes At Serial Port.vi&函数和&Serial Port Read.vi&它们都在前文所提到的路径中,客户机程序框图如图:前面板如图:串口的内容就为大家简单的介绍这么多,有什么问题可上我们的论坛发帖,我们会尽力为大家解答。
儿童市场被誉为&朝阳行业&、&常青行业&,不仅产品范围广泛、品类也非常丰富。近年来,儿童市场也成为了机器人产业发力的一个重要方向,陪伴机器人、教育机器人,以及编程机器人都成为了异军......关键字:
老实说,我在 20 岁时可没打算这样。我编程就是为了挣钱。只要编程还能挣钱,我就愿意一直这样挣下去,差不多就是这样。......关键字:
在讲述这个故事之前,我有一句话要说:编程是一件特别难的事情!成为优秀的程序员没有捷径,你要拥有高智商,要保持谦逊,还要不断的努力,犯错,在错误中成长,深刻理解你所学习的材料。但是有些人就是一定要寻找捷径,而其中之一,就是使用欺诈的手段。......关键字:
现在的编程代码全部都是英文,有没有可能有一天编程代码全是中文呢?而且如果当年计算机由中国人发明,编程代码是否就是以中文为主呢?......关键字:
来自一位对高考结果不满意,选择放弃上大学,自学走上IT工程师道路的新人自述。......关键字:
我 要 评 论
热门关键词
Cypress面议 | 上海市 浦东新区
Cypress面议 | 上海市 浦东新区
Cypress面议 | 上海市 浦东新区
Cypress面议 | 上海市 浦东新区
Cypress面议 | 上海市 浦东新区先说说为什么需要用GCC开发stm32吧,作为一名编程方面的爱好者,又是搞嵌入式的,总是用现成的IDE,感觉很不舒服,虽然IDE能很大提高咱们的工作效率,可是作为业余学习研究,还是越熟悉底层越好。比如如何搭建环境,如何使用编译器和编写makefile,这些搞过linux开发的都知道,而且 linux环境下没那么多IDE可用,而且也没必要用IDE.还有一个原因是,喜欢黑色的dos窗口下编程的感觉,IDE编辑环境太刺眼了,每次下班后都很累眼睛。
一、开发环境的搭建
在《一步步写嵌入式操作系统》一书中,讲到了如何搭建嵌入式开发环境,cygwin+arm-elf-gcc+make工具
1.首先从www.leeos.org网站中下载所需要的软件,可以用cygwin+skyeye+gcc
2.安装cygwin软件,安装步骤按照书上的进行,需要说明的是 :在进入cygwin setup-select packages界面时,必须选中devel包中的gcc4和make,我们还可以选中vim作为我们之后的编写环境,
就不用不停的在window界面下切换了。
3.安装编译环境arm-elf-gcc。 首先将leeos_tools_for_cygwin.tar.gz复制到D:\cygwin\usr中(我把cygwin装在了D盘,具体看自己情况),然后解压缩为leeos_tools_for_cygwin。打开cygwin,输入cd
/usr命令,切换到usr目录下,进行环境变量的设置,一次输入以下三条命令: echo "PATH=\$PATH:/usr/leeos_tools_for_Cygwin/bin"&&/etc/profile
echo "PATH=\$PATH:/usr/leeos_tools_for_Cygwin/libexec/gcc/arm-elf/4.4.2"&&/etc/profile
echo "PATH=\$PATH:/usr/leeos_tools_for_Cygwin/arm-elf/bin"&&/etc/profile 此时编译环境安装成功。我们可以打开看一下D:/cygwin/etc/profile文件,在该文件的最下边多了三句话 还要说明的一点是我们需要用chmod命令将三个目录下的所有exe文件设置一下权限,方法是chmod
777 *.exe 重启cygwin之后arm-elf-gcc就可以用了。
以上环境搭建的方法,摘自网络,百度一下有很多,我照着上面说的试了试,没有成功,再用arm-elf-gcc编译时出来了一堆提示汇编的错误,最后解决了,原来还是权限的问题。
二.编写makefile
上面的环境搭建好了,接下来就可以动手实验了。需要注意的是,下载的arm-elf-gcc编译器先看一下版本,听说只有4.2以上的才支持stm32.然后测试下编译器是否管用,随便写个c文件,用arm-elf-gcc -o2 -c hello.c -o hello.o测试下,成功生成hello.o说明环境搭建成功了。然后看一下make工具是否管用,make
-v查看一下。
开始写makefile,其实这一步也不是必须的,完全可以手动的去编译,但是makefile的确很强大,写好一次,保存为模板,很好用,编辑时直接mske就可以了。
不用makefile,你需要写很长的东西,如:
arm-elf-gcc -g -mcpu=cortex-m3 -mthumb -c uart_helloworld.c -nostartfiles -o uart_helloworld.o
arm-elf-gcc -g -mcpu=cortex-m3 -mthumb -c isr.c -nostartfiles -o isr.o
arm-elf-ld -T stm32f103vet6.ld -o helloworld.out uart_helloworld.o isr.o
arm-elf-objcopy -O binary helloworld.out helloworld.bin
写成makefile就省事多了,简单的写法如:
PREFIX := arm-elf-
.PHONY: all clean
all: helloworld.bin
uart_helloworld.o: uart_helloworld.carm-elf-gcc -g -mcpu=cortex-m3 -mthumb -c uart_helloworld.c -nostartfiles -o uart_helloworld.o
isr.o: isr.carm-elf-gcc -g -mcpu=cortex-m3 -mthumb -c isr.c -nostartfiles -o isr.o
helloworld.out: uart_helloworld.o isr.o stm32f103vet6.ldarm-elf-ld -T stm32f103vet6.ld -o helloworld.out uart_helloworld.o isr.o
helloworld.bin: helloworld.outarm-elf-objcopy -O binary helloworld.out helloworld.bin
clean:rm -f *.o *.out *.bin
这样写,虽然很清楚,文件的依赖关系等很明显,但是还是不够精简。这个就是一个简单的makefile,方便初学者学习和理解makefile原理。
以下是我整理了一份自己使用的模板:makefile
BINARY= main
PREFIX = arm-elf
CC = $(PREFIX)-gcc
LD = $(PREFIX)-ld
OBJCOPY = $(PREFIX)-objcopy
OBJDUMP = $(PREFIX)-objdump
CFLAGS= -mcpu=cortex-m3 -mthumb -nostartfiles
LDSCRIPT =standalone.ld
-T $(LDSCRIPT)
OBJS= main.o
.PHONY: clean
all:images
images: $(BINARY).hex $(BINARY).bin $(BINARY).srec $(BINARY).list
$(OBJS):%.o:%.c$(CC) -c $(CFLAGS) $& -o $@
%.elf: $(OBJS) $(LDSCRIPT)$(CC) $(CFLAGS) -o start.o -c start.s$(LD) -o $(*).elf start.o $(OBJS) $(LDFLAGS)
%.bin: %.elf$(OBJCOPY) -Obinary $(*).elf $(*).bin
%.hex:%.elf$(OBJCOPY) -Oihex $(*).elf $(*).hex
%.srec: %.elf$(OBJCOPY) -Osrec $(*).elf $(*).srec
%.list: %.elf$(OBJDUMP) -S $(*).elf & $(*).list
clean:rm -f *.orm -f *.drm -f *.elfrm -f *.binrm -f *.hexrm -f *.srecrm -f *.list
接下来,开始用GCC开发stm32了,先从简单的点灯开始......
用GCC开发STM32入门二
之前从网上下载了一份用GCC开发stm32的程序,也是用的stm32的库函数编程,启动文件是startup_stm32f10x_hd.s,
链接脚本文件是从gcc_ride7中拷贝出的stm32f10...
完整且超简化的linux下stm32开发环境(编译,下载)---测试中
完整且超简化的linux下stm32开发环境(编译,下载)
最近要用stm32开发产品,考虑到以前作高端arm,or32开发以及低端的avr开发都用gcc,因此为了降低学习难度和省钱,决定继续使...
如何使用GNU编译器GCC来编译Cortex-M3?GCC + STM32
这里有个德国人做的样例,各位可以参考下:
http://gandalf.arubi.uni-kl.de/avr_projects/arm_projects/index_cortex.html...
STM32F gcc编译全纪录
STM32Fgcc编译全纪录
使用Keil uVision编译的时候,有编译限制(32K,盗版的例外),正版的Keil,你懂的。为此想到了网上开源的编译器,大名鼎鼎的gcc编译器,大家都听过,但是对...
Keil5.15使用GCC编译器编译STM32工程
我们使用Keil一般使用ARMCC编译MCU工程代码.其实,Keil也是支持内嵌GCC编译器的.我们可以使用GCC来编译我们的工程代码.
下载GCC编译器GCC编译器下载地址
安装GCC我们可以把G...
我们使用Keil一般使用ARMCC编译MCU工程代码.其实,Keil也是支持内嵌GCC编译器的.我们可以使用GCC来编译我们的工程代码.
一、下载GCC编译器
GCC编译器下载地址
二、安装GC...
&em&stm32&/em& &em&gcc&/em& 编译器的链接脚本,含 Ram 和 FLash 如果使用ram需要在编译时加入 向量函数的设置,详见 外设 3.5 的readme.综合评分:0 收藏(1)评论举报 所需: 3...
一个利用&em&GNU&/em&开发&em&STM32&/em&的例程,使用修改过的makefile,集成库3.4与dsp库。具体看配套文章: http://blog.csdn.net/xuzhenglim/archive//5979313.aspx
&em&STM32&/em& FreeRTOS &em&GNU&/em&/&em&GCC&/em& arm-none-eabi-&em&gcc&/em&
因做linux嵌入式开发,所以工作平台在linux下居多,而市面上开发单片机的环境又是windows平台据多,
所以在linux平台下搭建stm32单片机的开发环境,现以作备忘
1,软件安装
没有更多推荐了,今天来谈一下keil中模块化编程的问题,模块化对于比较大型的程序很有帮助,一般都是C文件和H文件配合来形成模块,下面我就来谈谈二者的关系:
我认为:本质上没有任何区别。 只不过一般:.h文件是头文件,内含函数声明、宏定义、结构体定义等内容,.c文件是程序文件,内含函数实现,变量定义等内容。而且是什么后缀也没有关系,只不过编译器会默认对某些后缀的文件采取某些动作。你可以强制编译器把任何后缀的文件都当作c文件来编。
没图没证据,下面对同一个程序分别在keil中和GCC中编译。
//a.h中的内容
//不能和a.c中同时存在
//a.c中的代码
int a=10;//main.c中的内容
#include &reg52.h&
#include "a.c"
void main()
}下面开始编译main.c 里面#include "a.h"文件,
keli并不会报错,可以正常编译过去。但是换成#include "a.c",就是下面的图了:
若是换成了a.c的话并不会编译通过(有人会说这个错误是重复定义造成的,但是我在编译的时候已经把其H文件定义的那行注释掉了。)。但是如果在linux下编译的话,会怎么样,我试了一下,截图如下:
如上图,用gcc编译的话是可以通过的,也许有人认为上面的操作完全是做无用功,若如实,也权当我没事打发时间了。(include的功能就是把这句删掉,然后复制你所包含的文件中的内容到当前位置)
接下来谈一下编译过程:
main函数为标准C/C 的程序入口,编译器会先找到该函数所在的文件。假定编译程序编译myproj.c(其中含main())时,发现它include了mylib.h(其中声明了函void test()),那么此时编译器将按照事先设定的路径(Include路径列表及代码文件所在的路径)查找与之同名的实现文件,如果找到该文件,并在其中找到该函数的实现代码,则继续编译;如果在指定目录找不到实现文件,或者在该文件及后续的各include文件中未找到实现代码,则返回一个编译错误.
其实include的过程完全可以"看成"是一个文件拼接的过程,将声明和实现分别写在头文件及C文件中,或者将二者同时写在头文件中,理论上没有本质的区别。以上是所谓动态方式。
对于静态方式,基本所有的C/C 编译器都支持一种链接方式被称为Static Link,即所谓静态链接。在这种方式下,我们所要做的,就是写出包含函数,类等等声明的头文件a.h,b.h,...),以及他们对应的实现文件a.cpp,b.cpp,...编译程序会将其编译为静态的库文件(a.lib,b.lib,...)。在随后的代码重用过程中,我们只需要提供相应的头文件(.h)和相应的库文件(.lib),就可以使用过去的代码了。相对动态方式而言,静态方式的好处是实现代码的隐蔽性,即C
中提倡的"接口对外,实现代码不可见"。有利于库文件的转发。
接下来看一下我在微信上看到的一个问题:
void foo()?//a.c
#include "a.h"
//我的问题出来了:这句话是要,还是不要?
} //main.c
#include "a.h"
int main(int argc, char *argv[])
} 请回答三个问题:
1&a.c 中的 #include "a.h" 这句话是不是多余的?
2&为什么经常见 xx.c 里面 include 对应的 xx.h?
3&如果 a.c 中不写,那么编译器是不是会自动把 .h 文件里面的东西跟同名的
.c 文件绑定在一起?
(请针对上面3道题仔细考虑10分钟,莫要着急看下面的解释。:) 考虑的越多,下面
理解的就越深。)
好了,时间到!请忘掉上面的3道题,以及对这三道题引发出的你的想法,然后再
听我慢慢道来。正确的概念是:从C编译器角度看,.h和.c皆是浮云,就是改名为.txt、.doc也没有大的分别。换句话说,就是.h和.c没啥必然联系。.h中一般放的是同名.c文件中定义的变量、数组、函数的声明,需要让.c外部使用的声明。这个声明有啥用?只是让需要用这些声明的地方方便引用。因为 #include "xx.h" 这个宏其实际意思就是把当前这一行删掉,把 xx.h 中的内容原封不动的插入在当前行的位置。由于想写这些函数声明的地方非常多(每一个调用 xx.c中函数的地方,都要在使用前声明一下子),所以用 #include "xx.h" 这个宏就简化了许多行代码--让预处理器自己替换好了。也就是说,xx.h 其实只是让需要写 xx.c 中函数声明的地方调用(可以少写几行字),至于include这个.h 文件是谁,是.h 还是.c,还是与这个.h 同名的.c,都没有任何必然关系。这样你可能会说:啊?那我平时只想调用xx.c 中的某个函数,却include了 xx.h 文件,岂不是宏替换后出现了很多无用的声明?没错,确实引入了很多垃圾,但是它却省了你不少笔墨,并且整个版面也看起来清爽的多。鱼与熊掌不可得兼,就是这个道理。反正多些声明(.h一般只用来放声明,而放不定义)也无害处,又不会影响编译,何乐而不为呢?
翻回头再看上面的3个问题,很好解答了吧?
答:不一定。这个例子中显然是多余的。但是如果.c中的函数也需要调用同
个.c中的其它函数,那么这个.c往往会include同的.h,这样就不需要为声明和调用顺
序而发愁了(C语言要求使用之前必须声明,而include同名.h一般会放在.c的开头)。
有很多工程甚至把这种写法约定为代码规范,以规范出清晰的代码来。
答:1中已经回答过了。
答:不会。问这个问题的人绝对是概念不清,要不就是想混水摸鱼。
看书要看好书,问人要问强人。烂书和烂人都会给你一个错误的概念,误导你;
勤能补拙是良训,一分辛苦一分才;(1)通过头文件来调用库功能。在很多场合,
源代码不便(或不准)向用户公布,只要向用户提供头文件和二进制的库即可。用
户只需要按照头文件中的接口声明来调用库功能,而不必关心接口怎么实现的。编译器会 C语言中.h文件和.c文件详细解析从库中提取相应的代码。
(2)头文件能加强类型安全检查。如果某个接口被实现或被使用时,其方式与头
文件中的声明不一致,编译器就会指出错误,这一简单的规则能大大减轻程序员调
试、改错的负担。头文件用来存放函数原型。
头文件如何来关联源文件?
这个问题实际上是说,已知头文件"a.h"声明了一系列函数(仅有函数原型,没有函数
实现),"b.cpp"中实现了这些函数,那么如果我想在"c.cpp"中使用"a.h"中声明的这些
在"b.cpp"中实现的函数,通常都是在"c.cpp"中使用#include "a.h",那么c.cpp是怎样
找到b.cpp中的实现呢?其实.cpp和.h文件名称没有任何直接关系,很多编译器都可以
接受其他扩展名。
%3R谭浩强老师的《C程序设计》一书中提到,编译器预处理时,要对#include命令进行"文件包含处理":将headfile.h的全部内容复制到#include "headfile.h"处。这也正说明了,为什么很多编译器并不care到底这个文件的后缀名是什么----因为#include预处理就完成了一个"复制并插入代码"的工作。 程序编译的时候,并不会去找b.cpp文件
中的函数实现,只有在link的时候才进行这个工作。我们在b.cpp或c.cpp中用#include "a.h"实际上是引入相关声明,使得编译可以通过,程序并不关心实现是在哪里,是怎么实现的。源文件编译后成生了目标文件(.o或.obj文件),目标文件中,这些函数和变量就视作一个个符号。在link的时候,需要在makefile里面说明需要连接哪个.o或.obj文件(在这里是b.cpp生成的.o或.obj文件),此时,连接器会去这个.o或.obj文件中找在b.cpp中实现的函数,再把他们build到makefile中指定的那个可以执行文件中。
本文中的大部分内容都来自微信的推送文章,再次感谢下文章作者李师傅。
C/C++ 语言中.h文件和.c文件详细解析
引用 .c和.h文件的区别
预处理是编译器的前驱,作用是把存储在不同文件里的程序模块集成为一个完整的源程序.
#include本身只是一个简单的文件包含预处理命令,即为把include的后面文件放到这条命令这里,除此之外,没有其...
keil 创建多文件工程
第一步:新建一个工程文件夹,再在文件夹下新建inc、user、output、listing四个文件夹。
第二步:打开KEIL,新建工程并保存到上一步的新建的工程文件夹下。
第三部:在KEIL的工程...
当你的keil工程同时有c文件和CPP文件
当你的keil工程同时有c文件和CPP文件,那么c文件的函数在cpp文件中肯定无法访问了。
正常的include“”xxx.h“”那肯定是不行的,编译会提示说c文件中函数未定义。
那么只要稍微修改...
在 Keil5 中添加 .h 文件的问题
由于不是经常用到keil,所以有一些常识性的问题会忘记,因此特地写下来防止下次再忘记
一般来说的步骤:
得到text文件,然后文件名保存为xx.h,之后就直接在代码里用就好了;
今天自己看stm32在创建工程的时候,包含了一个库文件stm3210xR.LIB,而且自己还发现,我无法查看其中的内容!而且在我编译我的.c文件的时候,又发现了在.c文件里包含的许多的.h文件,在其下...
你可能已经很熟悉&em&keil&/em&的使用了,但&em&keil&/em&中有一个比较重要且很实用的文件,不知道...lib不是c代码,不能对它编辑,只能通过.&em&h文件&/em&调用。所以为了别人能使用你的lib,...
转载于:http://blog.csdn.net/yunfeiyang62/article/details/
Keil 下生成LIB库文件以及如何使用LIB库文件
从http://blog.csdn.net/gasbi/article/details/6761420的博客中看到了如何解决这个问题。
然后又从http://blog.csdn.net/CaesarZ...
C++中的头文件和源文件:如何写头文件
C++中的头文件和源文件
一、C++编译模式
通常,在一个C++程序中,只包含两类文件——.cpp文件和.h文件。其中,.cpp文件被称作C++源文件,里面放的都是C++的源代码;而.h文件则...
没有更多推荐了,一个简单的makefile示例及其注释  相信在unix下编程的没有不知道makefile的,刚开始学习unix平台下的东西,了解了下makefile的制作,觉得有点东西可以记录下。  下面是一个极其简单的例子:现在我要编译一个Hello world,需要如下三个文件:  1. print.h      #include&stdio.h&      void printhello();  2. print.c      #include"print.h"      void printhello(){        printf("Hello, world\n");      }   3. main.c      #include "print.h"      int main(void){        printhello();        return 0;      }  好了,很简单的程序了。如果我们想要编译成功需要哪些步骤呢?我认为在这里需要理解的就两步:  #
为每一个 *.c文件生成 *o文件。  #
连接每一个*o文件,生成可执行文件。下面的makefile 就是根据这样的原则来写的。一:makefile 雏形:#makefile的撰写是基于规则的,当然这个规则也是很简单的,就是:#target : prerequisites   command  //任意的shell 命令实例如下:makefile:    helloworld : main.o print.o #helloword 就是我们要生成的目标                 # main.o print.o是生成此目标的先决条件      gcc -o helloworld main.o print.o#shell命令,最前面的一定是一个tab键    mian.o : mian.c print.h      gcc -c main.c    print.o : print.c print.h      gcc -c print.c        clean :                  rm helloworld main.o print.o  OK,一个简单的makefile制作完毕,现成我们输入 make,自动调用Gcc编译了,输入 make clean就会删除 hellowworld mian.o print.o二:小步改进:  在上面的例子中我们可以发现 main.o print.o 被定义了多处,我们是不是可以向C语言中定义一个宏一样定义它呢?当然可以:makefile:    objects =
main.o print.o #应该叫变量的声明更合适    helloworld : $(objects) //声明了变量以后使用就要$()了      gcc -o helloworld$(objects)   
mian.o : mian.c print.h      gcc -c main.c    print.o : print.c print.h      gcc -c print.c        clean :                  rm helloworld $(objects)修改完毕,这样使用了变量的话在很多文件的工程中就能体现出方便性了。三:再进一步:  再看一下,为没一个*.o文件都写一句gcc -c main.c是不是显得多余了,能不能把它干掉?而且 main.c 和print.c都需要print.h,为每一个都写上是不是多余了,能不能再改进?能,当然能了:makefile:   
main.o print.o     helloworld : $(objects)       gcc -o helloworld$(objects)        $(objects) : print.h # 都依赖print.h   
mian.o : mian.c
#干掉了gcc -c main.c 让Gun make自动推导了。    print.o : print.c         clean :                  rm helloworld $(objects)好了,一个简单的makefile就这样完毕了,简单吧。
没有更多推荐了,

我要回帖

更多关于 单片机编程软件keil4 的文章

 

随机推荐