第04章 单片机程序设计基础.ppt_第1页
第04章 单片机程序设计基础.ppt_第2页
第04章 单片机程序设计基础.ppt_第3页
第04章 单片机程序设计基础.ppt_第4页
第04章 单片机程序设计基础.ppt_第5页
已阅读5页,还剩64页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第4章 单片机程序设计基础,4.1 编程的步骤、方法和技巧 4.2 汇编语言源程序的编辑和汇编 4.3 汇编语言程序设计举例 4.4 C51高级语言简介,4.1 编程的步骤、方法和技巧,4.1.1 编程的步骤 4.1.2 编程的方法和技巧 4.1.3 汇编语言程序的基本结构,4.1.1 编程的步骤,一、分析问题 二、确定算法 三、画程序流程图 四、编写程序,4.1.2 编程的方法和技巧,一、模块化的程序设计方法 二、编程技巧,一、模块化的程序设计方法,1、程序功能模块化的优点 2、划分模块的原则,1、程序功能模块化的优点,单个模块结构的程序功能单一,易于编写、调试和修改。 便于分工,从而可使多

2、个程序员同时进行程序的编写和调试工作,加快软件研制进度。 程序可读性好,便于功能扩充和版本升级。 对程序的修改可局部进行,其它部分可以保持不变。 对于使用频繁的子程序可以建立子程序库,便于多个模块调用。,2、划分模块的原则,每个模块应具有独立的功能,能产生一个明确的结果,即单模块的功能高内聚性。 模块之间的控制耦合应尽量简单,数据耦合应尽量少,即模块间的低耦合性。控制耦合是指模块进入和退出的条件及方式,数据耦合是指模块间的信息交换方式、交换量的多少及交换频繁程度。 模块长度适中。20条100条的范围较合适。,二、编程技巧,1、尽量采用循环结构和子程序。 2、尽量少用无条件转移指令。 3、对于通

3、用的子程序,考虑到其通用性,除了用于存放子程序入口参数的寄存器外,子程序中用到的其他寄存器的内容应压入堆栈保护。 4、在中断处理程序中,除了要保护处理程序中用到的寄存器外,还要保护标志寄存器。 5、用累加器传递入口参数或返回参数比较方便,在子程序中,一般不必把累加器内容压入堆栈。,4.1.3 汇编语言程序的基本结构,一、顺序程序 二、分支程序 三、循环程序,子程序结构,4.2 汇编语言源程序的编辑和汇编,4.2.1 源程序的编辑 4.2.2 源程序的汇编 4.2.3 伪指令,4.2.1 源程序的编辑,在微型计算机上,借助编辑软件,编写或修改汇编语言源程序。如行编辑或屏幕编辑软件。,4.2.2

4、源程序的汇编,汇编:将汇编语言源程序转换为机器码表示的目标程序的过程。对单片机有: 一、手工汇编 二、机器汇编,反汇编:将二进制机器语言程序翻译成汇编语言程 序的过程称反汇编。,4.2.3 伪指令,伪指令不是真正的指令,无对应的机器码,在汇编时不产生目标程序,只是用来对汇编过程进行某种控制。 89S51有8个伪指令: ORG END EQU DATA DB DW DS BIT,ORG 汇编起始命令,格式:ORG 16位地址 功能:规定该伪指令后面程序的汇编地址,即汇编后生成目标程序存放的起始地址。例如: ORG 2000H START:MOV A,#64H 规定了START的地址是2000H,

5、又规定了汇编后的第一条指令码从2000H开始存放。,END 汇编结束指令,格式:END 功能:通知汇编程序结束汇编。在END之后所有的汇编指令均不予以处理。,EQU 赋值命令,格式:字符名称 EQU 项(数或汇编符号) 功能:把“项”赋给“字符名称”。 注意:字符名称不等于标号(其后没有冒号);其中的项可以是数,也可以是汇编符号。EQU赋值过的符号名可以用作数据、代码地址、位地址或一个立即数。可以是8位的,也可以是16位的。 例1: AA EQU R1 MOV A,AA;AA代表工作寄存器R1 例2: A10 EQU 10 DELY EQU 07EBH MOV A,A10;A10作为片内的一个

6、直接地址 LCALL DELY;DELY作为一个16位子程序的入口地址,DATA 数据地址赋值命令,格式:字符名称 DATA 表达式 功能:与EQU类似,但有以下差别: 1、EQU定义的字符名必须先定义后使用,而DATA定义的字符名可以后定义先使用。 2、用EQU伪指令可以把一个汇编符号赋给一个名字,而DATA只能把数据赋给字符名。 3、DATA语句可以把一个表达式的值赋给字符名称,其中的表达式应是可求值的。DATA伪指令在程序中用来定义数据地址。,DB 定义字节命令,格式:DB(项或项表) 功能:通知汇编程序从当前ROM地址开始,保留一个字或字节串的存储单元,并存入DB后的数据。 注意:项或

