第四章 指令系统及汇编语言程序设计.

Slides:



Advertisements
Similar presentations
第7章 AT89S51单片机的 串行口 1.
Advertisements

第三章 计算机系统 的组成与工作原理 本章学习目标 理解模型机的结构及工作过程 掌握单片机的结构 掌握单片机I/O口的使用
第5章 中断系统 5.1 中断的概念 5.2 MCS-51单片机的中断流程 5.3 MCS-51的中断响应条件和中断处理
本章内容: 中断的概念 MCS-51单片机中断系统 外部事件中断及应用
第四章 指令系统及汇编语言程序设计.
8051 指令.
本章分为四节,主要介绍: 4.1 程序编制的方法和技巧 4.2 源程序的编辑和汇编 4.3 基本程序结构 4.4 常用程序举例.
项目2 2个LED发光二极管控制 知识与能力目标 熟悉单片机的I/O口功能与特性。
得技通电子 问题 1 右何者非為假指令 (1) XRL (2) EQU (3) MACRO (4) ORG.
本章小结 C51单片机指令系统概述 C51单片机寻址方式 C51单片机指令系统
单片机原理与应用.
第9章 串行扩展技术 (课时:6学时).
第9章 数模转换器与模数转换器 本章学习目标 了解数模转换器的工作原理及性能指标 掌握模数转换器的应用 掌握数模转换器的应用.
第2章 MCS-51单片机指令系统与汇编语言程序设计
報告者:朱耿育 紀翔舜 組員:詹以群 張永傑 指導老師:梁新潁
复 习 一. 计算机中的数和编码 1. 2,10,16进制数及其之间的转换(整数) 按权展开,除x取余 2
第二部分 微机原理 第4章 汇编语言 程序设计 主讲教师:喻红.
单片机应用技术 项目一 循环彩灯装置 第6讲 指令功能及汇编语言程序设计(一) 《单片机应用技术》精品课程组 湖北职业技术学院机电工程系.
本章内容: 中断的概念 MCS-51单片机中断系统 外部事件中断及应用
6.3 定时器/计数器的应用 初始化 初始化的内容如下:
第8章 模拟接口 8.1 模拟接口概述 8.2 DAC及其接口 8.3 ADC及其接口.
第二部分 微机原理 第3章 MCS-51的 指令系统 主讲教师:喻红.
一、任务描述 二、任务分析 三、任务演示 四、相关知识 五、任务布置. 一、任务描述 二、任务分析 三、任务演示 四、相关知识 五、任务布置.
第14章 单片机应用系统抗干扰 与可靠性设计 1.
第6章 MCS - 51单片机内部定时器/ 计数器 及串行接口 6.1 定时器/计数器的结构及工作原理 6.2 方式和控制寄存器
第七章 MCS-51系统扩展 一、程序存储器扩展
第十一章 复位、时钟和省电方式控制.
第3章 AT89C51指令系统 3.1基本概念内部结构和引脚功能 指令、指令系统、机器代码
逻辑运算类指令 包括与、或、非、异或、清0及移位等共24条;一般不影响PSW中的标志位;助记符有:ANL、ORL、XRL、RL、RLC、RR、RRC、CLR和CPL共9种。 一、逻辑与指令 ANL A,Rn ;A←(A)∧( Rn) ANL A,direct;A←(A)∧(direct)
单片机原理及应用 MCS-51系列单片机的基本硬件结构 MCS-51指令系统 MCS-51单片机的系统扩展与应用.
第五章 单片机的C语言程序设计及仿真调试.
第三章 计算机系统的组成与工作原理.
单片机原理及应用 ——基于Proteus与Keil C 哈工大出版社
4.A/D与D/A转换器 1).DAC0832与MCS-51接口
第2章 单片机的结构原理与 简单应用 (课时:10学时).
第八章 MCS-51与数码显示器和键盘的接口 一、MCS-51与数码显示器接口 数码显示器是单片机应用产品中最常用的廉价的输 出设备,它由8个发光二极管按一定规律排列而成, 当某一发光二极管导通时,则会被点亮,控制不同 组合的二极管导通,就能显示出各种字符。 1.显示器的结构.
本 章 重 点 单片机的简单I/O扩展 8255A可编程并口芯片 8279可编程键盘/显示器接口芯片 单片机键盘接口技术
单片机原理 单 片 机 单片机接口技术 单片机应用技术.
第七章 定时/计数器.
第三章 指令系统.
第3章 指令系统及程序设计举例 3.1 指令格式与寻址方式 一、指令格式 1. 指令 操作码 目标操作数,源操作数
第十章 人机交互接口 本章学习目标 掌握键盘接口技术 掌握数码、液晶显示技术 了解数码管显示驱动和键盘扫描控制专用芯片.
第10章 综合实训 课题一 水温控制系统设计 一、实训目的 二、课题要求 熟悉常用温度传感器AD590的特性及接口电路的设计方法;
第2章 单片机系统组成原理 2.1 MCS-51单片机组成原理 2.2 单片机复位电路设计 2.3 MCS-51存储器配置
6.1 输入/输出 6.2 CPU与外设数据传送方式 6. 3 MCS-51中断系统 6. 4 中断应用举例
单元五 MCS-51单片机内部资源 5.1 任务九 单片机计数并显示 5.2 任务十 单片机流水灯控制 5.3 任务十一 两台单片机数据互传
本 章 重 点 单片机的结构特点 单片机的存储器特点 I/O端口的特点 CPU时序 课时安排:3个课时.
第四章 指令系统及汇编语言程序设计.
第4章 中断技术 一个完整的微机系统是由硬件和软件共同构成的。微机系统的硬件有CPU、存储器和I/O口,外设组成。CPU与存储器之间的信息交换比较简单,而CPU与外设之间进行信息交换之前必须确定外设是否准备好,即选择I/O传送方式。I/O传送方式有4种:无条件、查询、中断和DMA。本章学习中断传送方式的有关内容。
第二章 单片机基础知识.
单片机系统设计 教师:朱华贵 2016年03月01日
数码管数字时钟电路的设计 1. 系统硬件电路的设计
第3章 MCS-51指令系统 介绍MCS—51系列单片机的寻址方式 介绍MCS—51系列单片机的指令系统
第4章 80C51系列指令系统 教学目的:熟悉80C51系列单片机的寻址方式及 每一种寻址方式对应的寻址空间;掌 握每一条指令功能。
本章内容 MCS-51单片机指令系统的格式 MCS-51单片机寻址方式 指令系统的分析
5-6 串列埠模式0輸出埠擴充實習.
单片机原理与应用 主讲人:张荣刚 福建师范大学福清分校.
CPU中的专用寄存器(SFR) 一、累加器Acc 二、通用寄存器B 三、程序计数器PC 四、堆栈指针SP 五、数据指针DPTR
第五讲:AT89C51单片机存储器结构 一、半导体存储器 二、存储器空间划分方法 三、数据存储器(RAM) 四、程序存储器(ROM)
3.1 指令系统简介 一、几个概念 二、汇编语言指令格式 三、指令的分类 四、指令的符号说明 主讲:吴政江 下一页.
第三章 计算机系统的组成与工作原理.
汽车单片机应用技术 学习情景1: 汽车空调系统的单片机控制 主讲:向楠.
四、手工汇编 完成汇编的方法有两种:手工汇编和汇编程序汇编 1.手工汇编步骤 A
单片机原理与应用.
简单芯片扩展I/O接口 8155可编程接口芯片及其使用 键盘及显示器接口设计 A/D和D/A转换接口技术
单片机应用技术 (C语言版) 第3章 MCS-51指令系统及 汇编程序设计
第二章 MCS-51单片机程序设计 第一章 8086程序设计 第三章 微机基本系统的设计 第四章 存贮器与接口 第五章 并行接口
第4章 MCS-51汇编语言程序设计 教学基本要求: (1)、了解MCS-51汇编语言程序设计的特点;
第2章 80C51单片机的硬件结构 教学基本要求: (1)、熟悉单片机的定义、名称、分类方法;
第1章 微型计算机基础.
Presentation transcript:

