内容包括Keil MDK ARM和Keil C51安装,Keil5.12警告与错误的处理,程序的编译与调试等。紫色文字是超链接,点击自动跳转至相关博文。持续更新,原创不易!
目录:
一、Keil MDK ARM和Keil C51安装
1、Keil MDK ARM安装
1)以5.12版说明 2)注册 3)Help >> About uVision中查看自己安装的工具链
4)如何让 keil MDK v5 支持 ARM7/9 设备
2、Keil C51安装
1)以c51v952说明 2)注册 3)删除原来的C51,用此C51
4)STC单片机的头文件导入 5)Help >> About uVision中查看自己安装的工具链
二、Keil5.12警告的处理
1、一般介绍
2、文件的末尾增加空白行警告
3、出现“invalid multibyte character sequence”
三、Keil5.12错误的处理(STM32使用J-Link仿真相关汇总)
1、去除“STM32F10X_MD”
2、文件名中有C的关键字,报“Malformed via file”
3、__use_no_semihosting was requested, but _ttywrch was referenced
4、应用程序发生异常未知的软件异常(0xc0000409),位置为0x0a36a6f7
5、出现identifier "bool" is undefined
6、出现“No space in execution regions with .ANY selector match Section”
7、隐藏的文件处理
8、图标错乱
9、地址空间溢出
10、Registered ARM Compiler ignored,Version needs to be 5 or higher
11、explicit type is missing ("int" assumed)
12、Keil5.14.0.0版本编译通过的程序,在Keil5.12.0.0版本运行出错
13、STM32单片机模拟仿真晶振处出不来
14、MDK无法更新Package(pack软件包镜像下载)
15、array index 10 is past the end of the arry
四、RAM和ROM
1、查看内存
2、ARM单片机RAM和ROM
1)ARM编译结果(可看代码量) 2)ARM映像文件的组成 3)ARM映像文件的存储地址映射
五、ARM单片机Keil5.12正确配置Flash截图
1、Devie设置 2、Target设置 3、Output设置 4、Listing设置 5、User设置
6、C/C++设置 7、Asm设置 8、Linker设置 9、Debug设置 10、Utilities设置
六、Keil MDK ARM输出汇编与fromelf.exe生成.bin文件
1、设置按下图
2、文件存放
3、使用fromelf.exe生成.bin文件
七、MDK LIB库文件的制作与C文件生成静态库
1、打开一个测试通过的工程
2、打开KEIL MDK->Project->Option for target...->Output,选 中Create Executable:....选项
3、重新编译,即可在原本生成Hex文件的目录下找到*.lib文件
4、打开原工程,只需将原来的dsp_g2.c文件移除,添加进该.lib文件即可使用
5、使用指令生成.lib文件(Keil C51测试通过)
6、C文件生成静态库(如何将C文件生成静态库)
八、程序编辑
1、从任意位置选择程序的多行
2、Keil5.12中文注释代码或粘贴后乱码
1)中文注释代码乱码 2)复制粘贴后乱码(复制粘贴代码变乱码)
3、Keil5.12代码补全功能
4、支持C99模式
5、Keil使用AStyle格式化代码
九、程序调试
1、查看硬件的状态
2、周期性Watch窗口更新(变量随着程序更新)
3、Watch窗口以十进制显示
4、使用串口调试程序
5、程序中事先进行中断的“埋点”处理
6、硬仿真查看代码运行时间
7、watch中添加的变量不能实时更新
8、调试串口的软件仿真方法
图1.1.1
----------------------
2)注册
图1.2.1
注:Win7/64位Keil必须用管理员运行
图1.2.3
----------------------
3)Help >> About uVision中查看自己安装的工具链
图1.2.4
----------------------
4)如何让 keil MDK v5 支持 ARM7/9 设备
For maintaining existing MDK Version 4 projects, or using devices that are not yet supported by a Software Pack, please install Legacy Support for ARM 7/9 or Cortex-M. Refer to the Device Database for Legacy Support device coverage.
原来,keil-5 的安装包突然变那么小是因为裁掉了很多老版的设备,如一些 Cortex-M 系列的和 ARM7、9系列的。
MDK v4 Legacy Support
图1.2.5
----------------------------------------------
2、Keil C51安装
1)以c51v952说明
图2.2.1
----------------------
2)注册
图2.2.2
余下的操作同上。
----------------------
3)删除原来的C51,用此C51
图2.2.3
----------------------
4)STC单片机的头文件导入
图2.2.4
----------------------
5)Help >> About uVision中查看自己安装的工具链
图2.2.5
--------------------------------------------------------------------------------------------------------
二、Keil5.12警告的处理
1、一般介绍
打开keil的帮助文档,help->uVision help ,本处以搜索#550-D为例说明:
图2.1.1
打开倒数第二项,suppress这行,由文档可知,这个语句的作用是禁止某一类warning;
若禁止“已设置但未用”警告, 在相关的文件里添加代码:#pragma diag_suppress 550;
如有很多文件,打开“options for target”,在C/C++选项中,可以看到有个Misc Controls选项,如图2.2.2处理。
----------------------------------------------
2、文件的末尾增加空白行警告
图2.2.1
打开工程配置菜单,点击C/C++选项卡,在Misc Controls里面输入:--diag_suppress=1
图2.2.2
图2.2.2的2处绿圆中的“1”对应图2.2.1编译处的“#1-D”的“1”。----------------------------------------------
3、出现“invalid multibyte character sequence”
1)某个文件的代码中加入#pragma diag_suppress 1,550,870
2)或在“Misc Controls”中输入:--diag_suppress=1,550,870,......
--------------------------------------------------------------------------------------------------------
三、Keil5.12错误的处理(STM32使用J-Link仿真相关汇总)
3.1.0 软件版本
----------------------------------------------
1、去除“STM32F10X_MD”
编译后报错如下:
原来的设置如下,后来突然就没有此选项(原因不明)。
图3.1.1
这样就只能安装知识包,将下图中的STM32F10X_MD去掉即可解决。
图3.1.2
在编译环境中预先定义USE_STDPERIPH_DRIVER的意义:
打开stm32f10x.h头文件,可以找到如下语句
图3.1.3
也就是说只有预先定义了USE_STDPERIPH_DRIVER后,才会包含stm32f10x_conf.h头文件。在stm32f10x_conf.h中,包含了各个驱动脚本的头文件。
图3.1.4
这也是为什么有些头文件并没有手动添加却自动包含了进来的原因。
----------------------------------------------
2、文件名中有C的关键字,报“Malformed via file”
报错startup_stm32f10xx.s: error: A3906U: Malformed via file'.\debug\startup_stm32f10xx._ia'.
you might be using special character like '#" for directory name under which you put your project.
就是在放工程的目录名不能使用象“#”那样的特殊符号。
The easy solution is to make sure, the directory name under which you have your project files should not have any special characters.
e.g. your project path :C:\Users\acer\Desktop\myProject#2\App Code\Application\s310\arm
Here the directory "myProject#2" is invalid path for keil, if you remove the special character from directory name then it will compile without any error.
或将工程放置在全英文路径下,最简单方法,可以直接将文件放在桌面
----------------------------------------------
3、__use_no_semihosting was requested, but _ttywrch was referenced
如果加载了库文件(该库包含有打印输出到串口、memcpy()等函数),则要点选“Use MicroLIB”。
图3.3.1
图3.3.2
MicroLIB是缺省 C 库的备选库。 它用于必须在极少量内存环境下运行的深层嵌入式应用程序。 这些应用程序不在操作系统中运行。MicroLIB不会尝试成为符合标准的 ISO C 库。
MicroLIB进行了高度优化以使代码变得很小。 它的功能比缺省 C 库少,并且根本不具备某些 ISO C 特性。某些库函数的运行速度也比较慢,例如,memcpy()。
----------------------------------------------
4、应用程序发生异常未知的软件异常(0xc0000409),位置为0x0a36a6f7
应用程序发生异常未知的软件异常(0xc0000409),位置为0x0a36a6f7
原因:当前使用J-LINK进行仿真,但驱动使用了ST-Link的。
图3.4.2
----------------------------------------------
5、出现identifier "bool" is undefined
编译IEC104规约时出现“..\..\HARDWARE\INC\IEC104.h(159): error: #20: identifier "bool" is undefined”
在stm32f103.h中添加 typedef enum {FALSE = 0, TRUE = !FALSE} bool; 就没有错误了。
图3.5.1
----------------------------------------------
6、出现“No space in execution regions with .ANY selector match Section”
图3.6.1
1)分析
这个出现的原因是因为芯片RAM空间不足,无法执行程序。通常RAM的空间会比较小,ROM空间相对较大。
--------------------------
2)解决办法
(1)扩大RAM,更换芯片
比如这里将STM32F103VCT6(0xC000)更改为STM32F103VDT6或STM32F103VET6(0x10000)。
图3.6.2
(2)减少需要存在RAM里的内容
尝试修改”Target Options“中右侧RAM的Size,但这个要先查看芯片文档,找到文档中描述的RAM大小,把Size调成最大值。但是我的这个工程还是不行,看来是预存的数据量太大了。
如果第一种方法还是不行,那就只能尝试把一些数据类的变量定义为静态,这样就可以利用ROM的存储空间了。找到工程中存储数据的部分,发现是大量的float数组。这种情况会占用大量的空间,所以要在float声明的前面加一个”const“,转换为静态变量。这样我的就可以通过了,成功生成了hex文件。
如果第二种方法还是不行,那就只能修改代码的数据结构了。
----------------------------------------------
7、隐藏的文件处理
图3.7.1
Keil直接编译掩藏的文件会报错,按下图设置。
图3.7.2
----------------------------------------------
8、图标错乱
图3.8.1
界面的菜单栏有个"Windows"菜单,单击”Windows“菜单下的"Reset View to Default"。如果运行还是不行,这时就将keil软件关闭,打开重试。一般会恢复正常。如果您的图标还是错误,那您就在关闭软件,打开在点”Reset View to Default“,这样反复重复几遍。
----------------------------------------------
9、地址空间溢出
图3.9.1
图3.9.2
small模式未指定存储类型的变量默认为data,data有128字节 可以直接寻址,但是并不是全部分配给变量,其中通用寄存器组0 要占8个字节,用于主程序,因此超过120字节的变量就要溢出 。
可以用 idata修饰 idata为间接寻址 速度稍慢,可以把速度要求不严格的变量放在idada 或者放在xdata片外RAM,xdata的访问速度是最慢的。
51单片机的内部RAM是128字节,128~255字节是SFR(特殊功能寄存器),超出的都会存放到扩展RAM中,最大可以扩展64K外部RAM。直接DATA访问0~127,128~255用idata访问,再多的用xdata。
或者直接就在程序之前声明然后数组的话,类型为code,直接编译时候写到ROM
其他的话就用xdata,STC会根据内存空间自动分配是否在RAM里。慎用large模式。
----------------------------------------------
10、Registered ARM Compiler ignored,Version needs to be 5 or higher
PC机时间不对。
----------------------------------------------
11、explicit type is missing ("int" assumed)
图3.11.2
----------------------------------------------
12、Keil5.14.0.0版本编译通过的程序,在Keil5.12.0.0版本运行出错
Keil5.14.0.0版本编译通过的程序,在Keil5.12.0.0版本运行时会造成程序的时钟变慢,如果有闪烁指示灯会非常明显的感觉到闪烁变长。
----------------------------------------------
13、STM32单片机模拟仿真晶振处出不来
图3.13.1
Dialog DLL默认是DARMSTM.DLL;Parameter默认是-pSTM32F103VC。
若未做相应设置,调试时程序一直停在SystemInit()等待晶振出不来。
----------------------------------------------
14、MDK无法更新Package(pack软件包镜像下载)
----------------------------------------------
15、array index 10 is past the end of the arry
数组下标越界
--------------------------------------------------------------------------------------------------------
四、RAM和ROM
1、查看内存
1)“字母:数字”,D、 I、 X、 C分别代表着直接寻址的片内RAM、间接寻址的片内RAM、扩展的外部RAM和ROM。
切记:查看内存仅限于模拟仿真时。
图4.1.1
2)保存memory中的数据,注意保存下来的文件是HEX386格式的,可以通过其他工具转换成BIN格式。
“Command”中用“SAVE”命令:
SAVE path filename addr1, addr2
SAVE E:\ 0x0000,0x0100
3)keil编译后会产生.M51或者.map文件,在这里面也可看到内存的使用情况。
4)C程序中查看某一个变量在内存中的地址,比如下面的ChannelKindFault变量
通过串口输出:printf("\r\nSRAM Address:%x",&ChannelKindFault);
----------------------------------------------
2、ARM单片机RAM和ROM
ARM程序(指在ARM系统中正在执行的程序,而非保存在ROM中的bin文件)的组成一个ARM程序包含3部分:RO段,RW段和ZI段。
1)ARM编译结果(可看代码量)
另可参看:单片机C语言程序与数据存储之二、C语言程序的存储区域。
----------------------
2)ARM映像文件的组成
所谓ARM映像文件就是指烧录到ROM中的bin文件,也成为image文件。以下用Image文件来称呼它。 Image文件包含了RO和RW数据。之所以Image文件不包含ZI数据,是因为ZI数据都是0,没必要包含,只要程序运行之前将ZI数据所在的区域一律清零即可。包含进去反而浪费存储空间。
ARM程序的执行过程:
从以上两点可以知道,烧录到ROM中的image文件与实际运行时的ARM程序之间并不是完全一样的。因此就有必要了解ARM程序是如何从ROM中的image到达实际运行状态的。
实际上,RO中的指令至少应该有这样的功能:
(1)将RW从ROM中搬到RAM中,因为RW是变量,变量不能存在ROM中。启动过程另可见main函数之前都发生了什么。
(2)将ZI所在的RAM区域全部清零,因为ZI区域并不在Image中,所以需要程序根据编译器给出的ZI地址及大小来将相应得RAM区域清零。ZI中也是变量,同理:变量不能存在ROM中。
在程序运行的最初阶段,RO中的指令完成了这两项工作后C程序才能正常访问变量。否则只能运行不含变量的代码。
------------------------
更为详细的讲解搜索百度云盘“嵌入式网络那些事LwIP协议深度剖析与实战演练”的第三章3.1.4 ARM连接器。
一个映像文件(image)一般由一个或多个域组成,而往往在image中的位置同域在实际存储器的的位置俱有对应关系。
图4.2.2
----------------------
3)ARM映像文件的存储地址映射
图4.2.3
--------------------------------------------------------------------------------------------------------
五、ARM单片机Keil5.12正确配置Flash截图
图5.0.1
----------------------------------------------
1、Devie设置
图5.1.1
----------------------------------------------
2、Target设置
图5.2.1
----------------------------------------------
3、Output设置
图5.3.1
----------------------------------------------
4、Listing设置
图5.4.1
----------------------------------------------
5、User设置
图5.5.1
----------------------------------------------
6、C/C++设置
图5.6.1
----------------------------------------------
7、Asm设置
图5.7.1
----------------------------------------------
8、Linker设置
图5.8.1
----------------------------------------------
9、Debug设置
图5.9.1
----------------------------------------------
10、Utilities设置
图5.10.1
--------------------------------------------------------------------------------------------------------
六、Keil MDK ARM输出汇编与fromelf.exe生成.bin文件
图6.0.1
1、设置按下图
图6.1.1
----------------------------------------------
2、文件存放
在“Project\LIST目录下方”
----------------------------------------------
3、使用fromelf.exe生成.bin文件
命令:fromelf.exe --bin -o "[email protected]" "#L"
图6.3.1
编译后的输出结果:
图6.3.2
在使用KEIL的时候,我们要使生成的hex文件转化成bin文件,方便下载或fireware更新,有时候看到的是一个目录,遇到这种情况是什么问题呢!
比如说这个命令:fromelf.exe --bin -o "[email protected]" "#L", 这个也许就生成了一个bin目录文件,这个是为什么呢?
首先看一下链接脚本,发现里面有几个段的定义,其实我们需要的只是代码段,那么我们只需要修改这条命令为:
fromelf.exe --bincombined -o "[email protected]" "#L",把--bin 改成 --bincombined, 这样子我们就达到了我们所需要的bin文件,它可以把多个负载段生成一个输出文件。
--------------------------------------------------------------------------------------------------------
七、MDK LIB库文件的制作与C文件生成静态库
另可参考:STM32标准库编译成lib库文件、如何将C文件生成静态库。
1、打开一个测试通过的工程
如果本来要打包的库文件里面的代码有错的话,打包成库后也是不能用的,这步是关键。
图7.1.1
测试没有问题后将不需要的部分删除
图7.1.2
----------------------------------------------
2、打开KEIL MDK->Project->Option for target...->Output,选 中Create Executable:....选项
图7.2.1
----------------------------------------------
3、切记:需要重新编译,即可在原本生成Hex文件的目录下找到*.lib文件
----------------------------------------------
4、打开原工程,只需将原来的dsp_g2.c文件移除,添加进该.lib文件即可使用
----------------------------------------------
5、使用指令生成.lib文件(Keil C51测试通过)
1)在编译通过的工程目录里找到delay1s.obj和delay5ms.obj文件,复制到Keil安装目录下的BIN文件夹内。
图7.5.1
----------------------
2)打开上图中突显的LIB51.EXE。在上面输入以下代码:
图7.5.2
----------------------
3)这时在BIN中就出现了mylib.lib文件,它已经被添加了之前的两个延时程序。
图7.5.3
----------------------
4)复制这个库到LIB中,并添加进该.lib文件即可使用
使用指令生成.lib文件在Keil MDK中测试没有通过。
----------------------------------------------
6、C文件生成静态库(如何将C文件生成静态库)
--------------------------------------------------------------------------------------------------------
八、程序编辑
1、从任意位置选择程序的多行
-------------------------------------------
2、Keil5.12中文注释代码或粘贴后乱码
1)中文注释代码乱码
在新版本的KEIL中,总有人反映中文注释会出现乱码。出现这种情况,对于中文注释程序的人来说,无疑是一件十分不爽的事情。但实际解决这个问题其实很简单,在Edit/Configuration里如下图:
图8.3.1
图8.3.2
设置一下代码补全功能。
-------------------------------------------
4、支持C99模式
程序中加入“#include "complex.h"”报需要“C99 mode or gnu mode”
图8.4.1
-------------------------------------------
5、Keil使用AStyle格式化代码
1、查看硬件的状态
图9.1.1
-------------------------------------------
2、周期性Watch窗口更新(变量随着程序更新)
图9.2.1
-------------------------------------------点到Trace”标签下,若选择“SW”,则勾选“Enable”选项,在“Core”框中输入MCU实际工作时钟频率(就是单片机以什么频率来执行指令,MDK会用它来计算时间),再勾选“Autodetect max SW0 Clock”。
图9.6.1
若选择“JTAG”,先勾选“Enable”,在“Core”中设好时钟频率,最后去掉刚才勾选的“Enable”
进入仿真,界面右下角就会有时间窗口:
图9.6.4
鼠标放在上面右键点击,就会有:
图9.6.5
上面两个是复位“t1”和“t2”的,下面3个是选择在状态栏上显示哪个时间。
“t0”表示程序开始运行到现在的时间,是不能复位的。另外两个可以随便复位,就可以用来测具体某一个函数或某一行程序的运行时间。
具体方法:在要测试的代码前加一个断点,当程序运行到目标行时会停下,然后复位“t1”或“t2”,并在下一行代码前加断点,然后继续运行程序,程序会停在下一行代码前,这个时候“t1”的值就是目标行程序的运行时间。
图9.6.6
运行两次程序,如图9.6.2晶振处设置0.072MHz,故时间单位mS,1010.27mS。
-------------------------------------------
7、watch中添加的变量不能实时更新
图9.7.1