搭建并配置Keil嵌入式开发环境,完成一个基于STM32汇编程序的编写
作者:快盘下载 人气:目录
一、环境配置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 ;开始记录。
加载全部内容