第四章 指令系统及汇编语言程序设计

STC15系列单片机器件手册----1473页 任课教师:刘忠国 山东大学课程中心网站: http://course.sdu.edu.cn/G2S/stcmcu.cc 宏晶官方网站:http://www.stcmcu.com/ stc15系列单片机器件手册等 keil μvision软件下载及指导手册(Help→μvision Help) http://www.keil.com/ STC15系列单片机器件手册----1473页 (2015/6/29更新)

第四章 指令系统及汇编语言程序设计 本章学习目标 了解助记符、指令格式 掌握单片机寻址方式 掌握单片机指令系统 掌握单片机汇编语言程序设计及开发环境 参考资料: keil μVision软件的帮助文件 18:13:32

第四章 指令系统及汇编语言程序设计语言 4.6 汇编语言程序设计 4.6.1 汇编语言程序设计的一般步骤和基本框架 4.1 编程语言简介 4.2 指令和伪指令 4.3 汇编语言程序调试 4.4 利用STC-ISP工具将程序下载到单片机中验证程序 4.5各类指令详解 4.5.1 数据传送类指令 4.5.2 逻辑操作类指令 4.5.3 算术运算类指令 4.5.4 位操作指令 4.5.5 控制类转移指令 4.6 汇编语言程序设计 4.6.1 汇编语言程序设计的一般步骤和基本框架 4.6.2 汇编语言程序设计举例 18:13:32

根据算法要求分配资源,包括内部RAM、定时器、 中断等资源的分配。 根据流程图编写程序。 上机调试源程序,进而确定源程序。 4.6 汇编语言程序设计 4.6.1 汇编语言程序设计的一般步骤和基本框架 汇编语言程序设计的一般步骤是: 分析课题,确定算法或解题思路。 根据算法或思路画出流程图。 根据算法要求分配资源,包括内部RAM、定时器、 中断等资源的分配。 根据流程图编写程序。 上机调试源程序,进而确定源程序。 对复杂的程序可按功能分为不同的模块, 按模块功能 确定结构, 编写程序时应采用模块化的程序设计方法。 18:13:32

4.6.1 汇编语言程序设计的一般步骤和基本框架 COLUMN EQU 32H BUFFER DATA 40H 4.6.1 汇编语言程序设计的一般步骤和基本框架 $INCLUDE (STC15.INC) ;下面是汇编语言程序的框架 ;本语句包含IAP15W4K58S4单片机寄存器定义头文件 ;---------------------这里可以编写程序中用到的一些符号定义(使用 EQU, DATA, BIT等伪指令) ORG 0000H START: LJMP MAIN ;跳转到主程序 ORG 0003H LJMP INT0_ISR ;外部中断0入口 ORG 000BH LJMP T0_ISR ;定时器0中断入口 ORG 0013H LJMP INT1_ISR ;外部中断1入口 ORG 001BH LJMP T1_ISR ;定时器1中断入口 ORG 0023H LJMP UART1_ISR ;串口1中断入口 COLUMN EQU 32H BUFFER DATA 40H 18:13:32

4.6.1 汇编语言程序设计的一般步骤和基本框架 ORG 002BH LJMP ADC_ISR ;ADC中断服务程序入口 ORG 0033H LJMP LVD_ISR ;低电压检测中断服务程序入口 ORG 003BH LJMP PCA_ISR ;PCA中断服务程序入口 ORG 0043H LJMP UART2_ISR ;串口2中断服务程序入口 ORG 004BH LJMP SPI_ISR ;SPI中断服务程序入口 18:13:32