7、项表可以是一个字节,用逗号隔开的字节串或括在单引号中的ASCII字符串。 例如:ORG 2000H DB 0A3H LIST: DB 26H,03H STR: DB ABC 经汇编后(2000H)=A3H, (2001H)=26H, (2002H)=03H, (2003H)=41H,(41H43H为A,B,C的ASCII码) (2004H)=42H, (2005H)=43H,,DW 定义字命令,格式:DW 16位数据项或项表 功能:把DW后的16位数据项或项表从当前地址连续存放。每项数值为16位二进制数,高8位先放,低8位后存放。DW用于定义一个地址表。 例如: ORG 1500H TABLE

8、:DW 7234H,8AH,10H 经汇编后(1500H)=72H, (1501H)=34H, (1502H)=00H, (1503H)=8AH, (1504H)=00H, (1505H)=10H,,DS 定义存储空间命令,格式:DS 表达式 功能:在汇编时,从指定地址开始保留DS之后表达式的值所规定的存储单元以备后用。 例如: ORG 1000H DS 08H DB 30H,8AH 汇编后,从1000H保留8个单元,然后从1008H按DB命令给内存赋值,即(1008H)=30H (1009H)=8AH,注:DB,DW,DS伪指令都只对程序存储器起作用,不能对数据存储器进行初始化。,BIT 位

9、地址符号命令,格式:字符名 BIT 位地址 功能:把BIT后的位地址值赋给字符名。其中字符名不是标号,其后没有冒号,但字符名是必须的。 例如: A1 BIT P1.0 A2 BIT 02H 汇编后,P1口第0位的位地址90H就赋给了A1,而A2的值则为02H。,4.3 汇编语言程序设计举例,一 简单程序设计举例 二 分支程序 三 循环程序 四 子程序设计举例 五 代码转换程序设计举例 六 运算类程序设计举例 七、查表程序设计举例 八、延时程序设计举例,一、 简单程序设计举例,例1 :拆字。将片内RAM 20H单元的内容拆成两段,每段四位。并将它们分别存入21H与22H单元中。程序如下:,解:

10、ORG 2000H START:MOVR0,#21H ;21HR0 MOVA,20H ;(20H)A ANLA,#0FH ;A#0FHA MOVR0,A ;(A)(R0) INCR0 ;R0+1 R0 MOVA,20H ;(20H)A SWAP A ;A03 A47 ANLA,#0FH ;A#0FHA MOVR0,A ;(A)(R0) SJMP$,例2:16位数求补。设16位二进制数在R1R0中,求补结果存于R3R2中。,解:ORG 1000H START:MOV A,R0 CPL A ADD A,#01H MOV R2,A MOV A,R1 CPL A ADDC A,#00H MOV R3,

11、A SJMP $,例1:片内RAM ONE和TWO两个单元中存有两个无符号数,将两个数中的小者存入RES单元。程序如下:,二、 分支程序,解:ORG1000H ONE DATA 22H; 定义ONE TWO DATA 23H;定义TWO RES DATA 30H;定义RES MOVA,ONE START:CJNE A,TWO,BIG SJMP STORE BIG: JCSTORE MOV A,TWO STORE:MOV RES,A SJMP $,例2 使用多条CJNE实现多分支程序转移 某温度控制系统,采集的温度值(Ta)放在A中,此外,在内部RAM 54h单元存放控制温度的下限值(T54),

12、在55h单元中存放控制温度的上限(T55),若TaT55,程序转向JW(降温处理),若TaT54,程序转向SW(升温处理),否则,转向FH(返回主程序).,CJNEA,55H,LOOPH AJMPFH LOOPH:JNCJW CJNEA,54H,LOOP2 AJMPFH LOOP2:JCSW FH:RET JW:. ;降温处理 SW:. ;升温处理,例3 使用散转指令实现多分支程序设键盘上有3个操作键 键值:01 功能:读数据 键值:02功能:写数据 键值:03功能:插入数据 假定键值放在A中, MOVDPTR,#3000H CLRC RLCA JMPA+DPTR 3000H 3001H 30

