搭建并配置Keil嵌入式开发环境,完成一个基于STM32汇编程序的编写
作者:快盘下载 人气:59目录
一、环境配置1、准备工作2、安装keil软件3、安装stm32pack 二、keil简单设置三、stm32简单程序编译;LED)闪烁1、新建工程2、新建main.c文件3、编译程序4、stm32程序仿真调试1;调试前的设置2;开始调试 四、HEX文件字节内容一、环境配置
1、准备工作
下载打包好的安装包
链接; https://pan.xunlei.com/s/VNDqEoit-Uw3jrsaEPMekrv_A1
提取码;s74j
链接;https://pan.xunlei.com/s/VNDqF6qVVrIUFD0yOLBJsmL_A1
提取码;vum8
解压安装包;开始安装
2、安装keil软件
在刚解压的文件中;双击打开mdk531.exe软件;一路默认安装完成
3、安装stm32pack
在刚解压的文件中;双击打开keil.STM32F1xx_DFP.2.1.0.pack
;一路默认安装完成。
二、keil简单设置
下载好了 keil 后;我们需要进行一些简单的设置
;1;首先点击Edit→Configuration…;或者直接点工具栏的扳手图标;进入设置界面。
;2;设置编码形式为Chinese GB2312(Simplified);如果不设置;你从其它地方粘贴过来的代码含有中文的话;就会出现乱码;然后设置Tab size为4。
;3;进入Color & Fonts;选中C/C;; Editor files;选中中间窗口内的元素后;可以在右侧修改样式;比如设置字体、大小、颜色、背景;Sample是设置后预览效果。
三、stm32简单程序编译;LED)闪烁
1、新建工程
;1;打开project->New uVision Project…
;新建一个工程
;2;在左侧的窗口内选择STM32芯片;这里我们选择STM32F103RB;并保存。
;3;勾选相应的选项;并点击OK;这样工程创建完毕。
2、新建main.c文件
;1;工程创建完毕后;在左上角点击新建文件;然后窗口出现了一个Text1的文件。
;2;然后将下列代码复制粘贴到Text1文本框内。
//宏定义;用于存放stm32寄存器映射
#define PERIPH_BASE ((unsigned int)0x40000000)//AHB #define APB2PERIPH_BASE (PERIPH_BASE ; 0x10000) #define GPIOA_BASE (APB2PERIPH_BASE ; 0x0800) //GPIOA_BASE=0x40000000;0x10000;0x0800=0x40010800;该地址为GPIOA的基地址 #define GPIOB_BASE (APB2PERIPH_BASE ; 0x0C00) //GPIOB_BASE=0x40000000;0x10000;0x0C00=0x40010C00;该地址为GPIOB的基地址 #define GPIOC_BASE (APB2PERIPH_BASE ; 0x1000) //GPIOC_BASE=0x40000000;0x10000;0x1000=0x40011000;该地址为GPIOC的基地址 #define GPIOD_BASE (APB2PERIPH_BASE ; 0x1400) //GPIOD_BASE=0x40000000;0x10000;0x1400=0x40011400;该地址为GPIOD的基地址 #define GPIOE_BASE (APB2PERIPH_BASE ; 0x1800) //GPIOE_BASE=0x40000000;0x10000;0x0800=0x40011800;该地址为GPIOE的基地址 #define GPIOF_BASE (APB2PERIPH_BASE ; 0x1C00) //GPIOF_BASE=0x40000000;0x10000;0x0800=0x40011C00;该地址为GPIOF的基地址 #define GPIOG_BASE (APB2PERIPH_BASE ; 0x2000) //GPIOG_BASE=0x40000000;0x10000;0x0800=0x40012000;该地址为GPIOG的基地址 #define GPIOA_ODR_Addr (GPIOA_BASE;12) //0x4001080C #define GPIOB_ODR_Addr (GPIOB_BASE;12) //0x40010C0C #define GPIOC_ODR_Addr (GPIOC_BASE;12) //0x4001100C #define GPIOD_ODR_Addr (GPIOD_BASE;12) //0x4001140C #define GPIOE_ODR_Addr (GPIOE_BASE;12) //0x4001180C #define GPIOF_ODR_Addr (GPIOF_BASE;12) //0x40011A0C #define GPIOG_ODR_Addr (GPIOG_BASE;12) //0x40011E0C #define BITBAND(addr, bitnum) ((addr & 0xF0000000);0x2000000;((addr &0xFFFFF)<<5);(bitnum<<2)) #define MEM_ADDR(addr) *((volatile unsigned long *)(addr)) #define LED0 MEM_ADDR(BITBAND(GPIOA_ODR_Addr,8)) //#define LED0 *((volatile unsigned long *)(0x422101a0)) //PA8 //定义typedef类型别名 typedef struct { volatile unsigned int CR; volatile unsigned int CFGR; volatile unsigned int CIR; volatile unsigned int APB2RSTR; volatile unsigned int APB1RSTR; volatile unsigned int AHBENR; volatile unsigned int APB2ENR; volatile unsigned int APB1ENR; volatile unsigned int BDCR; volatile unsigned int CSR; } RCC_TypeDef; #define RCC ((RCC_TypeDef *)0x40021000) //定义typedef类型别名 typedef struct { volatile unsigned int CRL; volatile unsigned int CRH; volatile unsigned int IDR; volatile unsigned int ODR; volatile unsigned int BSRR; volatile unsigned int BRR; volatile unsigned int LCKR; } GPIO_TypeDef; //GPIOA指向地址GPIOA_BASE,GPIOA_BASE地址存放的数据类型为GPIO_TypeDef #define GPIOA ((GPIO_TypeDef *)GPIOA_BASE) void LEDInit( void ) { RCC->APB2ENR|=1<<2; //GPIOA 时钟开启 GPIOA->CRH&=0XFFFFFFF0; GPIOA->CRH|=0X00000003; } //粗略延时 void Delay_ms( volatile unsigned int t) { unsigned int i,n; for (n=0;n<t;n;;) for (i=0;i<800;i;;); } int main(void) { LEDInit(); while (1) { LED0=0;//LED熄灭 Delay_ms(500);//延时时间 LED0=1;//LED亮 Delay_ms(500);//延时时间 } }
;3;复制粘贴完后;点击左上角保存按钮;在弹出的窗口内;输入文件名main.c;如果不加后缀;就不会是.c文件;;点击保存;而后Text1文件就变成了main.c文件。
;4;右键点击 Source Group 1 ;然后点击 Add Existing Files to Group …;在工程下添加main.c文件;
;5;选中main.c文件;再点击Add;然后关闭窗口;此时你会发现;Source Group 1 文件下新增了一个main.c文件。
3、编译程序
点击左上角编译按钮;开始编译程序;此时0错误;0警告;表示编译成功。