IAP15W4K58S4的以上中断与STC15F2K60S2的相同 4.6.1 汇编语言程序设计的一般步骤和基本框架 ORG 0053H LJMP INT2_ISR ;INT2中断服务程序入口 ORG 005BH LJMP INT3_ISR ;INT3中断服务程序入口 ORG 0063H LJMP T2_ISR ;定时器2中断服务程序入口 ORG 0083H LJMP INT4_ISR ;INT4中断服务程序入口 IAP15W4K58S4的以上中断与STC15F2K60S2的相同 18:13:32

IAP15W4K58S4的以下中断对STC15F2K60S2不存在 4.6.1 汇编语言程序设计的一般步骤和基本框架 4.6.1 汇编语言程序设计的一般步骤和基本框架 ORG 008BH LJMP UART3_ISR ; UART3中断服务程序入口 ORG 0093H LJMP UART4_ISR ;UART4中断服务程序入口 ORG 009BH LJMP T3_ISR ;T3中断服务程序入口 ORG 00A3H LJMP T4_ISR ;T4中断服务程序入口 ORG 00ABH LJMP COMP_ISR ;比较器中断服务程序入口 ORG 00B3H LJMP PWM_ISR ;PWM中断服务程序入口 ORG 00BBH LJMP PWMFD_ISR ;PWM异常检测(PWM Fault Detection)

;设置堆栈指针(可根据实际情况进行修改) ……;初始化内存区域内容 ……;设置有关特殊功能寄存器(SFR)的控制字 4.6.1 汇编语言程序设计的一般步骤和基本框架 ORG 0100H MAIN: MOV SP, #70H ;设置堆栈指针(可根据实际情况进行修改) ……;初始化内存区域内容 ……;设置有关特殊功能寄存器(SFR)的控制字 ……;根据需要开放相应的中断控制 MAINLOOP: ;主程序循环 LJMP MAINLOOP 18:13:32

4.6.1 汇编语言程序设计的一般步骤和基本框架 ;下面是各个中断服务子程序的入口 INT0_ISR: ;外部中断0服务子程序 …… ;根据需要填入适当的内容 RETI INT1_ISR: ;外部中断1服务子程序 T0_ISR: ;定时器0中断服务子程序 T1_ISR: ;定时器1中断服务子程序 UART1_ISR: ;串口1中断服务子程序 …… ;根据需要填入适当内容(注意中断请求标志位清零) 18:13:32

4.6.1 汇编语言程序设计的一般步骤和基本框架 UART2_ISR: ;串口2中断服务子程序 …… ;根据需要填入适当内容(注意中断请求标志位清零) RETI ADC_ISR: ;ADC中断服务子程序 SPI_ISR: ;SPI通信中断服务子程序 LVD_ISR: ;低电压检测服务子程序 PCA_ISR: ;PCA和PWM中断服务子程序 18:13:32

4.6.1 汇编语言程序设计的一般步骤和基本框架 INT2_ISR: ;INT2中断服务子程序 …… ;根据需要填入适当的内容 RETI INT3_ISR: ;INT3中断服务子程序 T2_ISR: ;定时器2中断服务子程序 INT4_ISR: ;INT4中断服务子程序 ; IAP15W4K58S4的以上中断服务程序同STC15F2K60S2 18:13:32

4.6.1 汇编语言程序设计的一般步骤和基本框架 IAP15W4K58S4的以下中断中断服务程序对STC15F2K60S2不存在 T3_ISR: ;定时器3中断服务子程序 … ;根据需要填入适当的内容 RETI T4_ISR: ;定时器4中断服务子程序 UART3_ISR: ;串口3中断服务子程序 … ;根据需要填入适当的内容(注意中断请求标志位的清0) UART4_ISR: ;串口4中断服务子程序 … ;根据需要填入适当的内容(注意中断请求标志位的清0) COMP_ISR: ;比较器中断服务子程序 PWM_ISR: ;PWM中断服务子程序 … ;根据需要填入适当的内容(注意中断请求标志位的清0) PWMFD_ISR: ;PWM异常检测中断服务子程序 … ;根据需要填入适当的内容(注意中断请求标志位的清0) ;下面可以编写其他子程序或者定义程序中所用的常数 END IAP15W4K58S4的以下中断中断服务程序对STC15F2K60S2不存在 4.6.1 汇编语言程序设计的一般步骤和基本框架

所以第一条指令是一条长跳转指令,跳到避开上述中 断处理子程序入口地址的0100H的地址,主程序MAIN 从这个地址开始存放; 4.6.1 汇编语言程序设计的一般步骤和基本框架 注意: 由于地址0003H、000BH、0013H、001BH、0023H 、002BH、 0033H、003BH、0043H、004BH、0053H、005BH、0063H、 0083H、0033H、008BH、0093H、009BH、00A3H、00ABH、 00B3H和00BBH是专门为中断处理子程序分别预留的入 口地址, 所以第一条指令是一条长跳转指令,跳到避开上述中 断处理子程序入口地址的0100H的地址,主程序MAIN 从这个地址开始存放; MAIN 语句前面的伪指令“ORG 0100H”表示,以标 号MAIN表示的主程序放在0100H开始的区域,当然也 可以是跳到能够避开上述入口地址的其他地址。 18:13:32

如果用户系统根本没有任何中断源,或者没有使用 全部中断源,就可以不用或者少用中断的功能; 4.6.1 汇编语言程序设计的一般步骤和基本框架 如果用户系统根本没有任何中断源,或者没有使用 全部中断源,就可以不用或者少用中断的功能; 0003H到00BBH的区域也就无须全部或部分用于中 断处理。没有任何中断的情况下,主程序甚至可以 从0000H开始连续存放下去。 主程序的末尾是一条长跳转指令,跳转到某个合适 的地方反复执行主程序。 一般的子程序不可形成死循环,但是作为整个主程 序却应该是一个最大的死循环。无论执行哪个子程 序,之后都要回到主程序,反复循环运行。 18:13:32