13、02HAJMPDS;转到读数据程序 3003H 3004HAJMPXS;转到写数据程序 3005H 3006HAJMPCR;转到插入数据程序,K=?,转向0分支,K=0,转向1分支,转向n-1分支,转向n分支,图中,K的最大值一般为128。,设寄存器R3中存有分支转移序号00H7FH,试编写根据序号转移的程序。,散转程序设计框图,JMP_128:MOVA, R3 RL A MOVDPTR, #JMPTAB JMPA+DPTR JMPTAB:AJMPROUT00 ; 128个子程序首址 AJMP ROUT01 AJMP ROUT7F,说明: 此程序要求转移目的地址ROUT00 ROUT7F必须驻

14、留在与指令AJMP同一个2KB存储区内,且程序的最大分支值为128。,三 、循环程序,例1:数据块传送。将片内RAM 20H单元开始的10个字节,传送到片外RAM 1000H单元开始的单元中去。,解:程序如下: ORG0800H START:MOV R0,#20H MOVDPTR,#1000H MOVR7,#0AH LOOP:MOVA,R0 MOVX DPTR,A INCR0 INCDPTR DJNZR7,LOOP SJMP$,循环程序,例2:统计字串长度。内存从STRING开始有一字串,该字串以$(ASCII码为24H)结束,试统计该字串长度,结果存于NUM单元中。,解:ORG0800H N

15、UM DATA 20H STRING DATA 21H START:CLRA MOV R0,#STRING LOOP:CJNE R0,#24H,NEXT SJMP COMP NEXT:INCA INCR0 SJMPLOOP COMP:MOV NUM,A SJMP$,四、 子程序设计举例,例1:用查表法编一子程序,将40H中的BCD码转换成ASCII码。 入口:待转换数在(40H) 出口:转换后的数(40H),解:ORG1000H TAB: DB30H,31H,32H,33H,34H,35H,36H,37H, 38H,39H SUB1:MOV A,40H MOV DPTR,#TAB MOVC A

16、,A+DPTR MOV 40H, A RET,若将30H单元BCD码转换成ASCII码,利用SUB1子程序。,ORG 2000H MAIN:MOV 40H,30H LCALL SUB1 MOV 30H,40H SJMP $,例:片外RAM2000H单元中有一BCD码,编一子程序将其转换成ASCII码。,ORG0100H BAS2:MOV DPTR,#2000H MOVX A,DPTR ADD A, #30H MOVX DPTR, A RET,五、 代码转换程序设计举例,六 、运算类程序设计举例,例1:片内RAM30H单元开始有10个字节的二进制数。编一子程序,求它们的和。(和256)将和存入2

17、0H单元中。,解:方法1 ORG 1000H ASUB1: MOV R0,#30H CLRA MOV R7,#10 CLRC LOOP:ADDC A,R0 INC R0 DJNZ R7,LOOP MOV 20H,A RET,方法2 ORG 2000H ASUB2: MOV R0,#30H MOVA,R0 MOVR7,#09 CLRC LOOP:INCR0 ADDC A,R0DJNZ R7,LOOP MOV20H,A RET,例2:编写将30H,31H单元中的两字节二进制数乘以2的程序(积小于65536)。,解:ORG1000H MSUB:CLR C MOV A,30H RLC A MOV 30

18、H,A MOV A,31H RLC A MOV 31H,A RET,例1 利用查表的方法编写Y= X2 (X=0,1,29 )的程序。 编程说明: 设变量X的值存放在内存30H单元中,变量Y的值存入内存31H单元。 先用远查表指令MOVC A, A+DPTR 编写程序(参考程序1);再用近查表指令MOVC A , A+PC 编写程序(见参考程序2)。,七、查表程序设计举例,参考程序1: ORG 1000H START:MOV A , 30H MOV DPTR , #TABLE MOVC A , A+DPTR MOV 31H , A TABLE:DB 0 , 1 , 4 , 9 , 16 DB

19、25 , 36 , 49 , 64 , 81 END,思考: 程序结构有问题吗?,参考程序2: ORG 1000H START:MOV A , 30H ADD A , #03H;思考该指令的作用? MOVC A , A+PC MOV 31H , A RET DB 0 , 1 , 4 , 9 , 16 DB 25 , 36 , 49 , 64 , 81 END,例2 将1位十六进制数,转换成相应ASC码。用计算求解和查表求解,进行比较。 (1) 计算求解: 编程说明: 设待转换的一位十六进制数存放在40H 单元中,转换后的ASC码仍存放在40H 中。 编程思路: 十六进制数09 ASC码:30H