文件大小如图;

4、stm32程序仿真调试
1;调试前的设置
;1;首先点击 魔法棒;然后在弹出的窗口内;点击 Debug;勾选 Use Simulator ;再选择 ULINK2/ME Cortex Debugger ;并点击 Settings 。
;2;确定一下Port是JTAG;Reset可以设置为Autodetect或SYSRESEETREQ;然后点击OK返回上一级窗口;再点击OK。
2;开始调试
选中带有红色d的放大镜开始调试;然后利用调试工具开始进行调试操作

寄存器的值如图;

可以看到;寄存器R5,R6,R7,R8的值和程序设置一致。
四、HEX文件字节内容
1;.hex文件是什么
它是由一行行符合Intel HEX 文件格式的文本所构成的ASCII 文本文件。每一行包含一 个 HEX 记录 ;由对应机器语言码和/或常量数据的十六进制编码数字组成。Hex文件通常用于传输将被存于ROM 或者EPROM 中的程序和数 据。大多数EPROM 编程器或模拟器使用Intel HEX 文件。Hex文件是可以烧写到单片机中;被单片机执行的一种文件格式;生成Hex文件的方式由很多种;可以通过不同的编译器将C程序或者汇编程序编译生成hex。
2;.hex文件的数据格式

Intel HEX 由任意数量的十六进制记录组成。每个记录包含5个域;每一组字母 对应一个不同的域;每一个字母对应一个十六进制编码的数字。每一个域由至少两个十六进制编码数字组成;它们构成一个字节。
;(冒号) 每个Intel HEX 记录都由冒号开头;
LL 是数据长度域, 它代表记录当中数据字节 (D…D) 的数量;
aaaa 是地址域, 它代表记录当中数据的起始地址;
TT是代表HEX 记录类型的域 , 它可能是以下数据当中的一 个;
00; 数据记录;Data Record;;用来记录数据;HEX文件的大部分记录都是数据记录。
01; 文件结束记录;End of FileRecord;;用来标识文件结束;放在文件的最后;标识HEX文件的结尾。
02; 扩展段地址记录;ExtendedSegment Address Record;;用来标识扩展段地址的记录;扩展段地址记录(HEX86);它包含4~19位数据地址段。由于普通的Intel的HEX记录文件只能记录64K的地址范围;所以大于64K的地址数据要靠扩展段地址记录。
03; 开始段地址记录;Start Segment Address Record;
04; 扩展线性地址记录;Extended Linear Address Record;;用来标识扩展线性地址的记录;扩展线性地址记录也叫32位地址记录或者HEX386记录;这些记录包含了数据在存储器里真实地址的高16位。 当一个扩展线性地址记录被读取后;将一直保持有效;直到它被另一个扩展地址记录改变。因为它记录的是后面数据在存储器里存放的真实起始地址;所以它的起始地址偏移量;Load offset;总是0000。
05; 开始线性地址记录;Start Linear Address Record;;32位机;80386或更高的CPU;的EIP寄存器里存放的地址;main函数的入口地址;。
D…D是数据域;它代表一个字节的数据。一个记录可以有许多数据字节。记录当中数据字节的数量必须和数据长度域(LL)中指定的数字相符。
CC是校验和域;它表示这个记录的校验和。校验和的计算是通过将记录当中所有十六进制编码数字对的值相加;以256为模进行以下补足。
记录格式可表示为;“;[1字节长度][2字节地址][1字节记录类型][n字节数据段][1字节校验和] ”
3;举例说明

如图;其中第一行 :020000040800F2 中;可以看做是0x02 0x00 0x00 0x04 0x08 0x00 0xf2
第一个0×02表示该行数据中有两个数据
第二个;第三个0x00 0x00表示本行数据的起始地址位
第四个字节 0x04 表示扩展线性地址记录;对应上述的TT域
第五个、第六个 0x08 0x00表示数据字节;与**数据长度域(LL)**中对应;即第一个 0x02
最后一个字节0xf2为校验和。校验和= 0x100 - 累加和
说明;第1行只有 0x08 0x00 两个字节的数据;类型是 04 ;即该行记录的是一个拓展地址(0x08 0x00 是地址信息;用法是将该地址;0x0800<<16) 后作为基地址。并且表示在下一个 04 类型行出现之前都要使用该地址。
第2行的地址信息是 0x0000,则表示该行数据从0x08000000; ;0x0800<<16) | 0x0000 ;开始记录。
第3行则从 0x08000010 ; ;0x0800<<16) | 0x0010 ;开始记录。
加载全部内容