程序流程图 4.6.1 汇编语言程序设计的一般步骤和基本框架 在程序编制以前,先根据系统方案绘制程序流程图 是一个很好的方法。 4.6.1 汇编语言程序设计的一般步骤和基本框架 程序流程图 在程序编制以前,先根据系统方案绘制程序流程图 是一个很好的方法。 程序流程图可以简洁清晰地将程序的分支走向标示 清楚,尤其是在程序复杂,编写人员较多相互衔接 容易出错的的情况下,利用流程图理顺各部分关系 显得尤为重要。 画流程图有两个常用的结构:顺序执行的矩形框和 条件分支的菱形框。 18:13:32

画流程图两结构:顺序执行矩形框和条件分支菱形框 顺序执行:某个局部功能或者顺序执行的语句使用矩形 方框表示,矩形方框内注明程序的功能,各方框之间用 箭头表示执行顺序,一目了然; 条件分支: 遇到需要根据条件判断是否转移时,使用菱形 方框表示, 菱形框内注明分支条件, 不同出口表明分支的 去向: 可以向后跳转, 也可向前跳转。 计数单元-1=0? 退出循环 Y N 循环体 Y N 循环体 R0-1→R0=0? 存储单元清零 堆栈指针赋初值 调用延时子程序 分支结构 顺序结构 分支结构另种画法 例: DJNZ R0, L1 18:13:32

程序流程图 循环程序设计 当程序处理的对象 具有重复性规律时, 可以使用循环程序 设计。一个循环表 示重复执行一组指 令(程序段)。 图4-47 典型循环程序结构的流程图 18:13:32

画流程图两结构:顺序执行矩形框和条件分支菱形框 条件分支: 菱形框内注明分支条件, 不同出口表明分支 的去向: 可以向后跳转, 也可向前跳转。一般框图如下 所示: 二分支结构 用: CJNZ, JZ, J(N)C, J(N)B等 多分支结构 18:13:32

1、分支程序设计 2、查表程序设计 3、循环程序设计 4、定点数运算子程序设计 5、数据排序程序设计 6、代码转换程序设计 4.6.2 典型汇编语言程序设计举例 1、分支程序设计 2、查表程序设计 3、循环程序设计 4、定点数运算子程序设计 5、数据排序程序设计 6、代码转换程序设计 18:13:32

1、分支程序设计 程序分支是通过条件转移指令实现的,即根据条件进 行判断后决定程序的走向。条件满足则进行程序转移, 不满足就顺序执行程序。 程序分支是通过条件转移指令实现的,即根据条件进 行判断后决定程序的走向。条件满足则进行程序转移, 不满足就顺序执行程序。 通过条件判断实现单分支程序转移的指令有JZ、JNZ、 CJNE (4条)和DJNZ(2条)等。 以位状态为条件,进行程序分支的指令JC、JNC、 JB、JNB和JBC等。 18:13:32

1、分支程序设计 【例4-10】编程实现下面的比较函数。设变量x存放 在R0,求得的y 值存入SIGN单元。 解:可以利用比较转移CJNE指令和进位位C状态控制 转移(JC指令)来实现三分支转移。 18:13:32

【例4-10】程序 SIGN EQU 50H ;求得的y 值存入SIGN单元 ORG 0000H LJMP MAIN ORG 0100H MAIN: CJNE R0, #37, NOTEQ ;R0与37比较, 不相等则转NOTEQ MOV SIGN, #00H ;若比较相等,则SIGN←0 LJMP ENDM ;转到程序结束 NOTEQ:JC NEG ;两数不相等, 若R0<37则C=1, 转NEG处理 MOV SIGN,#01H ;R0>37时,SIGN←+1 LJMP ENDM ;转到程序结束 NEG:MOV SIGN, #0FFH ;R0<37时, SIGN←-1 ENDM:NOP END 设变量x值存放在R0 18:13:32

2、查表程序设计 查表法产生的背景 参数的计算非常复杂; 公式计算法计算程序长,难于计算; 需要耗费大量时间; 非线性参数,无法用一般算术运算就可以计算出来, 如指数、对数、三角函数以及积分、微分等运算; 数学计算无法建立相应的数学模型。 查表法定义 就是把事先计算或测得的数据按一定顺序编制成表格, 查表程序根据被测参数的值或中间结果, 查出最终所需 的结果。它具有程序简单, 执行速度快等优点。 18:13:32

2、查表程序设计 应用: 在键盘处理程序中,查找按键相应的命令处理子程 序的入口地址; 在键盘处理程序中,查找按键相应的命令处理子程 序的入口地址; 在一些快速计算的场合,根据自变量的值,从函数 表上查找出相应的函数值以及实现非线性修正、代 码转换等等。 常用MOVC A,@A+DPTR查找程序存储器空间 的代码或常数,每次传送一个字节。 举例: 在LED显示程序中, 获得LED数码管显示字模; 18:13:32

2、查表程序设计 1 1 h g f e d c b a h g f e d c b a A中存要显示的0~9的数字 例如, 假如要显示的数据需放到累加器A中, 采用共阳极LED显 示, 则可采用下面查表法程序获得LED显示字模: MOV DPTR, #SEGTAB ;获得字模表的首地址 MOVC A, @A+DPTR ;查表获得字模 …… ;下面可以送出字模进行显示 SEGTAB: DB 0C0H ;0的字模 DB 0F9H ;1的字模 DB 0A4H ;2的字模 DB 0B0H ;3的字模 DB 99H ;4的字模 DB 92H ;5的字模 DB 82H ;6的字模 DB 0F8H ;7的字模 DB 80H ;8的字模 DB 90H ;9的字模 如何转换? 1 1 D7 D6 D5 D4 D3 D2 D1 D0 h g f e d c b a 数字的字模 h g f e d c b a 18:13:32

3、循环程序设计 DJNZ R7, LOOP 延时程序是典型的循环程序。 下面就以延时程序为例, 说明 循环程序的设计方法。 流程图如图所示。 DJNZ R7, LOOP 图4-48 延时程序流程图 18:13:32