20、39H,加30H, 十六进制数AF ASC码:41H46H,加37H。,参考程序如下: ORG 0100 H MOV A , 40 H ANL A , # 0F H CLR C SUBB A, # 0AH ;A10? JC NEXT ADD A , #0AH ADD A , #37H SJMP SAVE NEXT: ADD A , #0AH ADD A , #30H SAVE: MOV 40H , A RET END,(2) 查表求解: ORG 0100H MOV A , 40H ANL A , #0FH ADD A , #03H MOVC A , A+PC MOV 40H , A RET D

21、B 0, 1, 2, 3, 4, 5 DB 6, 7, 8, 9, A, B DB C, D, E, F END,八、延时程序设计举例,查表注意到执行DJNZ指令要用两个机器周期 执行MOV Rn,#data要一个机器周期 执行MOV dir,#data要两个机器周期 因此可以精确算出程序执行时间。 例:以机器周期为单位,计算以下程序的执行时间。 MOV R7,#64H LOOP: MOV R6,#0FAH DJNZ R6,$ DJNZ R7,LOOP RET,;1个机器周期 ;1 ;250*2=500 ;2,503*100=50300 ;2,共50303个机器周期,问题:将以上程序的第二句

22、LOOP: MOV R6,#0FAH 改为 LOOP: MOV R6,#0 则 DJNZ R6,$ 语句会执行多少次? 要实现延时功能,有时还需要用到空操作指令:,* 空操作指令不进行任何操作,但它在程序存储器中占了一个字节的位置,执行时也需要占用一个机器周期的时间。,例1:设单片机晶振频率6M,编写一段程序,大约延时1秒钟。 分析:由于DJNZ指令最多的循环次数是256次,而1S256256 约等于15S,晶振频率6MHZ,则1个机器周期为2S,我们把内循环定为8个机器周期16S。则16S250250=1S。 Delay: MOV R7,#0FAH LOOP: MOV R6,#0FAH LO

23、OP1:NOP NOP NOP NOP NOP NOP DJNZ R6,LOOP1 DJNZ R7,LOOP 实际执行时间: (6+2)250+2+1250+1=500751个机器周期,需1.001502秒。,例2:编写延时4ms的子程序。设晶振为12MHZ。,解:晶振为12MHZ,则1个机器周期为1s,1条DJNZ指令为2个机器周期,则执行该指令2000次为4ms, 200020*100. ORG1000H Delay:MOVR6,#20 DLY1:MOVR7,#100 DLY2:DJNZR7,DLAY2 DJNZR6,DLY1 RET,4.4 51高级语言简介4.4.1 C51的标识符与关

24、键字,标识符 标识符由字母、数字、下划线等组成,第一个 字符必须是字母或下划线。 说明: 标识符用来标识源程序中某个对象的名字,这些对象可以是语句、数据类型、函数、变量、数组等。 C51语言是一种区分大小写的高级语言。 C51语言中有一些库函数的标识符是以下划线开头的,编程者一般不要以下划线开头来命名标识符。 在C51编译器中,只支持标识符的前32个字符为有效标识。,关键字 关键字是编程语言保留的特殊标识符,它们具有固定名称和含义,在程序编写过程中不允许将关键字另做它用。 说明: 1. 在C51语言中,除了有ANSI C标准的32个关键字以外,还根据单片机的特点扩展了相关的关键字 。 2. 在

25、C51语言的文本编辑中编写C51语言程序时,系统可以把关键字用不同的颜色显示 。 3. 表4.1 按用途列出了标准C语言ANSI C的关键字 。 4. 表4.2 列出了C51编译器扩展的关键字 。,4.4.2 C51语言的数据类型,数据类型 数据是MCS-51单片机操作的对象,是具有一定格式的数字或数值。数据的不同格式就称为数据类型。数据按照一定的数据类型进行排列、组合和架构后称为数据结构。 说明: C51语言与标准C语言的数据类型基本相同,使用方法基本类似。增设了位型,取消了布尔型,大体可以分为基本数据类型、构造数据类型、指针类型、空类型。 C51语言的数据类型如表4.3所示。,表4.3C5

26、1语言的数据类型,表4.3,C51语言的数据类型,C51语言扩展的数据类型 bit:位型 sfr:特殊功能寄存器 sfr16:16位特殊功能寄存器 sbit:可寻址位,例:用关键字sbit定义特殊功能寄存器中的可寻址位 1、sbit OV=0 xD2;/*将位地址赋给位变量OV*/ 2、sfr P1=0 x90;/*定义特殊功能寄存器P1*/ sbit Switch_k1=P10;/*定义位变量Switch_k1在P1.0位*/ 3、sbit CY=0 xD07;/*定义CY在字节地址0 xD0的第7位*/,4.4.3 C51变量的存储种类和存储器类型,变量 C51语言规定变量必须先定义后使用

