keil优化等级设置
KEIL编译环境优化等级说明
keil c51中优化级别意思2012-04-25 17:36Keil C51中的优化级别及优化作用级别说明0 常数合并:编译器预先计算结果,尽可能用常数代替表达式。
包括运行地址计算。
优化简单访问:编译器优化访问8051系统的内部数据和位地址。
跳转优化:编译器总是扩展跳转到最终目标,多级跳转指令被删除。
1 死代码删除:没用的代码段被删除。
拒绝跳转:严密的检查条件跳转,以确定是否可以倒置测试逻辑来改进或删除。
2 数据覆盖:适合静态覆盖的数据和位段被确定,并内部标识。
BL51连接/定位器可以通过全局数据流分析,选择可被覆盖的段。
3 窥孔优化:清除多余的MOV指令。
这包括不必要的从存储区加载和常数加载操作。
当存储空间或执行时间可节省时,用简单操作代替复杂操作。
4 寄存器变量:如有可能,自动变量和函数参数分配到寄存器上。
为这些变量保留的存储区就省略了。
优化扩展访问:IDATA、XDATA、PDATA和CODE的变量直接包含在操作中。
在多数时间没必要使用中间寄存器。
局部公共子表达式删除:如果用一个表达式重复进行相同的计算,则保存第一次计算结果,后面有可能就用这结果。
多余的计算就被删除。
Case/Switch优化:包含SWITCH和CASE的代码优化为跳转表或跳转队列。
5 全局公共子表达式删除:一个函数内相同的子表达式有可能就只计算一次。
中间结果保存在寄存器中,在一个新的计算中使用。
简单循环优化:用一个常数填充存储区的循环程序被修改和优化。
6 循环优化:如果结果程序代码更快和有效则程序对循环进行优化。
7 扩展索引访问优化:适当时对寄存器变量用DPTR。
对指针和数组访问进行执行速度和代码大小优化。
8 公共尾部合并:当一个函数有多个调用,一些设置代码可以复用,因此减少程序大小。
9 公共块子程序:检测循环指令序列,并转换成子程序。
Cx51甚至重排代码以得到更大的循环序列。
Keil-C51详细设置
Keil C51详细设置一.target名更改打开Keil后,左侧Project Workspace中的target可改,方法:右击Target——Manage Compnents——双击待修改项即可,若要添加,使用对话框内对应工具栏。
二.option for target 设置之TARGET项1 MEMARY MODELSmall:变量存储在内部ram里.Compact:变量存储在外部ram里,使用页8位间接寻址Large:变量存储在外部Ram里,使用16位间接寻址.我们一般使用Small来存储变量,就是说单片机优先把变量存储在内部ram里,如果内部ram 不够了,才会存到外部去.Compact的方式要自己通过程序来指定页的高位地址,编程比较复杂,如果外部ram很少,只有256个字节,那么对该256个字节的读取就比较快,用MOVX @Ri,A 或MOVX A,@Ri指令.如果超过256字节,那么要不断地进行切换的话,就比较麻烦.Compact模式适用于比较少的外部ram的情况.Large模式,是指变量会优先分配到外部ram里,用MOVX A,@DPTR或MOVX @DPTR,A来读取.要注意的是,3种存储方式都支持内部256字节和外部64k字节的ram.区别是变量的优先(或默认)存储在哪里的区别.除非你不想把变量存储在内部ram,才使用后面的Compact,Large模式.因为变量存储在内部ram里,运算速度比存储在外部ram要快的多,大部分的应用都是选择Small的模式.使用Small的方式:也不是说变量就不可以存储在外部,一样可以存储在外部,只是你要指定,比如:unsigned char xdata a;那么变量a就存储在外部的ram.unsigned char a;变量存储在内部ram.假如用Large的模式:unsigned char xdata a;那么变量a就存储在外部的ram.unsigned char a;变量存储在外部ram.这就是区别,就是说这几个选项只是影响没有特别指定变量的存储空间的时候,默认存储在哪里,比如上面的变量定义unsigned char a .2. CODE ROM SIZESmall: program 2K or less ;适用于89c2051这些芯片,2051只有2k的代码空间,所以跳转地址只有2k,编译的时候会使用ACALL AJMP这些短跳转指令,而不会使用LCALL,LJMP指令.如果你的代码跳转超过2k,那么会出错.Compact:2k functiongs ,64k program:表示每个子函数的程序大小不超过2k,整个工程可以有64k的代码.就是说在main()里可以使用LCALL, LJMP指令,但在子程序里只会使用ACALL,AJMP 指令.除非你确认你的每个子程序不会超过2k,否则不要用Compact方式.Large:64K program:表示程序或子函数都可以大到64k.使用code bank还可以更大.通常我们都选用该方式.Code Rom Size选择Large方式速度不会比Small慢很多,所以一般没有必要选择Compact和Small的方式.我们这里选择Large方式.3. OPERATINGNONE:不适用操作系统RTX51-TINY:使用TINY操作系统RTX-FULL:使用FULL操作系统Keil C51 提供了Tiny多任务操作系统,使用定时器0来做任务切换,效率很低,无实用价值。
英飞凌单片机关于keilC166的使用
关于Keil C166的使用单片机开发除了必要的硬件同样也离不开软件,我们写的程序要转化成CPU所能执行的机器码有两种方法:一是手工汇编,二是机器汇编。
机器汇编是通过汇编软件将源程序编程机器码。
Keil软件是目前最流行的开发单片机的软件工具,Keil编译器提供了包括C编译器,宏汇编,连接器,库管理和一个功能强大的仿真调试器等在内的完整的开发方案。
通过一个集成开发环境(uVision)将这些部分组合在一起。
KEIL软件有支持8位单片机的Keil C 51系列和支持16位单片机的Keil C 166系列。
在项目开发过程中并不是仅有一个源程序就足够了,还要为项目选择CPU确定编译,汇编,连接的参数,指定调试的方式,有一些项目还会由多个文件组成。
为管理和使用方便,Keil 引入了工程(Project)概念。
将这些参数和所需要的文件都加在一个工程中,只能对工程进行编译和连接等操作。
工程的详细设置:以下针对在使用XC164CS评估板过程中在Keil C166环境下的一些设置谈一下。
首先点击Project窗口中的Target1 Project->Option for Target1 “target 1”即出现对工程设置的对话框。
菜单如下图1:图1以下针对各个标签详细说明:Device选择所使用的CPU(即所选用的芯片)。
KEIL支持很多种CPU,当选中一款芯片以后右侧窗口还会有相应的芯片介绍。
此处选择Infineon XC164CS.系列芯片作为CPU。
Target窗口设置如下:图2这里可以设置时钟频率,片内和片外资源的选择及地址的设置。
其中Memory Model用于设置RAM使用情况,KEIL C 166编译器可支持7种存储类型。
TINY CPU处于非分段工作方式下,可产生高效的16位线性地址,并把代码和数据限制在64KB种。
不能使用far, huge, xhuge存储类型。
SAMLL 使用分段CPU方式,同样产生高效的代码,但代码和数据不再限制再64KB中,用户可通过far, huge, xhuge引用变量和函数COMPACT 一般用于代码少而数据多的场合HCOMPACT 一般用于代码多而数据少的场合MEDIUM 所有的函数调用默认为far调用,一般用于代码多而数据少的场合 LARGE 所有的函数调用默认为far调用,一般用于代码和数据多的场合HLARGE 所有的函数调用默认为far调用,一般用于代码和数据多的场合,不适合于C166系列CPU在仿真过程中如果使用片内FLASH,则选中Use On-chip ROM在仿真过程中如果使用片外RAM,则取消Use On-chip ROM复选框并设置ROM和RAM 空间起始地址及大小。
KEIL编译环境优化等级说明详解
KEIL编译环境优化等级说明详解
opTIon -》c/c++ -》language/code genderaTIon -》opTImizaTIon选项下的优化等级
优化级别说明(仅供参考):
则其中的Code Optimization 栏就是用来设置C51的优化级别。
共有9个优化级别(书上这么写的),高优化级别中包含了前面所有的优化级别。
现将各个级别说明如下:
0级优化:
1、常数折叠:只要有可能,编译器就执行将表达式化为常数数字的计算,其中包括运行地址的计算。
2、简单访问优化:对8051系统的内部数据和位地址进行访问优化。
3、跳转优化:编译器总是将跳转延至最终目标上,因此跳转到跳转之间的命令被删除。
1级优化:
1、死码消除:无用的代码段被消除。
2、跳转否决:根据一个测试回溯,条件跳转被仔细检查,以决定是否能够简化或删除。
2级优化:
1、数据覆盖:适于静态覆盖的数据和位段被鉴别并标记出来。
连接定位器BL51通过对全局数据流的分析,选择可静态覆盖的段。
3级优化:
1、窥孔优化:将冗余的MOV命令去掉,包括不必要的从存储器装入对象及装入常数的操作。
另外如果能节省存储空间或者程序执行时间,复杂操作将由简单操作所代替。
4级优化:
1、寄存器变量:使自动变量和函数参数尽可能位于工作寄存器中,只要有可能,将不为这些变量保留数据存储器空间。
2、扩展访问优化:来自IDATA、XDATA、PDATA和CODE区域的变量直接包含在操作。
Keil软件及其调试功能简介
Keil软件及其调试功能简介目前流行的51系列单片机开发软件是德国Keil公司推出的Keil C51软件,它是一个基于32位Windows环境的应用程序,支持C语言和汇编语言编程,其6.0以上的版本将编译和仿真软件统一为μVision(通常称为μV2)。
Keil提供包括C编译器、宏汇编、连接器、库管理和一个功能强大的仿真调试器等在内的完整开发方案,由以下几部分组成:μVision IDE集成开发环境(包括工程管理器①、源程序编辑器②、程序调试器③,见图2)、C51编译器、A51汇编器、LIB51库管理器、BL51连接/定位器、OH51目标文件生成器以及Monitor-51、RTX51实时操作系统。
应用Keil进行软件仿真开发的主要步骤为:编写源程序并保存—建立工程并添加源文件—设置工程—编译/汇编、连接,产生目标文件—程序调试。
Keil使用“工程”(Project)的概念,对工程(而不能对单一的源程序)进行编译/汇编、连接等操作。
工程的建立、设置、编译/汇编及连接产生目标文件的方法非常易于掌握。
首先选择菜单File-New…,在源程序编辑器中输入汇编语言或C语言源程序(或选择File-O pen…,直接打开已用其它编辑器编辑好的源程序文档)并保存,注意保存时必须在文件名后加上扩展名.asm(.a51)或.c;然后选择菜单Project-New Project…,建立新工程并保存(保存时无需加扩展名,也可加上扩展名.uv2);工程保存后会立即弹出一个设备选择对话框,选择CPU后点确定返回主界面。
这时工程管理窗口的文件页(Files)会出现“Target1”,将其前面+号展开,接着选择Source Group1,右击鼠标弹出快捷菜单,选择“Add File to Group ‘Source Group1’”,出现一个对话框,要求寻找并加入源文件(在加入一个源文件后,该对话框不会消失,而是等待继续加入其它文件)。
keil调试经验
KEIL调试高级技巧在调试状态,Debug 菜单项中的命令可以使用了,有关编译的工具栏按钮消失了,出现了一个用于运行和调试的工具栏,Debug 菜单上的大部份命令都有相应的快捷按钮。
从左到右依次是复位、运行、暂停、单步跟踪、单步、执行完当前子程序、运行到当前行、下一状态、打开跟踪、观察跟踪、反汇编窗口、观察窗口、代码作用范围分析、1#串行窗口、内存窗口、性能分析、工具按钮命令;然后按一下图示第二个“运行”按钮。
连接上相关的实验资源,本实验用一条8PIN的数据排线把实验仪的CPU部份的P1口(JP44)连接到八路指示灯部份的JP32。
这时你会看到实验仪的八个红色LED,轮流点亮,表示运行成功,也可以查看相关的变量和参数,非常方便。
⒈单步跟踪运行使用菜单Debug->Step 或上图第四个单步运行按钮或使用快捷键 F11 可以单步跟踪执行程序,在这里我们按下 F11 键,即可执行该箭头所指程序行,每按一次 F11,可以看到源程序窗口的左边黄色调试箭头指向下一行,如果程序中有Delay延时子程序,则会进入延时程序中运行。
⒉单步运行如果Delay 程序有错误,可以通过单步跟踪执行来查找错误,但是如果 Delay 程序已正确,每次进行程序调试都要反复执行这些程序行,会使得调试效率很低,为此,可以在调试时使用 F10 来替代 F11(也可使用菜单 Step Over 或相应的命令按钮),在 main 函数中执行到 Delay时将该行作为一条语句快速执行完毕。
为了更好的进行对比,我们重新进入仿真环境,将反汇编窗口关闭,不断按F10 键,可以看到在源程序窗口中的左边黄色调试箭头不会进入到延时子程序。
⒊全速运行点击工具栏上的“运行”按钮或按F5 键启动全速运行,全速执行程序,此时用户板上的 P1 口所接 LED 以流水灯状态显示。
⒋暂停点击工具栏上的按钮,此时用户板上的P1 口所接 LED 停止以流水灯状态显示,只有一个 LED 灯点亮(取决于暂停前的 P1 的值)。
Keil C51详细设置
Keil C51详细设置一.target名更改打开Keil后,左侧Project Workspace中的target可改,方法:右击Target——Manage Compnents——双击待修改项即可,若要添加,使用对话框内对应工具栏。
二.option for target 设置之TARGET项1 MEMARY MODELSmall:变量存储在内部ram里.Compact:变量存储在外部ram里,使用页8位间接寻址Large:变量存储在外部Ram里,使用16位间接寻址.我们一般使用Small来存储变量,就是说单片机优先把变量存储在内部ram里,如果内部ram不够了,才会存到外部去.Compact的方式要自己通过程序来指定页的高位地址,编程比较复杂,如果外部ram很少,只有256个字节,那么对该256个字节的读取就比较快,用MOVX @Ri,A 或MOVX A,@Ri指令.如果超过256字节,那么要不断地进行切换的话,就比较麻烦.Compact模式适用于比较少的外部ram的情况.Large模式,是指变量会优先分配到外部ram里,用MOVX A,@DPTR或MOVX @DPTR,A 来读取.要注意的是,3种存储方式都支持内部256字节和外部64k字节的ram.区别是变量的优先(或默认)存储在哪里的区别.除非你不想把变量存储在内部ram,才使用后面的Compact,Large模式.因为变量存储在内部ram里,运算速度比存储在外部ram要快的多,大部分的应用都是选择Small的模式.使用Small的方式:也不是说变量就不可以存储在外部,一样可以存储在外部,只是你要指定,比如:unsigned char xdata a;那么变量a就存储在外部的ram.unsigned char a;变量存储在内部ram.假如用Large的模式:unsigned char xdata a;那么变量a就存储在外部的ram.unsigned char a;变量存储在外部ram.这就是区别,就是说这几个选项只是影响没有特别指定变量的存储空间的时候,默认存储在哪里,比如上面的变量定义unsigned char a .2. CODE ROM SIZESmall: program 2K or less ;适用于89c2051这些芯片,2051只有2k的代码空间,所以跳转地址只有2k,编译的时候会使用ACALL AJMP这些短跳转指令,而不会使用LCALL,LJMP指令.如果你的代码跳转超过2k,那么会出错.Compact:2k functiongs ,64k program:表示每个子函数的程序大小不超过2k,整个工程可以有64k的代码.就是说在main()里可以使用LCALL, LJMP指令,但在子程序里只会使用ACALL,AJMP 指令.除非你确认你的每个子程序不会超过2k,否则不要用Compact方式.Large:64K program:表示程序或子函数都可以大到64k.使用code bank还可以更大.通常我们都选用该方式.Code Rom Size选择Large方式速度不会比Small慢很多,所以一般没有必要选择Compact和Small的方式.我们这里选择Large方式.3. OPERATINGNONE:不适用操作系统RTX51-TINY:使用TINY操作系统RTX-FULL:使用FULL操作系统Keil C51 提供了Tiny多任务操作系统,使用定时器0来做任务切换,效率很低,无实用价值。
Keil uVision4编译器代码空间优化指南 V1.0
Keil uVision4编译器代码空间优化指南目录摘要 (1)1.Keil链接定位器(Code Linker)设置 (2)2.未调用(UNCALLED)函数的处理 (5)3.编译优化等级设置 (7)3.1 全局代码优化 (7)3.2 局部代码优化 (8)3.3 优化设置中的注意事项 (9)4.8位机与16位机编译差异 (12)5.Keil C编程与调试技巧 (15)5.1 存储器类型 (15)5.2 C语言中嵌入汇编 (15)5.3 volatile修饰声明 (15)5.4 静态局部变量 (16)5.5 静态全局变量 (16)5.6 static 函数 (16)5.7 位域 (17)5.8 C51 intrins.h库文件 (17)5.9 指针 (17)5.10 C程序优化 (18)(1)程序结构的优化 (18)(2)代码的优化 (19)6.附录 (21)7.版本更新 (24)摘要随着家电产品的功能日益丰富、应用方案的平台化兼容趋势以及IoT概念下Wi-Fi通信处理的引入,对单片机的ROM及RAM空间大小提出了更高的要求。
但随着ROM空间增大,应用方案的成本也相应提高,在能够保证量产可靠性的前提下,优化程序代码是更为合理的选择。
然而,相对于16位单片机,8 bit MCU的编译效率存在无法避免的劣势(如高位运算指令、拓展指令集等)。
在实际应用中,考虑到应用程序指令密度以及计算复杂度不同,在不应用Keil编译器优化设置的情况下,8位机所编译生成的代码体积比16位机可能增大30%以上。
故本文针对中颖8 bit单片机所使用的Keil uVision4仿真平台,提出了5项代码空间优化方式。
需要注意,由于不同应用程序及编程语法在Keil编译器中的处理方式存在差异,故在使用文章中所涉及的优化方法时,应当设计适当验证实验,以保证软件在量产测试下的可靠性。
根据经验,采用本文的优化方式后,在将瑞萨16位单片机软件移植到中颖8位机上时,软件空间增大量可控制在10%左右。
MDK Keil编译器使用的一些设置
MDK Keil编译器编译窗口的设置在使用MDK Keil编译器时会遇到一些和编辑窗户设置相关的问题,如字体的大小、颜色,字符字符串的颜色等。
现按照配置(configuation)的顺序归纳如下:首先打开Keil编译界面,打开右上角的configuation(配置),如下图所示。
打开configuation后界面如下图。
1)EditorGeneral Editor Settings 中默认前两个勾上,View White Space若勾上,则会在空格的地方添加·····其界面如下所以此选项一般勾掉不选。
在右边的Function Dispiay 中三个不选,用不到。
中间的Look&Feel是设置显示效果的,1处Highlight Current Line是当前行高亮,Highlight matching and matched braces 是突出显示匹配的括号。
中间右边2处Files&Projects Handing 是设置文件和工程的,需要勾上Save Projects before entering debug和Save Projects before entering debug 可以在进入每次Debug之前保存文档和工程。
3处的是设置C/C++编译窗口的tab 键代表几个空格和显示行号,4处的是设置ASM(汇编)编译窗口的tab键代表几个空格和显示行号。
2)Colors&Fonts如下图:前三个分别是设置汇编窗口、C语言窗口、C++窗口的,现在先看C语言出口的,其他两个窗口类似。
1处是设置颜色和字体的,2处设置前景和后景的,下面主要说明从text往下的设置;Text Selection 是被选中的部分显示的颜色和背景颜色。
如下图背景蓝色,字体白色Number是选择数字的。
Operator是运算符的设置,主要设置分号逗号等。
keil 4 目标工具选项详解
Keil µVision 4 目标工具选项详解一、目标工具选项(Target Options …)µVision可以设置目标硬件的选项。
通过下图1中的工具栏2区域按钮或1区域菜单项Project -> Options for Target打开Options for Target对话框。
二、设备选项卡(device )在 Target页中设置目标硬件及所选CPU片上组件的参数。
如图2所示。
图2在图2中,各区域说明如下:1:显示当前选定的CPU的厂商名,CPU的型号,和编译工具。
2:是该cpu 的一些描述。
3:更改所使用的CPU,三、硬件目标设置选项卡(Target),见图3 所示。
图3在图3中,各区或详细说明如下:1:指定用晶振频率,可以用于模拟调试,仅反映外部振荡频率。
2:可以选择KEIL集成的实时操作系统RTX Kernel。
针对复杂的嵌入式应用,MDK内部集成了由ARM开发的实时操作系统(RTOS)内核RTX,它可以帮助用户解决多时序安排、任务调度、定时等工作。
值得一提的是,RTX可以无缝集成到MDK工具中,是一款需要授权的、无版税的RTOS。
RTX程序采用标准C语言编写,由RVCT编译器进行编译。
4:片外ROM设置,最多支持3块ROM(Flash),在Start栏输入起始地址,在Size栏输入大小。
若是有多片片外ROM,需要在7区域设置一个作为启动存储块,程序从该块启动;有几块ROM需要选中对应的3区域。
6:片内ROM设置。
设置方法同片外ROM,只是程序的存储区在芯片内集成。
9:使用 Cross-Module优化。
10:使用MicroLib库。
它旨在与需要装入到极少量内存中的深层嵌入式应用程序配合使用. 这些应用程序不在操作系统中运行. MicroLib进行了高度优化以使代码变得很小. 它的功能比缺省 C 库少,并且根本不具备某些 ISOC 特性. 某些库函数的运行速度也比较慢,例如,memcpy(). 与缺省 C 库之间的差异MicroLib与缺省 C 库之间的主要差异是: MicroLib不符合 ISO C 库标准. 不支持某些 ISO 特性, 并且其他特性具有的功能也较少.MicroLib不符合 IEEE 754 二进制浮点算法标准. MicroLib进行了高度优化以使代码变得很小. 无法对区域设置进行配置. 缺省 C 区域设置是唯一可用的区域设置. 不能将 main() 声明为使用参数,并且不能返回内容. 不支持 stdio,但未缓冲的 stdin,stdout 和 stderr 除外. MicroLib对 C99 函数提供有限的支持. MicroLib不支持操作系统函数. MicroLib不支持与位置无关的代码. MicroLib不提供互斥锁来防止非线程安全的代码.MicroLib不支持宽字符或多字节字符串. 与 stdlib 不同, MicroLib不支持可选择的单或双区内存模型. MicroLib只提供双区内存模型,即单独的堆栈和堆区. 可以合理地将MicroLib与 --fpmode=std 或 --fpmode=fast 配合使用. MicroLib中的函数负责: 创建一个可在其中执行 C 程序的环境.这包括: 创建一个堆栈创建一个堆(如果需要) 初始化程序所用的库的部分组成内容.11:指令集中也分为高字节结尾,大端模式。
M0+keil快速设置
Confidential
8
3. Group
图10 图9 ㆍ如图9所示鼠标右单击选择Add Existing Files to Group ‘Group’直接添加一个已有的File ㆍ文件路径(Blink test 示例范例) 1. System_A31G11x_series.c AC31G11x_Series\Core\Device\ABOV\A31G11x_series\Source 2. A31G11x_pcu.c; A31G11x_scucg.c; A31G11x_uartn.c; debug_frmwrk.c AC31G11x_Series\Drivers\source 3. main.c A31G11x_Series\Examples\Gpio_LedBlinky 4. startup_A31G11x_series_CM0P.s AC31G11x_Series\Core\Device\ABOV\A31G11x_series\Source\ARM
• 在Examples文件夹里面,存放的是示例代码。 Confidential
3
1. Folder
•
在Flashloader文件夹里面,存放的是编程算法文件flash file和readme.txt文件。
Confidential
4
2. 创建Project
1. 点击Menu Project 2. 点击New uVision Project...
A31G11x_Series
V1.0
Cortex-M0+
Compiler Setting - KEIL
1
목차
1. 2. 3. 4.
• • • • • • • • • •
MDK Keil 5软件小技巧
几乎所有玩ARM Cortex M单片机的坛友都是通过MDK Keil 5或者IAR环境进行单片机的程序开发的,俗话说工欲善其事必先利其器,我们天天都在用这个开发环境,那么,有些在MDK Keil 5中的实用功能小技巧,大家又知道多少呢?1.并不是所有源文件(.c)都需要加进工程中,只需要添加必要的源文件即可。
无论是什么开发环境,只要是C/C++的工程,工程编译时间的决定因素就是工程中的源文件,以STM32 HAL库的工程为例,单片机外设的驱动文件一般是【stm32fxxx_hal_xxx.c】的格式,里面有多少个这样的源文件,就代表这个工程启用了多少个STM32单片机的外设。
我们可以做个对比:我们使用STM32CubeMX生成一个工程,工程用到了外部高频、低频晶振、SPI1、USART1,CubeMX 自动生成的工程里面,源文件只有必要的十来个:然后我们把一些不必要用到的源文件也加进去,我这里索性把CubeF1固件库里面的全部外设驱动都加进去了,甚至包括一些完全没有必要加进去的template.c模版:可以看到,生成的Code大小差得非常远,我这里还是用ARMCCV6版本的编译器,还看不出前后两个工程的编译时间,如果是用ARMCCV5版本的,估计时间要差好几倍。
实际上前后两个工程,实现的效果完全是一样的,那些原本没有必要加进去的源文件,除了浪费编译空间和编译时间以外,没有任何用处。
2.头文件(.h)可以随便加进工程中。
在MDK的代码开发工程中,头文件是必不可少的。
头文件在工程的作用是提供宏定义/常量、结构体声明、枚举量声明统一放置的地方、函数的声明(甚至可以直接把函数的实现写在头文件里面,没有任何问题)。
在实际的开发过程中,经常要频繁修改宏定义,而传统MDK开发者的习惯一般是工程只添加源文件而不添加头文件,这样就使得修改宏定义变得非常麻烦了,我们应该摒弃这个习惯,把频繁使用的头文件加进工程中。
keil μVision 使用详解教程
3
捷键)、Templates(模板)、Other(其他),看似复杂其实这六个选项卡中大部分是我们不需要 改变的,我们只需要对“Colors & Fonts(颜色和字体)”选项卡进行更改就可以了。
选项卡下面的“Foreground”项下的 ,来选择对应的颜色,如图 1.1.5 所示,这里选择蓝 色,默认是黑色。
图 1.1.5 关键字颜色设置 将自己想要设置的项设置完,单击“OK”键返回软件界面。 如果是为了教学方便,要将程序编辑框铺满整个电脑铺满,可以依次单击“View->Full Screen”来达到目的,如图 1.1.6,要从满屏页面恢复到一般页面也是非常简单的,只要在满
2
第一章 Keil 的配置设置
在建立工程和编写程序之前最好将系统字体和关键字的颜色等信息进行设置一番,来使 软件更适合使用,下面我们就来对这些配置进行简单的设置。
有多种方式可以打开配置对话框,常用的有两种,既通过菜单的方式打开配置对话框和 点击快捷图标的方式打开配置对话框。菜单打开配置对话框的方法是依次单击 “Edit->Configuration...”如图 1.1.1 所示;单击快捷图标打开配置对话框是单击图标 来完成的。
点击“Project -> New μVision Project„”菜单,如图 2.1.2 所示。
8
图 2.1.2 创建工程选项 执行上面的操作就会出现一个对话框,为了管理方便最好新建一个文件夹,因为一个工 程里面会包含多个文件,一般以工程名为文件夹名来对该新建的文件夹取名,如图 2.1.3 所 示,在选择刚才建立的文件夹然后单击“打开”按钮,然后给将要建立的工程起一个名字, 你可以在编缉框中输入一个名字(这里设为 exam1), 不需要扩展名,如图 2.1.4 所示。
KEIL C51使用说明
20.1 工程项目的建立、源程序文件的建立及加载Keil C51软件UVision打开后,程序窗口的左边有一个项目工作区管理窗口,该窗口有3个标签,分别是Files、Regs和Books,这3个标签页分别显示当前项目的文件结构、CPU的寄存器及部分特殊功能寄存器的值(调试时才出现)和所选CPU的附加说明文件,如果是第一次启动Keil C51,那么这3个标签页全是空的(图20-1)。
图20-1 Keil C51打开后界面20.1.1 建立工程文件在单片机开发项目中,有时有多个的源程序文件,并且还要为项目选择CPU以确定编译、汇编、连接的参数,指定调试的方式等。
为便于管理,Keil C51使用工程项目(Project)的方法,将这些参数设置和所需的所有文件都放在一个工程项目中,只能对工程项目而不能对单一的源程序进行编译(汇编)和连接等操作。
一、先在硬盘上建立一个需保存工程文件的目录(例如在“我的文档” 中建立一个test的文件夹),为便于管理及使用,目录名称可与工程名称一致。
二、1、选择“工程>新工程”菜单(图20-2)。
弹出对话框,要求给将要建立的工程起一个名字,可以在编辑框中输入一个名字(例如test),扩展名不必输入(默认的扩展名为.uv2)。
点击“保存”按钮(图20-3)。
2、随后弹出一个“为目标target选择设备”(Select Device for Target “Target1”)对话框,这个对话框要求选择目标CPU(即你所用单片机开发板芯片的型号),Keil C51支持的CPU很多,我们选择Atmel公司的AT89C51(或AT89S51)芯片,用鼠标单击Atmel前的“+”号,选择“AT89C51(或AT89S51)”单片机后按确定(图20-4)。
随即系统弹出是否拷贝8051启动代码到工程项目并添加到当前项目组的提示(Copy Standard 8051 Startup Code to Project Folder and Add File to Project ?),我们选否。
Keil的代码优化产生的问题
Case/Switch优化:包含SWITCH和CASE的代码优化为跳转表或跳转队列。
5 全局公共子表达式删除:一个函数内相同的子表达式有可能就只计算一次。中间结果 保存在寄存器中,在一个新的计算中使用。
告诉Keil C51,这个地址不是一般的扩展RAM,而是连接的设备,具有“挥发”特性,每次读取都是有意义的。
可以修改变量定义,增加“volatile”关键字说明其特征:
unsigned char volatile xdata MAXl97_at_Ox8000;
也可以在程序中包含系统头文件:“#incIude”,然后在程序中修改变量,定义为直接地址:
本文中对原文提到的问题,提出了三种不同于原文的解决方法。每种方法都比原文中提到的方法更直接和简单,设计也更规范。(无意批评,请原文作者见谅)
1 问题回顾和分析
原文中提到:在实际工作中遇到对同一端口反复连续读取,Keil C5l编译并未达到预期的结果。原文作者对C编译出来的汇编程序进行分析发现,对同一端口的第二次读取语句并未被编译。但可惜原文作者并未分析没有被编译 的原因,而是匆忙地采用一些不太规范的方法试验出了两种解决办法。
而以上的问题,正是由于KeiI C5l编译优化产生的。因为在原文程序中将外设地址直接按如下定义:
unsigned char xdata MAXl97_at_Ox8000;
采用_at_将变量MAXl97定义到外部扩展RAM指定地址Ox8OOO。因此,Keil C51优化编译理所当然认为重复读第二次是没有用的,直接用第一次读取的结果就可以了,因此编译器跳过了第二条读取语句。至此,问题就一目了然了。
keil C51单片机内存优化
idata UCHaR c2;
但也不是绝的,如果 c1, c2 需要以极高的频率访问,而 tab 访问不那么频繁
则应该让访问量大的变量使用直接寻址:
data UCAHR c1;
data UCHaR c2;
#define LEN 120
data UCHAR tt1[LEN];
idata UCHAR tt2[127];
void main()
{
UCHAR i,j;
பைடு நூலகம்
for(i = 0; i < LEN; ++i )
{
j = i;
tt1[j] = 0x55;
对前面的代码,M51文件中关于内存一节如下:
* * * * * * * D A T A M E M O R Y * * * * * * *
REG 0000H 0008H ABSOLUTE "REG BANK 0"
DATA 0008H 0078H UNIT ?DT?TEST
IDATA 0080H 007FH UNIT ?ID?TEST
IDATA 00FFH 0001H UNIT ?STACK
第一行显示寄存器组0从地址0000H开始,占用0008H个字节
第二行显示DATA区变量从0008H开始,占用0078H个字节
该行表示从0010H开始连续0012H个字节未充分利用或根本未用到
出现这种情况最常见的原因是局变量太多、多个子程序中的局部变量数目差异太大、使用了寄存器切换但未充分利用
idata UCHAR tab[119];
这个是要根据具体项目需求来确定的
Keil编译与下载设置及常见问题解决方案
Keil编译与下载设置及常见问题解决方案这几天在群里朋友的帮助下学习了keil的编译与下载,现在将遇到的几个问题记录下来。
形成一个完整的教程。
为了帮助和我一样刚刚接触Keil的朋友,本文将分为两部分。
一,keil编译与下载设置。
二,常见问题原因分析与解决方案。
一,keil编译与下载设置首先看根据不同的MCU我们需要设置的项目有device,c/c++。
根据不同的下载器需要设置的项目有debug,utilities。
1.device的设置在device选项中search自己所要的芯片。
根据MCU的类型选择,其实就是修改HD或者是MD.3.DEBUG设置4.utilities设置二,常见问题原因分析与解决方案到此我将我遇到的问题一一展示给大家,一来自己复习巩固二来帮助小白更快的解决问题。
1)在device中没有我要的芯片?解决办法,到网上下载pack包加载到keil。
如图所示,在file中选择import...2)Error:Flash Download failed-”cortex-M3原因分析:flash download 设置错误解决办法:参考第一部分第3步骤3)No ULINK2/ME Decice found原因分析:Utilities设置错误解决方案:参见第一部分第4步骤4)编译过程中出现#67:expected a “}”原因分析:我是在跟换不同型号芯片时遇到的这个问题。
这两个芯片一个是大型,一个是中型,因此出现这样的问题。
解决方案:替换.S文件,修改C/C++宏定义方法:第一步:在.S文件中右键今入manage project items,add与芯片对应的.S的文件。
第二步:修改C/C++宏定义方案:参加第一部分第二步骤。
具体的就是修改一个字母H,M等。
评,根据实测这一步非常重要,其实.s文件不修改进修改c/c++宏定义就可以了。
具体原因我也不懂。
感谢再次特别感谢麒麟座开发板交流群的朋友,感谢晨风~依然、OneNET-嵌入式软件-周家绪悉心指导了我遇到的问题,他们都是群里真正的老司机。
keil程序debug用法
keil程序debug用法在Keil μVision中进行程序调试是嵌入式开发过程中的重要一环。
下面是在Keil中进行程序调试的基本步骤:1. 打开Keil μVision:启动Keil μVision集成开发环境。
2. 加载工程:打开或新建一个Keil工程,确保你的项目文件已加载。
3. 选择目标芯片:在“Project”菜单中,选择“Options for Target"。
在“Target”选项卡中,选择你的目标芯片型号。
确保芯片选型与你实际使用的芯片一致。
4. 配置调试工具:在“Flash Download”选项卡中,配置目标芯片的调试工具。
通常,你需要选择你的调试器型号,设置调试器连接参数。
5. 设置调试模式:在“Debug”菜单中,选择“Start/Stop Debug Session”以进入调试模式。
6. 添加断点:在你希望暂停程序执行的地方设置断点。
右键点击源代码的行号,选择“Toggle Breakpoint”或按下`F9`键。
7. 运行程序:在调试模式下,点击工具栏中的“Start/Stop Debug Session”按钮或按下`F5`键来运行程序。
当程序执行到设置的断点时,会暂停执行。
8. 查看变量值:在调试模式下,你可以查看和监视变量的值。
在“Watch”窗口中添加你感兴趣的变量,它们的值会在每次程序暂停时更新。
9. 单步执行:在调试模式下,你可以使用单步执行来逐行执行代码。
使用工具栏中的“Step Into”(F11), “Step Over”(F10), 和“Step Out”(Shift + F11)按钮。
10. 查看寄存器:在调试模式下,你可以查看和监视CPU寄存器的值。
在“Peripheral”窗口中选择“Register”标签。
11. 查看内存:在调试模式下,你可以查看和监视内存中的数据。
在“View”菜单中选择“Memory”来打开“Memory”窗口。
keil优化等级设置
keil优化等级设置优化级别说明(仅供参考):则其中的 Code Optimization 栏就是⽤来设置C51的优化级别。
共有9个优化级别(书上这么写的),⾼优化级别中包含了前⾯所有的优化级别。
现将各个级别说明如下:0级优化:1、常数折叠:只要有可能,编译器就执⾏将表达式化为常数数字的计算,其中包括运⾏地址的计算。
2、简单访问优化:对8051系统的内部数据和位地址进⾏访问优化。
3、跳转优化:编译器总是将跳转延⾄最终⽬标上,因此跳转到跳转之间的命令被删除。
1级优化:1、死码消除:⽆⽤的代码段被消除。
2、跳转否决:根据⼀个测试回溯,条件跳转被仔细检查,以决定是否能够简化或删除。
2级优化:1、数据覆盖:适于静态覆盖的数据和位段被鉴别并标记出来。
连接定位器BL51通过对全局数据流的分析,选择可静态覆盖的段。
3级优化:1、“窥孔”优化:将冗余的MOV命令去掉,包括不必要的从存储器装⼊对象及装⼊常数的操作。
另外如果能节省存储空间或者程序执⾏时间,复杂操作将由简单操作所代替。
4级优化:1、寄存器变量:使⾃动变量和函数参数尽可能位于⼯作寄存器中,只要有可能,将不为这些变量保留数据存储器空间。
2、扩展访问优化:来⾃IDATA、XDATA、PDATA和CODE区域的变量直接包含在操作之中,因此⼤多数时候没有必要将其装⼊中间寄存器。
3、局部公共⼦式消除:如果表达式中有⼀个重复执⾏的计算,第⼀次计算的结果被保存,只要有可能,将被⽤作后续的计算,因此可从代码中消除繁杂的计算。
4、 CASE/SWITCH语句优化:将CASE/SWITCH语句作为跳转表或跳转串优化。
5级优化:1、全局公共⼦式消除:只要有可能,函数内部相同的⼦表达式只计算⼀次。
中间结果存⼊⼀个寄存器以代替新的计算。
2、简单循环优化:以常量占据⼀段内存的循环再运⾏时被优化。
6级优化:1、回路循环:如果程序代码能更快更有效地执⾏,程序回路将进⾏循环。
7级优化:1、扩展⼊⼝优化:在适合时对寄存器变量使⽤DPTR数据指针,指针和数组访问被优化以减⼩程序代码和提⾼执⾏速度。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
优化级别说明(仅供参考):
则其中的Code Optimization栏就是用来设置C51的优化级别。
共有9个优化级别(书上这么写的),高优化级别中包含了前面所有的优化级别。
现将各个级别说明如下:
0级优化:
1、常数折叠:只要有可能,编译器就执行将表达式化为常数数字的计算,其中包括运行地址的计算。
2、简单访问优化:对8051系统的内部数据和位地址进行访问优化。
3、跳转优化:编译器总是将跳转延至最终目标上,因此跳转到跳转之间的命令被删除。
1级优化:
1、死码消除:无用的代码段被消除。
2、跳转否决:根据一个测试回溯,条件跳转被仔细检查,以决定是否能够简化或删除。
2级优化:
1、数据覆盖:适于静态覆盖的数据和位段被鉴别并标记出来。
连接定位器BL51通过对全局数据流的分析,选择可静态覆盖的段。
3级优化:
1、“窥孔”优化:将冗余的MOV命令去掉,包括不必要的从存储器装入对象及装入常数的操作。
另外如果能节省存储空间或者程序执行时间,复杂操作将由简单操作所代替。
4级优化:
1、寄存器变量:使自动变量和函数参数尽可能位于工作寄存器中,只要有可能,将不为这些变量保留数据存储器空间。
2、扩展访问优化:来自IDATA、XDATA、PDATA和CODE区域的变量直接包含在操作之中,因此大多数时候没有必要将其装入中间寄存器。
3、局部公共子式消除:如果表达式中有一个重复执行的计算,第一次计算的结果被保存,只要有可能,将被用作后续的计算,因此可从代码中消除繁杂的计算。
4、CASE/SWITCH语句优化:将CASE/SWITCH语句作为跳转表或跳转串优化。
5级优化:
1、全局公共子式消除:只要有可能,函数内部相同的子表达式只计算一次。
中间结果存入一个寄存器以代替新的计算。
2、简单循环优化:以常量占据一段内存的循环再运行时被优化。
6级优化:
1、回路循环:如果程序代码能更快更有效地执行,程序回路将进行循环。
7级优化:
1、扩展入口优化:在适合时对寄存器变量使用DPTR数据指针,指针和数组访问被优化以减小程序代码和提高执行速度。
8级优化:
1、公共尾部合并:对同一个函数有多处调用时,一些设置代码可被重复使用,从而减小程序代码长度。
9级优化:
1、公共子程序块:检测重复使用的指令序列,并将它们转换为子程序。
C51甚至会重新安排代码以获得更多的重复使用指令序列。
当然,优化级别并非越高越好,应该根据具体要求适当选择。
KeilC51的编译器有一个优化设置,不同的优化设置,会产生不同的编译结果。
一般情况缺省编译优化设置被设定为8级优化,实际最高可设定为9级优化:
1.Dead code elimination。
2.Data overlaying。
3.Peephole optimization。
4.Register variables。
mon subexpression elimination。
6.Loop rotation。
7.Extended Index Access Optimizing。
8.Reuse Common Entry Code。
mon Block Subroutines。
附表:Keil C51中的优化级别及优化作用级别说明
0常数合并:编译器预先计算结果,尽可能用常数代替表达式。
包括运行地址计算。
优化简单访问:编译器优化访问8051系统的内部数据和位地址。
跳转优化:编译器总是扩展跳转到最终目标,多级跳转指令被删除。
1死代码删除:没用的代码段被删除。
拒绝跳转:严密的检查条件跳转,以确定是否可以倒置测试逻辑来改进或删除。
2数据覆盖:适合静态覆盖的数据和位段被确定,并内部标识。
BL51连接/定位器可以通过全局数据流分析,选择可被覆盖的段。
3窥孔优化:清除多余的MOV指令。
这包括不必要的从存储区加载和常数加载操作。
当存储空间或执行时间可节省时,用简单操作代替复杂操作。
4寄存器变量:如有可能,自动变量和函数参数分配到寄存器上。
为这些变量保留的存储区就省略了。
优化扩展访问:IDATA、XDATA、PDATA和CODE的变量直接包含在操作中。
在多数时间没必要使用中间寄存器。
局部公共子表达式删除:如果用一个表达式重复进行相同的计算,则保存第一次计算结果,后面有可能就用这结果。
多余的计算就被删除。
Case/Switch优化:包含SWITCH和CASE的代码优化为跳转表或跳转队列。
5全局公共子表达式删除:一个函数内相同的子表达式有可能就只计算一次。
中间结果保存在寄存器中,在一个新的计算中使用。
简单循环优化:用一个常数填充存储区的循环程序被修改和优化。
6循环优化:如果结果程序代码更快和有效则程序对循环进行优化。
7扩展索引访问优化:适当时对寄存器变量用DPTR。
对指针和数组访问进行执行速度和代码大小优化。
8公共尾部合并:当一个函数有多个调用,一些设置代码可以复用,因此减少程序大小。
9公共块子程序:检测循环指令序列,并转换成子程序。
Cx51甚至重排
代码以得到更大的循环序列。
优化论
谈到优化,其实很多人都哭笑不得,因为在一个C51软件工程师的生涯中,总要被KEIL的优化耍那么一次到几次。
我被耍过,想必看着文章的你也被耍过,如果你回答说不,那只能说你写的C51程序不多!
看看KEILC的优化级别选项吧:
0-9共10个级别的优化,0是最低,9最高,一个普通的程序,设置最高级别和最低级别,编译后代码量有时会相差很远,以DX板DEMO程序为例,0级优化后是14K 的CODE,9级优化后是10K的CODE,前后相差了4K。
可见这个差别是多么的大。
事实上我们不需要知道对应的各个级别KEIL会如何优化你的程序或优化了些什么,我们只需要以一种严谨的态度去编写和对待你的程序就可以了。
在我个人的观念中,程序在9级优化后依然能保持完美无误的运行,你才算了解KEIL的脾气。
好了,还是说点正点的:
有些人习惯整体程序都选择同一个优化级,事实上每个C文件都可以有独立的优化级别的:
在工作区右键选择你的模块(.C)然后选取Options for File xxx就会出现如下界面:
在C51选项中就可以选择优化级别和警告级别等东西了,被独立设置过的C文件会有特殊的标记的:
用以提醒你这个文件的编译处理并非默认设置!
如果你觉得模块优化都不够细的话,你可以考虑局部优化,也就是说对某个函数实
行某个级别的优化。
当你发现9级优化的时候某个函数总是变的不正常,但你又希望其它函数和程序段保持最高的简洁度,那么局部优化可以说是相当有用的了。
在KEIL手册中有介绍这个功能:
#pragma OPTIMIZE(x)x就是你希望的优化级别,一般应用如下:
#pragma OPTIMIZE(6)
void FunA()
{
}
......
......
#pragma OPTIMIZE(9)
void FunB()
{
}
上面的意思就是说,在void FunA()到void FunB()之前的所有函数,包括FunA在内,都采用6级的优化,而从FunB开始直到之后,只要没碰上#pragma OPTIMIZE,都采用9级优化了。
OPTIMIZE还可以多一个参数,就是speed和size,
用法:#pragma OPTIMIZE(9,speed)或#pragma OPTIMIZE(5,size)
对应的就是9级优化,以速度为主,或5级优化,以空间最小为主。
在实际使用时发现仿真时有写程序是白色的无法进行断点设置
搜索到的答案是优化等级过高,一些普通的程序被优化。
只得把优化程序等级降低。