3、循环程序设计 简单延时子程序如下(注释部分为指令的时钟周期数): DELAY100US : ;@11.0592MHz PUSH 30H ;指令的时钟周期数3T MOV 30H, #218 ;3T DLY_LOOP: DJNZ 30H, DLY_LOOP ; 5T ;30H←(30H)-1, 若(30H)≠0, 则转到DLY_LOOP执行 POP 30H ;2T RET ;4T IAP15W4K58S4为1T的8051单片机, 当系统时钟为 11.0592MHz时, 上述程序可延时约0.1ms。若需加长延 时时间, 可采用多重循环延时程序方法。 18:13:32

3、循环程序设计 创建延时程序最简单的方法是利用宏晶公司的下载工具 STC-ISP的“软件延时计算器”获得延时程序代码, 如图4- 49所示。上述延时0.1ms的程序即可用此法得到。 在工具中选择“软件延时计算器”标签页, 设置系统频率, 定时长度和8051指令集, 最后单击“生成ASM代码”按钮 即可生成延时子程序汇编代码。也可生成C程序代码。 18:13:32

4、定点数运算子程序设计 多字节无符号加法子程序和减法子程序设计较简单, 在此介绍有代表性的多字节BCD码减法程序和多字 节乘法程序的设计。 (1)多字节十进制BCD码减法 因指令系统中只有十进制加法调整指令DA A, 也即 该指令只有在加法指令(ADD、ADDC)后, 才能得到 正确的结果。 为了用十进制加法调整指令对十进制减法进行调整, 必须采用补码相加的办法,用9AH (100)减去减数即 得以10(100)为模的减数的补码。 GO 参考例4-9 18:13:32

求BCD码8943H - 7649H=? 编程前由实例测算计算过程。 以十六进制形式表示 求BCD码8943H - 7649H=? 编程前由实例测算计算过程。 先对低位字节运算43H - 49H: 1001 1010 模9A -) 0100 1001 减数49 0101 0001 得49对100补码51 +)0100 0011 加被减数43 0 1001 0100 差94 再对高字节运算89H -76H - C: 1001 1010 9A -) 0111 0110 76 0010 0100 得76对100补码为24 -)0000 0001 减去借位位C=1 0010 0011 减借位1后的值为23 +)1000 1001 加被减数89 1010 1100 结果0AC +) 0110 0110 对结果加66修正 10001 0010 差为12 应理解为 43向高位借位与49相减的结果 DA A 调整 后C=0 C=0无进位, 表示二者相减有 借位。应对借位C求反使C=1。 高字节减数变补与被减数相加调整后有进位1, 表示两者相减无借位, 为正确反映借位情况应对进位C求反使C=0(减法时C=1,表示有借位; C=0, 表示无借位)。最后结果为1294H, 且无借位, 计算正确。 18:13:32

(1)多字节十进制BCD码减法 BCD码减法程序举例:采用补码相加的办法,用 9AH(100)减去减数即得以10(100)为模的减数的补码。 程序说明(减法运算化成100的补码加法运算) 程序中,减数求补后与被减数相加,方可利用DA A 指令进行调整; 若二者相加调整(DA A)后结果无进位(C=0),实际 上表示二者相减有借位; 若二者相加调整(DA A)后有进位(C=1),实际上表 示二者相减没有借位(教材加文字); 参考例4-9 因此, 都需对进位位C进行求反操作。 18:13:32

(1)多字节十进制BCD码减法 编程代码: R1: 被减数低字节地址; R2: 字节数; R3: 差的字节数。 R0: 减数低字节地址;也是最后结果差(BCD码)的低字节地址 07H位地址存最终结果符号位。0表示结果为正,1表示结果为负。 SUBCD: MOV R3, #00H ;差的字节数置0 CLR 07H ;符号位单元清0 CLR C ;下面用带进位减法指令SUBB, 借位位C清0 SUBCD1: MOV A, #9AH SUBB A, @R0 ;求减数的100的补码 ADD A, @R1 ;补码与被减数相加 DA A ;十进制加法调整指令 MOV @R0, A ;结果差送到R0间接寻址单元 INC R0 ;减数地址值增1, 指向高字节 INC R1 ;被减数地址值增1, 指向高字节 INC R3 ;差的字节数增1 CPL C ;进位求反,以形成正确借位 DJNZ R2, SUBCD1 ;每字节减法算法相同,未完循环, 减完 顺序执行, JNC SUBCD2 ;无借位去SUBCD2返主, 否则继续 SETB 07H ;差为负置符号位07H为“1” SUBCD2: RET ;返回 18:13:32

GO (2)多字节乘法运算子程序 单片机指令系统中只有单字节乘法指令MUL AB, 而工 程应用中常需8位乘16位、两个16位数相乘的运算。 以两个16位无符号数相乘为例说明多字节乘法程序设计。 设被乘数放在R2、R3两单元(高字节在前), 乘数放在R6、 R7两单元, 两个双字节无符号数相乘, 结果送33H、32H、 31H、30H。 算法示意图如图所示。 (R3R7)L表示R3×R7的低8位, (R3R7)H表示R3×R7的高8位, 其余几项的含义类似。 程序如下: 18:13:32

(2)多字节乘法运算子程序 MOV B, R7 MUL AB ;R3×R7 MOV 30H, A ;(30H) ← (R3×R7)L DMUL: MOV A, R3 MOV B, R7 MUL AB ;R3×R7 MOV 30H, A ;(30H) ← (R3×R7)L MOV 31H, B ;(31H) ← (R3×R7)H MOV A, R2 MUL AB ;R2×R7 ADD A, 31H ;(R3×R7)H+(R2×R7)L MOV 31H, A CLR A ADDC A, B ;进位位C与(R2R7)H加 MOV 32H, A ;(32H) ← (R2R7)H 18:13:32