27、。对变量进行定义的格式如下: 存储种类数据类型 存储器类型 变量名表 说明: 每个变量都有一个变量名,在内存中占据一定的存储单元(地址),并在该内存单元中存放该变量的值。变量名应符合标识符的要求,各变量名之间用逗号“,”分隔,从而构成变量名表。,变量的存储种类 存储种类是指变量在程序执行过程中的作用范围。变量的存储种类有4种: auto extern static register,变量的存储器类型 存储器类型和存储种类是完全不同的概念,存储种类是指变量在程序执行过程中的作用范围,而存储器类型指明该变量所处的单片机内存空间。 C51编译器能识别以下存储器类型,如表4.4所示。,表4.4 C51

28、编译器能识别的存储器类型,存储模式 C51编译器允许采用3种存储模式:小编译模式Small、紧凑编译模式Compact、大编译模式Large。存储模式确定了变量在内存中的地址空间,在Small模式下,变量存放在单片机的内部RAM中;在Compact模式和Large模式下,变量存放在单片机外部RAM中。在Small模式下,未说明变量的存储器类型时,该变量被默认存放到data区。 存储模式的软件定义实例如下: #pragma small / small模式下,变量的存储器类型为片内直接寻址RAM区,4.4.4 C51语言的基本语句,控制语句 ifelse条件语句 for()循环语句 while()

29、循环语句 dowhile()循环语句 continue结束本次循环的语句 break中止执行开关语句switch或循环的语句 switchcase多分支选择语句 goto无条件转向语句 return函数返回语句,4.4.5 C51函数,函数的概念 “函数”与汇编语言中的“子程序”、“过程”的意义相同,是按照一定格式编写的完成一定功能的代码段。 在构成C51语言程序的若干个函数中,必有一个是主函数main( )。C51语言程序的执行从主函数main( )开始,主函数main( )可以根据需要来调用其他函数, 函数在使用前要先定义 。,函数的定义,概念: 创建函数称为函数的定义,函数定义的过程就是

30、给出函数原型(function prototype)。 无参函数的定义 返回值数据类型标识符 函数名( ) 函数体语句 有参函数的定义 返回值数据类型标识符 函数名( 形式参数列表) 形式参数说明 函数体语句 ,中断函数的定义,返回值数据类型标识符 函数名(形式参数列表 ) interrupt n using m 中断服务程序语句体 说明: 中断函数由单片机中断系统自动调用,用户在主程序或函数中,不能调用中断函数。 关键字interrupt后面的n是中断号,n的取值范围为031。C51编译器从8n+3处产生中断矢量,89S51单片机的中断源、中断号、中断矢量的关系如表4.5所示。 using

31、m选项用于实现工作寄存器组的切换,m是中断服务程序中选用的工作寄存器组区号。,表4.5 89S51的中断源、中断号、中断矢量,例: 单片机点对点双机串行通信。,单片机点对点的双机串行通信图,4.4.6 C51高级语言程序设计举例,双机串行通信程序可以在甲机、乙机中运行, 发送时源程序中将常量Select_TR定义为1;接收则定义为0。,#include #define uchar unsigned char #define Select_TR 1 /Select_TR=1时接收数据,Select_TR=0时发送数据 uchar idata buffer10; /定义全局变量 uchar dat

32、a cheak_sum; void serial_initialize(void);/函数声明 void send(uchar idata *data_buffer); void receive(uchar idata *data_buffer); main() serial_initialize();/串行口初始化 if (Select_TR=0) send(buffer); /发送数据 else receive(buffer); /接收数据 ,/* 串行口初始化函数原型 */ void serial_initialize(void) TMOD = 0 x20; /T1运行于定时工作方式2

33、TH0 = 0 xe8; TL0 = 0 xe8; TR1 = 1; SCON = 0 x50; /串行口工作方式1,允许接收 ,/* 发送数据函数原型 */ void send(uchar idata *data_buffer) uchar i; do SBUF = 0 xAA;/发送联络信号0 xAA while(TI=0);TI = 0;/等待1帧数据发送完毕 while(RI=0);RI = 0;/等待联络应答信号0 xBB while(SBUF0 xBB != 0);/接收方没准备好则继续联络 do cheak_sum = 0;/清0校验和变量 for (i=0;i10;i+)/循环发送10Bytes数据 SBUF = data_bufferi;/发送1Byte cheak_sum += data_bufferi; /计算校验和 while(TI=0);TI = 0; SBUF = cheak_sum;/发送校验和 while(T

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论