《第三章第二节thumb2指令集及汇编格式》由会员分享,可在线阅读,更多相关《第三章第二节thumb2指令集及汇编格式(56页珍藏版)》请在金锄头文库上搜索。
1、第二讲第二讲thumb-2指令集、指令集、IAR汇编及固汇编及固件库件库Thumb-2指令集n同时支持16位和32位指令系统nBit15:11q0b11101q0b11110q0b11111紧邻的两个半字构成一条32位指令q其他:皆为16位指令1 前索引2 后索引32位指令解码n.N表明此指令为16位指令n.W表面此指令为32位指令集n如果没有,则根据指令的15:11位自动选择nWFEn等待一个事件发生nWFIn等待一个中断发生汇编语言设计n汇编语言程序设计更能充分发挥处理器的硬件特性n两个优势q操作系统移植需要编写几百行底层硬件的汇编语言程序,这是C语言不可取代的。q优化算法的时空效率,C语
2、言的目标代码优化是编译器完成的,而汇编语言的目标代码优化是人工完成的。人是算法的创造者,也是编译器的设计者,人工优化比编译器质量高。n弱点q编程效率低,开发周期长,经济代价大。ARM汇编程序编写规范n汇编语句格式qARM汇编中,所有标号必须在一行的顶格书写,q而所有指令均不能顶格书写。qARM汇编器对标识符大小写敏感(即区分大小写字母),书写标号及指令时字母大小写要一致。q在ARM汇编程序中,ARM指令、伪指令、寄存器名可以全部为大写字母,也可以全部为小写字母,但不要大小写混合使用。q源程序中,语句之间可以插入空行,以使得源代码的可读性更好。ARM汇编程序编写规范(续)q格式如下:n标号标号
3、;注释注释n源程序中允许有空行。适当地插入空行,可以提高源程序的可读性。n如果单行代码太长,可以使用字符“”将其分行。“”后不能有任何字符,包括空格和制表符等。n对于变量的设置、常量的定义,其标识符必须在一行的顶格书写。汇编指令错误的例子DOBMOVR0,#1;标号DOB没有顶格书写MOV R2,#3;命令不允许顶格书写Loop Mov R2,#3;指令中大小写混合Bloop;无法跳转到loop标号,大小写;不一致几个重要伪指令1.1.DCB:DCB: 标号标号 DCB DCB 表达式表达式 说说明明:DCBDCB用用于于分分配配一一块块字字节节单单元元并并用用伪伪指指令令中中指指定定的的表表
4、达达式式进进行行初初始始化化。其其中中,表表达达式式可可以以为为使使用用双双引引号号的的字字符符串串或或0 0255255的数字的数字,DCB,DCB可用可用“= =”代替。代替。2.2.DCD/DCDUDCD/DCDU: 标号号 DCD/DCDU DCD/DCDU 表达式表达式 说明:明:DCDDCD伪指令用于分配一指令用于分配一块字字存存储单元并用元并用伪指令中指定指令中指定的表达式初始化,它定的表达式初始化,它定义的存的存储空空间是字是字对齐的。的。DCDDCD也可用也可用“& &”代替。代替。几个重要指令3.3.MODULE用于定义一个汇编模块,可用NAME,或PRAGRMA替代一般作
5、为汇编源文件名如:PROGRAMhello几个重要指令4.4._iar_program_start在IAR环境中,定义IAR程序入口处,是默认的5.PUBILC声明外部函数或公有函数(变量)如PUBLIC_iar_program_start声明一个外部的变量,将该入口地址告知其他源文件以及编译器几个重要指令6. 6. _vector_table在IAR中,具有特殊意义,定义了中断向量的入口7.SECTION定义一个程序段,如:SECTION.intvec:CODE:ROOT(2);程序段,定义中断向量nDATAn_vector_tablenDCD0x20000000;定义中断向量的入口地址(c
6、m3中的主堆栈地址)nDCD_iar_program_startSECTION.text:CODE:REORDER(2);一下可写具体代码几个重要指令8. 8. main在IAR中,对于汇编此标号也是需要的,不是程序入口,而是作为主堆栈的标志可以在设置中修改,但一般不做修改9.code16和code32作为16位指令和32位指令开始的标志等同于THUMB和ARM10 ENDnEND指示符告诉编译器已经到了源程序结尾。q语法格式:qENDq使用说明:n每一个汇编源程序都包含END指示符,以告诉本源程序的结束。内嵌汇编n内嵌汇编(inlineassembly)的语法如下:asm(“指令”);asm
7、(“指令”);内嵌汇编代码举例#includevoidstr_cpy(constchar*src,char*dst)intch;nasm(movr0,#1);nasm(movr0,#1);nasm(addr0,r1);IAR的固件库n由ST公司开发,包括驱动程序和应用函数的函数库n版本:3.4n优点:q入手快q便于开发,节约时间n缺点:q结构复杂繁琐q原理不够清晰PPP:某一外设名称说明n每一个外设都有一个对应的源文件:stm32f10x_ppp.c和一个对应的头文件:stm32f10x_ppp.hn文件stm32f10x_ppp.c包含了使用外设PPP所需的所有固件函数n文件stm32f10
8、x_ppp.h包含了.c文件所需的预定义,函数声明以及变量定义等n同时,外设需要在时钟控制下工作,因此会用到时钟的头文件说明nCM3对包括外设的所有存储设备统一编址,因此在头文件中包含了存储器的映射关系stm32f10x_map.hn该文件也包含了所有寄存器的声明n用户文件与库文件通过stm32f10x_lib.h建立关系,该文件中定义了所有外设头文件的头文件,用于声明头文件,因此需要include在用户的文件中n而文件stm32f10x_conf.h则指定具体的参数,用户可以对此文件进行修改外设的操作步骤nPPP代表任意外设n1.在主应用文件中,声明一个结构PPP_InitTypeDef,例
9、如:PPP_InitTypeDefPPP_InitStructure;这里PPP_InitStructure是一个位于内存中的工作变量,用来初始化一个或者多个外设PPP。外设的操作步骤n2.为变量PPP_InitStructure的各个结构成员填入允许的值。按照如下程序设置整个结构体PPP_InitStructure.member1=val1;PPP_InitStructure.member2=val2;PPP_InitStructure.memberN=valN;n3.调用函数PPP_Init(.)来初始化外设PPP。n4.在这一步,外设PPP已被初始化。可以调用函数PPP_Cmd(.)来使
10、能之。PPP_Cmd(PPP,ENABLE);可以通过调用一系列函数来使用外设。每个外设都拥有各自的功能函数。外设的操作步骤n注:n1.在设置一个外设前,必须调用以下一个函数来使能它的时钟:RCC_AHBPeriphClockCmd(RCC_AHBPeriph_PPPx,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_PPPx,ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_PPPx,ENABLE);n2.可以调用函数PPP_Deinit(.)来把外设PPP的所有寄存器复位为缺省值:PPP_DeInit(P
11、PP)外设的操作步骤n注:n3.在外设设置完成以后,继续修改它的一些参数,可以参照如下步骤:PPP_InitStucture.memberX=valX;PPP_InitStructure.memberY=valY;PPP_Init(PPP,&PPP_InitStructure);仅为arm公司粗略设计的存储器映射图,不同厂家根据需要,设计自己的存储器映射(对应)关系,以及各存储器的大小。关于存储器映射关系Bit-Bandn处理器存储器映射包括两个bit-banding区域。它们分别为SRAM和外设存储区域中的最低的1MB。n作用:将存储器别名区的一个字映射为bit-band区的一个位n即:在别
12、名存储区写入一个字具有对位段区的目标位执读-改-写操作的相同效果。n目的:所有STM32F10x外设寄存器都被映射到一个位段(bit-band)区。在各个函数中对单个比特进行置1/置0操作时被大量使用,用以减小和优化代码尺寸。Bit-BandBit-Bandn如何对应?n映射公式:nbit_word_offset=(byte_offsetx32)+(bit_number4)nbit_word_addr=bit_band_base+bit_word_offsetn其中:nbit_word_offset是目标位在存取器位段区中的位置bit_word_addr是别名存储器区中字的地址,它映射到某个目
13、标位。nbit_band_base是别名区的起始地址。nbyte_offset是包含目标位的字节在位段的序号bit_number是目标位所在位置(0-31)Bit-Bandexamplen设置地址0x2000_0000中的比特2,则:bit_word_offset=(byte_offsetx32)+(bit_number4)=0*32+2*4=8bit_word_addr=bit_band_base+bit_word_offset=0x22000000+8=0x2200008examplen设置地址0x2000_0000中的比特2,则:寄存器RCC_CR的PLLON24位,映射到别名区:#de
14、finePERIPH_BASE(u32)0x40000000)#definePERIPH_BB_BASE(u32)0x42000000)#defineRCC_OFFSET(RCC_BASE-PERIPH_BASE)#defineCR_OFFSET(RCC_OFFSET+0x00)#definePLLON_BitNumber0x18#defineCR_PLLON_BB(PERIPH_BB_BASE+(CR_OFFSET*32(PLLON_BitNumber*4)n一、什么是GPIO?nGPIO,英文全称为General-PurposeIOports,也就是通用IO口。嵌入式系统中常常有数量众多,
15、但是结构却比较简单的外部设备/电路,对这些设备/电路有的需要CPU为之提供控制手段,有的则需要被CPU用作输入信号。而且,许多这样的设备/电路只要求一位,即只要有开/关两种状态就够了,比如灯亮与灭。对这些设备/电路的控制,使用传统的串行口或并行口都不合适。所以在微控制器芯片上一般都会提供一个“通用可编程IO接口”,即GPIO。Example:GPIO控制n硬件资源分配:硬件资源分配:nPC6-PC9分别连到4个LED,定义为LED14跑马灯实验控制过程n点亮LEDn相应管脚输出高电平n即相应管脚置1n管脚如何控制?n特殊寄存器(端口配置寄存器)Example:GPIO控制nGPIO寄存器结构n
16、GPIO寄存器结构,GPIO_TypeDef和AFIO_TypeDef,在文件“stm32f10x_map.h”中定义如下:ntypedefstructnvu32CRL;nvu32CRH;nvu32IDR;nvu32ODR;nvu32BSRR;nvu32BRR;nvu32LCKR;nGPIO_TypeDef;ntypedefstructnvu32EVCR;nvu32MAPR;nvu32EXTICR4;nAFIO_TypeDef;Example:GPIO控制n五个GPIO外设声明于文件“stm32f10x_map.h”:n#definePERIPH_BASE(u32)0x40000000)n#d
17、efineAPB1PERIPH_BASEPERIPH_BASEn#defineAPB2PERIPH_BASE(PERIPH_BASE+0x10000)n#defineAHBPERIPH_BASE(PERIPH_BASE+0x20000).n#defineAFIO_BASE(APB2PERIPH_BASE+0x0000)n#defineGPIOA_BASE(APB2PERIPH_BASE+0x0800)n#defineGPIOB_BASE(APB2PERIPH_BASE+0x0C00)n#defineGPIOC_BASE(APB2PERIPH_BASE+0x1000)n#defineGPIOD_
18、BASE(APB2PERIPH_BASE+0x1400)n#defineGPIOE_BASE(APB2PERIPH_BASE+0x1800)Example:GPIO控制n“stm32f10x_conf.h”中定义如下:n#define_GPIOn#define_GPIOAn#define_GPIOBn#define_GPIOCn#define_GPIODn#define_GPIOEn#define_AFIOn用户可根据需要修改此文件中的定义,以决定其是否参与编译Example:GPIO控制n,初始化指针AFIO, GPIOA, GPIOB, GPIOC, GPIOD 和GPIOE 于文件“st
19、m32f10x_lib.c”:n#ifdef_GPIOAGPIOA=(GPIO_TypeDef*)GPIOA_BASE;n#endifn#ifdef_GPIOBGPIOB=(GPIO_TypeDef*)GPIOB_BASE;#endifn#ifdef_GPIOCGPIOC=(GPIO_TypeDef*)GPIOC_BASE;#endifn#ifdef_GPIODGPIOD=(GPIO_TypeDef*)GPIOD_BASE;#endifn#ifdef_GPIOEGPIOE=(GPIO_TypeDef*)GPIOE_BASE;#endifn#ifdef_AFIOAFIO=(AFIO_TypeDef*)AFIO_BASE;n#endifExample:GPIO控制Example:GPIO控制实验二 GPIO控制跑马灯n练习使用IAR,建立工程n连接系统,进行调试n改变延时时间,调试LED亮灭时间n不用函数,直接控制led亮灭