(2)多字节乘法运算子程序 MOV A, R3 MOV B, R6 MUL AB ;R3×R6 ADD A, 31H MOV 31H, A MOV A, B ADDC A, 32H ;(R2×R7)H+(R3×R6)H MOV 32H, A MOV F0, C ;暂存Cy ;因下面乘法使C清0 ;也可CLR A, ADDC A, #0, MOV 33H, A;下面程序相应修改 程序状态标志寄存器PSW 位号 D7 D6 D5 D4 D3 D2 D1 D0 符号 CY AC F0 RS1 RS0 OV F1 P F0: 用户标志位 18:13:32

(2)多字节乘法运算子程序 MOV F0, C ;暂存Cy MOV A, R2 MOV B, R6 MUL AB ;R2×R6 ADD A, 32H MOV 32H, A CLR A MOV ACC.0, C ;或 ADDC A, #0 MOV C, F0 ;前次加法进位送C, 为ADDC加(R2R6)H准备 ADDC A, B MOV 33H, A RET 程序状态标志寄存器PSW 位号 D7 D6 D5 D4 D3 D2 D1 D0 符号 CY AC F0 RS1 RS0 OV F1 P F0: 用户标志位 18:13:32

5、数据排序程序设计 数据排序是将数据块中的数据按升序或降序排列。下 面以数据升序排序为例, 说明数据排序程序设计方法。 数据升序排列常采用冒泡法。冒泡法是一种相邻数据 互换的排列方法,同查找极大值方法一样,一次冒泡 即找到数据块的极大值放到数据块最后, 再一次冒泡,次大数排在倒数第二位置,多次冒泡实现升序排列。 例, 将片内RAM 30H~37H中的数据从小到大升序排列。 设R6为循环次数计数器, R7为比较次数计数器。 F0为冒泡过程中是否有数据交换的状态标志,F0=0表 示无交换发生,F0=1表示有互换发生,须继续循环。 R0为指向RAM单元的地址指针初值为30H。 18:13:32

冒泡法数据排序程序流程图 数据在30H~37H中; R6为循环次数计数器 R7为比较次数计数器; F0为数据交换状态标志; R0地址指针. 18:13:32

冒泡法数据排序程序 SORT: MOV R6,#07H ;循环次数送到R6 GOON: CLR F0 ;交换标志清0 MOV R0, #30H ;数据首址送R0 MOV A, R6 MOV R7, A ;各次冒泡比较次数送R7 LOOP: MOV A, @R0 ;取前数 MOV 3BH, A ; 3BH单元存前数 INC R0 MOV 3AH, @R0 ;取后数送3AH单元 CLR C CJNE A, 3AH, EXCH LJMP NEXT A≥3AH时清C, A<3AH 时置C 18:13:32

冒泡法数据排序程序 CJNE A, 3AH, EXCH LJMP NEXT A≥3AH清C, A<3AH置C EXCH: JC NEXT ;前数(3BH)小于后数(3AH)不交换 MOV @R0, 3BH ;3BH单元内前数存后数地址 DEC R0 ; R0指向前数 MOV @R0, 3AH ; 3AH单元后数存前数地址 INC R0 ; R0指向后数地址 SETB F0 ;置交换标志位 NEXT: DJNZ R7, LOOP ;未比较完, 进行下一次比较 JNB F0, DONE ;一次也没交换, 说明已按顺序排列 DJNZ R6, GOON ; 循环次数减1, 不为0进下一轮循环 DONE: RET ;返回 18:13:32

6、代码转换程序设计 在汇编语言程序设计中,数据输入/输出、A/D、D/A 转换等常采用BCD码,字符的存储用ASCII码,算术 逻辑运算又采用二进制数。 除了用硬件逻辑实现转换外,可采用算法处理和查 表方法软件实现。 (1)4位二进制数转换为ASCII代码 从ASCII编码表可知,若4位二进制数小于10,则此 二进制数加上30H即变为相应的ASCII码,若大于10 (包括等于10, 是字符ABCDEF),则应加37H。 入口: 转换前4位二进制数存R2。 出口: 转换后的ASCII码存R2。 41H A 42H B 43H C 44H D 45H E 46H F 37H+0AH=41H 18:13:32

(1)4位二进制数转换为ASCII代码 ASCB1: MOV A, R2 ANL A,#0FH ;取出4位二进制数 CJNE A, #0AH, NOTA ;影响CY标志, 但是不改变A中的值 NOTA: JC LOOP ;该数<10去LOOP ADD A, #07H ;否则加37H(下面还加30H) LOOP: ADD A, #30H ;加30H MOV R2, A ;转换之ASCII码送R2中 RET ;返回 18:13:32

(3)BCD码转换为二进制码子程序 例: 设有用BCD码表示的4位十进制数分别存于R1, R2 中, 其中R2存千位和百位数, R1存拾位和个位数, 要把 其转换成二进制码。 解决思路:可用由高位到低位逐位检查BCD码的数值, 然后累加各十进制位(乘权值)对应的二进制数来实现。 其中, 1000=03E8H, 100=0064H, 10=000AH (个位数的 BCD码与二进制码相同)。 R2 千位数 百位数 R1 十位数 个位数 入口: 待转换的BCD码存于R1, R2中, 分配如下: 低位字节 : R1 ; 高位字节 : R2 出口: 结果存在20H, 21H单元中, 其中20H存低字节, 21H存高字节。 18:13:32

(3)BCD码转换为二进制码子程序 BCDB11:MOV 20H, #00H MOV 21H, #00H ;存结果单元清0 MOV R3, #0E8H MOV R4, #03H ;1千的二进制数03E8H送R3, R4 MOV A, R2 ANL A, #0F0H ;取千位数 SWAP A ;将千位数移至低四位 JZ BRAN1 ;千位数为0则转BRAN1, 去处理百位数 LOOP1: DEC A LCALL ADDT ;千位数不为0, 加千位数二进制权码 ;千位数是n, 就加n次千位数二进制码03E8H JNZ LOOP1 ;本循环即实现千位数n乘权值03E8H 18:13:32

BRAN1:MOV R3, #64H ;下面实现百位数转二进制码 MOV R4, #00H ;百位数的二进制码64H送R3, R4 MOV A, R2 ANL A, #0FH ;取百位数 JZ BRAN2 ;百位数是0转BRAN2, 去处理十位数 LOOP2: DEC A LCALL ADDT ;加百位数二进制权码 JNZ LOOP2 ;百位数是n, 就加n次64H BRAN2: MOV R3, #0AH ;十位数权值0AH送R3, R4=00H MOV A, R1 ;下面实现十位数转二进制码 ANL A, #0F0H ;取十位数 SWAP A JZ BRAN3 ;十位数为0转BRAN3, 去处理个位数 LOOP3: DEC A LCALL ADDT ;十位数不为0, 加十位数二进制权码 JNZ LOOP3 ;十位数是n, 就加n次0AH 18:13:32

MOV R3, A ;个位数(权值是自身)送R3, R4=00H LCALL ADDT ;加个位数二进制码 RET BRAN3: MOV A, R1 ANL A, #0FH ;取个位数 MOV R3, A ;个位数(权值是自身)送R3, R4=00H LCALL ADDT ;加个位数二进制码 RET ADDT: PUSH PSW PUSH ACC CLR C MOV A, 20H ;20H(低), 21H单元存累加的转换结果 ADD A, R3 ;累加转换结果 MOV 20H, A MOV A, 21H ADDC A, R4 MOV 21H, A POP ACC POP PSW RET ; R3, R4存1千(百, 十)的二进制数权值03E8H(0064H, 000AH) 18:13:32

两个16位的数据指针:DPTR0和DPTR1。它们的逻 辑地址相同,但是物理上是独立的。 7、IAP15W4K58S4单片机双数据指针的使用 两个16位的数据指针:DPTR0和DPTR1。它们的逻 辑地址相同,但是物理上是独立的。 功能:利用这两个数据指针,可以方便地进行数据的 迁移和拷贝。 使用方法:这两个数据指针在指令中只能以DPTR的 形式出现,因此,在使用中,需进行切换。这种切换 是通过设置辅助寄存器AUXR1中的DPS位实现的。 当DPS选择位为0时, 选择DPTR0; 当DPS选择位为1时, 选择DPTR1。 AUXR1各位定义: 位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 S1_S1 S1_S0 CCP_S0 CCP_S1 SPI_S1 SPI_S0 DPS 18:13:32

[例4-11]编程实现将单片机内部扩展RAM中0000H~ 000FH单元中内容传送到0040H~004FH单元中。 7、IAP15W4K58S4单片机双数据指针的使用 AUXR1各位定义 位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 S1_S1 S1_S0 CCP_S0 CCP_S1 SPI_S1 SPI_S0 DPS DPS:DPTR寄存器选择位。 0:选择DPTR0; 1:选择DPTR1 [例4-11]编程实现将单片机内部扩展RAM中0000H~ 000FH单元中内容传送到0040H~004FH单元中。 思路:可以分别由DPTR0和DPTR1分别指向源数据地 址和目的数据地址。 18:13:32

AUXR1 DATA 0A2H ;定义辅助寄存器AUXR1直接地址 ORG 0000H LJMP MAIN ORG 0100H 7、IAP15W4K58S4单片机双数据指针的使用 编程如下: AUXR1 DATA 0A2H ;定义辅助寄存器AUXR1直接地址 ORG 0000H LJMP MAIN ORG 0100H MAIN: MOV SP, #30H ;设置堆栈指针 MOV R2, #10H ;设置计数值(传送的字节数16) ANL AUXR1, #0FEH ;令DPS.0=0,选择DPTR0 MOV DPTR, #0000H ;置源数据地址指针DPTR0=0H ORL AUXR1, #01H ;令DPS.0=1,选择DPTR1 ;该句可用INC AUXR1代替(思考: 为何?) MOV DPTR, #0040H ;置目的数据地址指针DPTR1=40H 或$INCLUDE (STC15.INC); 包含STC15寄存器定义头文件 18:13:32

LOOP: ANL AUXR1, #0FEH ;该句可用INC DEC AUXR1代替 MOVX A, @DPTR ; A← (DPTR0) 7、IAP15W4K58S4单片机双数据指针的使用 LOOP: ANL AUXR1, #0FEH ;该句可用INC DEC AUXR1代替 MOVX A, @DPTR ; A← (DPTR0) INC DPTR ;修正源数据地址指针DPTR0+1 ORL AUXR1, #01H ;该句可用INC AUXR1代替, MOVX @DPTR, A ; (DPTR1) ← A INC DPTR ;修正目的数据地址指针DPTR1+1 DJNZ R2, LOOP ;传送字节数16没完, 继续循环传送 SJMP $ ;$表示本条语句地址, 本指令是死循环等待 ;SJMP $ 相当于HERE: SJMP HERE END 选DPTR0 选DPTR1 18:13:32

8、IAP15W4K58S4单片机数据Flash(EEPROM)的使用 IAP15W4K58S4单片机片内集成1KB的数据Flash存储 器, 可作为EEPROM使用, 用来保存程序的设置参数。 GO 【例4-12】一个完整的数据Flash操作实例。 $INCLUDE (STC15.INC) ;包含IAP15W4K58S4寄存器定义文件 ;定义ISP/IAP命令 ISP_IAP_BYTE_READ EQU 1H ;字节读 ISP_IAP_BYTE_PROGRAM EQU 2H ;字节编程 ISP_IAP_SECTOR_ERASE EQU 3H ;扇区擦除 ;定义Flash操作等待时间及允许IAP/ISP操作的常数(设置IAP_CONTR) ENABLE_IAP EQU 82H ;系统工作时钟<20MHz时 DEBUG_DATA EQU 5AH ;EEPROM单元的测试值,如正确应等于该值 START_ADDRESS EQU 0000H ;EEPROM测试起始地址 18:13:33

[例4-12] 一个完整的数据Flash操作实例(续) ORG 0000H LJMP MAIN ORG 0100H MAIN: MOV SP, #70H ;堆栈指针指向 70H单元 LCALL Delay ;延时 ;下面程序读出EEPROM测试起始地址单元的内容 MAIN1: MOV DPTR, #START_ADDRESS ;将EEPROM测试起始地址0H送DPTR数据指针 LCALL Byte_Read ;调子程读数据经IAP_DATA送入累加器A MOV 40H, A ;将EEPROM 的值送40H 单元保存 CJNE A, #DEBUG_DATA, NOT_EQU_DEBUG_DATA ;若数据不正确(非5AH),就跳转;数据正确(5AH)时, 顺序执行 LCALL Delay ;延时 SJMP $ ;数据正确, CPU在此无限循环执行此句 18:13:33

[例4-12] 一个完整的数据Flash操作实例(续) NOT_EQU_DEBUG_DATA: ;下面代码是当EEPROM里的数据错误时, 需进行的处理程序 ;即将该EEPROM所在的扇区整个擦除,将正确的数据写入 LCALL Delay ;延时 MOV DPTR, #START_ADDRESS ;将EEPROM测试起始地址0H送DPTR数据指针 LCALL Sector_Erase ;调擦除整个扇区子程序 ;将EEPROM测试起始地址送DPTR数据指针 MOV A, #DEBUG_DATA ;写入 EEPROM 数据 #DEBUG_DATA(5A) LCALL Byte_Program ;字节编程 SJMP $ ;字节编程后,CPU在此无限循环执行此句 18:13:33

[例4-12] 一个完整的数据Flash操作实例(续) ;下面程序是读一字节, 调用前需打开IAP功能, Byte_Read: ;入口: DPTR=字节地址, 返回: A=读出字节 MOV IAP_CONTR, #ENABLE_IAP ; IAP_CONTR←82H, 打开IAP功能,设置Flash操作等待时间 MOV IAP_CMD, #ISP_IAP_BYTE_READ ; IAP_CMD←01H,设置为IAP/ISP字节读模式命令 MOV IAP_ADDRH, DPH ;设置目标单元地址的高8位地址0H MOV IAP_ADDRL, DPL ;设置目标单元地址的低8位地址0H MOV IAP_TRIG, #5AH ;先送5AH,再送A5H到ISP/IAP触发寄存器 MOV IAP_TRIG, #0A5H ;送A5H后,ISP/IAP命令即被触发启动 NOP MOV A, IAP_DATA ;读出数据在IAP_DATA单元,送累加器A LCALL IAP_Disable ;关闭IAP功能, 清相关特殊功能寄存器 RET 字节读操作也可用MOVC指令, 用MOVC访问数据Flash存储器时, 其地址范围为F000H~F3FFH。 18:13:33

[例4-12] 一个完整的数据Flash操作实例(续) ;下面程序是字节编程, 调用前需打开IAP功能, Byte_Program: ;入口:DPTR=字节地址, A=需写入的数据 MOV IAP_CONTR, #ENABLE_IAP ; IAP_CONTR←82H, 打开IAP功能,设置Flash操作等待时间 MOV IAP_CMD, #ISP_IAP_BYTE_PROGRAM ; IAP_CMD←02H, 设置为IAP/ISP字节读模式命令 MOV IAP_ADDRH, DPH ;设置目标单元地址的高8位地址0H MOV IAP_ADDRL, DPL ;设置目标单元地址的低8位地址0H MOV IAP_DATA, A ;要编程的数据先送进ISP_DATA寄存器 MOV IAP_TRIG, #5AH ;先送5AH,再送A5H到ISP/IAP触发寄存器 MOV IAP_TRIG, #0A5H ;送完A5H后,ISP/IAP命令即被触发启动 NOP LCALL IAP_Disable ;关闭 IAP功能, 清相关特殊功能寄存器 RET 18:13:33

[例4-12] 一个完整的数据Flash操作实例(续) Sector_Erase: ;下面程序擦除扇区, 入口: DPTR =扇区地址 MOV IAP_CONTR, #ENABLE_IAP ;打开IAP功能,设置 等待时间 MOV IAP_CMD, #03H ;设置为IAP/ISP扇区擦除模式命令 MOV IAP_ADDRH, DPH ;设置目标单元地址的高8位地址 MOV IAP_ADDRL, DPL ;设置目标单元地址的低8位地址 MOV IAP_TRIG, #5AH ;先送5AH,再送A5H到ISP/IAP触发寄存器 MOV IAP_TRIG, #0A5H ;送A5H 后,ISP/IAP命令即被触发启动 NOP LCALL IAP_Disable ;关闭IAP功能, 清相关特殊功能寄存器 RET IAP_Disable: ;下面程序关闭IAP功能, 清相关特殊功能寄存器 ;一次连续的IAP操作完成之后建议关闭IAP功能,不需每次都关 MOV IAP_CONTR, #0 ;关闭 IAP 功能 MOV IAP_ADDRH, #0FFH ;送地址高字节单元,指向非EEPROM区 MOV IAP_ADDRL, #0FFH ;送地址低字节单元为FFH,防止误操作 RET 18:13:33

[例4-12] 一个完整的数据Flash操作实例 (续) ;------- ---------------- 延时子程序------------------------- Delay: CLR A MOV R0, A MOV R1, A MOV R2, #20H Delay_Loop: DJNZ R0, Delay_Loop DJNZ R1, Delay_Loop DJNZ R2, Delay_Loop RET END 延时时间: 256*256*32(20H) *时钟周期 18:13:33

第4章 作业 基本: 4-1; 4-2; 4-3; 4-4; 4-5; 4-6; 4-12; 综合: 4-11; 4-14; 18:13