《单片机程序设计》PPT课件.ppt_第1页
《单片机程序设计》PPT课件.ppt_第2页
《单片机程序设计》PPT课件.ppt_第3页
《单片机程序设计》PPT课件.ppt_第4页
《单片机程序设计》PPT课件.ppt_第5页
已阅读5页,还剩134页未读 继续免费阅读

下载本文档

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

文档简介

第4章 单片机程序设计方法 常用伪指令 定位伪指令ORG汇编结束伪指令END符号定义伪指令EQU定义字节数据伪指令DB定义字数据伪指令DW数据赋值伪指令DATA位地址赋值伪指令BIT定义空间伪指令DS数据地址赋值伪指令XDATA 逻辑及移位类指令 逻辑与指令 6条 例 ORG0000H 程序开始MOVA 34H A 34HANLA 0FH A A 0FH 04HNOPEND 结束 与运算技巧 与运算有见零为零的特点 通常用来将数据的某几位清零 其他位保持不变 逻辑或指令 6条 例 ORG0000H 程序开始MOVA 49H A 49HORLA 07H A A 07H 4FHNOPEND 结束 或运算技巧 或运算有见1为1的特点 通常用来将数据的某几位置1 其他位保持不变 逻辑异或指令 6条 例 ORG0000H 程序开始MOVA 55H A 55HXRLA 0FFH A A FFH AAHNOPEND 结束 异或运算技巧 异或运算有见1取反的特点 通常用来将数据的某几位取反 其他位保持不变 累加器A清0和取反指令 ORG0000H 程序开始MOVA 8CH A 8CHCLRA A 00HEND 结束 ORG0000H 程序开始MOVA 8CH A 8CHCPLA A 73HEND 结束 A 0 A 7 A 0 A 7 A 0 A 7 A 0 A 7 CY CY RLARRARLCARRCA 注意 执行带进位的循环移位指令之前 必须给CY置位或清零 循环移位指令 使用技巧 循环右移一次相当于除以2 ORG0000HMOVA 80HMOVR5 8LOOP RRADJNZR5 LOOPNOPEND 使用技巧 循环左移一次相当于乘以2 ORG0000HMOVA 01HMOVR4 8LOOP RLADJNZR4 LOOPNOPEND 循环左移指令 循环左移RLA 进位位C与操作数作为整体循环移位 1000000 0 C A RLCA RLCA 1 0000000 1 0 C 0 0000001 RLCA 1 位传送指令 注意 位存储单元之间的数据传递要通过进位标志CY来完成 例 MOVC P0 0 CY P0 0 MOVACC 3 C ACC 3 CY MOV05H C 05H CY 1位二进制数在位存储单元之间传递 2 位置位和位清零指令 设置位状态 例如 CLRC CY 0CLRB 0 B 0 0CLRP2 0 P2 0 0CLR7FH 7FH 0 例如 SETBC CY 1SETBRS1 RS1 1SETBP3 0 P3 0 1SETB60H 60H 1 3 位运算指令 注意 C是布尔机的累加器 例如 ANLC P3 2ORLC P3 2CPLCCPLP3 0 利用位逻辑运算指令可以实现各种各样的逻辑功能 利用位逻辑运算指令编程实现下面硬件逻辑电路的功能 MOVC P1 0ANLC P1 1CPLCORLC P1 2MOV0F0H CMOVC P1 3ORLC P1 4ANLC 0F0HMOVP1 5 C 数据的拼拆 例 设在30H和31H单元中各有一个8位数据 30H x7x6x5x4x3x2x1x0 31H y7y6y5y4y3y2y1y0现在要从30H单元中取出低5位 并从31H单元中取出低3位完成拼装 拼装结果送40H单元保存 并且规定 40H y2y1y0 x4x3x2x1x0利用逻辑指令ANL ORL来完成数据的拼拆 MOV40H 30H 将x7 x0传送到40H单元ANL40H 00011111B 将高3位屏蔽掉MOVA 31H 将y7 y0传送到累加器中SWAPA 将A的内容左移4次RLA y2 y0移到高3位ANLA 11100000B 将低5位屏蔽掉ORL40H A 完成拼装任务 4 位转移指令 MOVA 00110111BJBACC 1 LOOP1MOVB 4SJMPLOOP2LOOP1 MOVB 5LOOP2 SJMP 程序功能 根据ACC 1的状态 设定B的值 5 判CY标志指令 3 3 4控制转移类指令 无条件转移指令 4条 1 长转移指令 LJMPAAAAH AAAAH PC 注意 该指令可以转移到64KB程序存储器中的任意位置 2 绝对转移指令 AJMPaddr11 PC 2 PC addr11 PC 10 PC 0 3 相对转移指令 SJMPrel 4 间接转移指令指令格式 JMP A DPTR PC A DPTR 该指令的特点是转移地址可以在程序运行中加以改变 DPTR一般为确定值 根据累加器A的值来实现转移到不同的分支 在使用时往往与一个转移指令表一起来实现多分支转移 下面的程序能根据累加器A的值0 1 2 3转移到相应的TAB0 TA6分支去执行 MOVDPTR TABLE 表首地址送DPTRADDA ACCJMP A DPTR 根据A值转移TABLE AJMPTAB0 当 A 0时转TAB0执行AJMPTAB2 当 A 1时转TAB2执行AJMPTAB4 当 A 2时转TAB4执行AJMPTAB6 当 A 3时转TAB6执行 条件转移指令 8条 1 累加器A判0指令 2条 2 减1非零转移指令 2条 3 比较转移指令 4条 操作数为无符号数 条件转移类指令范例 方案一 还有什么方法实现循环的终止 将00H 0FH这16个数顺序地置入片内RAM20H 2FH单元中 MOVR0 20HMOVR7 0FHCLRALOOP MOV R0 AINCAINCR0DJNZR7 LOOPSJMP 地址指针 循环计数器 第一个数据 条件转移类指令范例 方案二 MOVR0 20HMOVR7 0FHCLRALOOP MOV R0 AINCAINCR0CJNEA 0FH LOOPSJMP 条件转移类指令范例 方案三 MOVR0 20HMOVA 0FHMOV30H 00HLOOP MOV R0 30HINC30HINCR0DECAJNZLOOPSJMP 地址指针 循环计数器 第一个数据 条件转移类指令范例 方案四 MOVR0 20HMOVA 0FHMOV30H 00HLOOP MOV R0 30HINC30HINCR0SUBBA 01HJNCLOOPSJMP 地址指针 循环计数器 第一个数据 调用和返回指令 8条 1 绝对调用指令 1条 2 长调用指令 1条 3 返回指令 4 空操作 分支程序 循环程序 简单程序 查表程序 子程序 应用举例 汇编语言程序设计 简单程序 结构特点 按指令的先后顺序依次执行 将20H单元的两个压缩BCD码拆开变成ASCII码 存入21H 22H单元 假设20H中的BCD码为00110100 什么是BCD码 什么是ASII码 0011 压缩BCD码 0011 0011 0100 低四位ASII码 高四位ASII码 方法1 将BCD码除以10H 恰好是将BCD码分别移到了A B的低4位 然后再各自与30H相或 即成为ASCII码 方法2 利用半字节交换指令来实现 ORG0000HMOVA 20HMOVB 10HDIVABORLB 30HMOV22H BORLA 30HMOV21H ASJMP END 简单程序例1 方法1 源程序如下 0011 0100 PC PC 00110100 00010000 PC 0011 0000 00000100 PC 00110100 PC PC PC 0011 PC ORG0000HMOVR0 20HMOVA 30HXCHDA R0MOV22H AMOVA R0SWAPAORLA 30HMOV21H ASJMP END 简单程序例1 方法2 PC PC PC PC PC PC PC PC 源程序如下 0011 00100000 0011 0100 0000 0100 0011 0100 0011 0000 0011 0000 0011 PC 0011 ORG0000HMOVA 30H 取值ANLA 0FH 取低4位ADDA 30H 转换成ASCII码MOV32H A 保存结果MOVA 30H 取值SWAPA 高4位与低4位互换ANLA 0FH 取低4位 原来的高4位 ADDA 30H 转换成ASCII码MOV31H A 保存结果SJMP END 简单程序例1 方法3 双字节求补 设原码存放在R1R0中 求补后存于R3R2 补码 0 原码 ORG0000HLJMPMAINORG0100HMAIN CLRCCLRASUBBA R0MOVR2 ACLRASUBBA R1MOVR3 ASJMP END 双字节求补 设原码存放在R1R0中 求补后存于R3R2 取反加1 ORG0000HLJMPMAINORG0100HMAIN MOVA R0CPLAADDA 1MOVR2 AMOVA R1CPLAADDCA 0MOVR3 ASJMP END 1 单分支 单分支程序的基本结构 2 分支程序 例 如图所示 设计一段程序实现功能 如果 A 中1的个数为奇数 所有的二极管发光 如果全0 则只让VD0 VD3发光 否则全灭 ORG0000HJBP JISHJZQUANMOVP2 00HSJMPTOendJISHU MOVP2 0FFHSJMPTOendQUAN MOVP2 0FHTOend SJMP END 流程图 源程序 判断奇偶标志位的值 判断 A 的值是否为0 A 有偶数个1 二极管灭 A 有奇数个1 二极管全亮 A 为0 VD0 VD3亮 注意 在MCS 51单片机中 实现单分支常用的指令有 JZ JNZ DJNZ CJNE JC JNC JB JNB JBC等 虚线框代表一个单分支 2 双分支 双分支程序的基本结构 双分支程序设计例 内部RAM的40H单元和50H单元各存放了一个8位无符号数 请比较这两个数的大小 比较结果用发光二极管显示 LED为低有效 若 40H 50H 则P1 0管脚连接的LED1发光 若 40H 50H 则P1 1管脚连接的LED2发光 题意分析 本例是典型的分支程序 根据两个无符号数的比较结果 判断条件 分别点亮相应的发光二极管 比较两个无符号数常用的方法是将两个数相减 然后判断有否借位CY 若CY 0 无借位 则X Y 若CY 1 有借位 则X Y 程序的流程图如下图所示 两数比较流程图 XDATA40H 数据地址赋值伪指令DATAYDATA50HORG0000HMOVA X X ACLRC CY 0SUBBA Y 带借位减法 A Y CY AJCL1 CY 1 转移到L1CLRP1 0 CY 0 40H 50H 点亮P1 0连接的LED1SJMPFIN 直接跳转到结束等待L1 CLRP1 1 40H 50H 点亮P1 1接的LED2FIN SJMP END 3 多分支 多分支程序的基本结构 例 在某单片机系统中 按下一按键 键值 代表哪个键被按下 存放在内部RAM的40H单元内 设计一段程序实现功能 如果 40H 00H 调用子程序SUB1 如果 40H 01H 调用子程序SUB2 如果 40H 02H 调用子程序SUB3 如果 40H 03H 调用子程序SUB4 如果 40H 04H 调用子程序SUB5 流程图 程序清单 MOV40H AMOVDPTR TABRLAADDA 40HJMP A DPTR TAB LCALLSUB1LCALLSUB2LCALLSUB3LCALLSUB4LCALLSUB5 设定表格首地址 40H 3传送给A 查表转移 转移地址表 3 循环程序 MOVR0 10MOVR1 30HSTART MOVA R1 取数JBACC 7 NEG 若为负数 转NEGJZZER0 若为零 转ZER0ADDA 02H 若为正数 求X 2AJMPSAVE 转到SAVE 保存数据ZER0 MOVA 64H 数据为零 Y 100AJMPSAVE 转到SAVE 保存数据NEG DECACPLA 求 X SAVE MOV R1 A 保存数据INCR1 地址指针指向下一个地址DJNZR0 START 数据未处理SJMP 暂停 例 在起始地址为M的内部数据存储器中放有100个数 其中有一个数的值等于a 试编一程序 求出这个数的地址 送N单元 若这个数不存在 则将00H送入N单元 NEQU08HMEQU09HORG2040HSTART MOVR0 MMOVR1 64HLOOP CJNE R0 a WSJMPWWW INCR0DJNZR1 LOOPMOVN 00HSJMPWWWWW MOVN R0WWW SJMP 例 在起始地址为M的内部数据存储器中放有100个数 其中有一个数的值等于a 试编一程序 求出这个数的地址 送N单元 若这个数不存在 则将00H送入N单元 4 子程序设计 在实际问题中 常常会遇到在一个程序中多次用到相同的运算或操作 若每遇到这些运算或操作 都从头编起 将使程序繁琐 浪费内存 因此在实际中 经常把这种多次使用的程序段 按一定结构编好 存放在存储器中 当需要时 可以调用这些独立的程序段 通常将这种可以被调用的程序段称为子程序 主要内容 1 主程序与子程序的关系 2 子程序嵌套 3 子程序的调用与返回 1 主程序与子程序的关系 主程序MAIN 主程序 LCALLSUB 调用子程序 子程序入口地址 RET ORG0000HMAIN MOVA 0FEH 送显示初值LP MOVR0 10 送闪烁次数LP0 MOVP1 A 点亮LEDLCALLDELAY 延时MOVP1 0FFH 熄灭灯LCALLDELAY 延时DJNZR0 LP0RLASJMPLPEND 例 LED灯的闪烁点亮 一 2 子程序嵌套 子程序嵌套 或称多重转子 是指在子程序执行过程中 还可以调用另一个子程序 子程序SUB1 子程序1 主程序MAIN 程序 程序 LCALLSUB1 RET 子程序1 子程序SUB2 RET 子程序2 LCALLSUB2 3 子程序的调用与返回 问题 子程序调用 返回到主程序中的正确位置 并接著执行主程序中的后续指令呢 为了解决这个问题 采用了堆栈技术 子程序SUB1 子程序1 主程序MAIN 程序 程序 RET 子程序1 子程序SUB2 RET 子程序2 2010 2013 2110 2113 2100 2200 2013 20 13 PC 2113 13 21 堆栈区 堆栈指针SP 堆栈 LCALLSUB1 LCALLSUB2 21 13 20 13 子程序设计注意事项 1 要给每个子程序起一个名字 也就是入口地址的代号 2 要能正确地传递参数 即首先要有入口条件 说明进入子程序时 它所要处理的数据放在何处 如 是放在A中还是放在某个工作寄存器中等 另外 要有出口条件 即处理的结果存放在何处 3 注意保护现场和恢复现场 在子程序使用累加器 工作寄存器等资源时 要先将其原来的内容保存起来 即保护现场 当子程序执行完毕 在返回主程序之前 要将这些内容再取出 送还到累加器 工作寄存器等原单元中 这一过程称为恢复现场 1 运算类子程序设计 例 假如在MCS 51单片机内部RAM中30H 37H单元 38H 3FH单元分别存放有两个8字节BCD码十进制数 设计一段程序将这两个数相加 并把结果存于2FH 37H单元中 小地址存数据的高字节 分析 先清Cy位 把 37H 和 3FH 进行带Cy相加 再进行十进制调整 结果存于37H单元中 把 36H 和 3EH 进行带Cy相加 再进行十进制调整 循环至结束 结果把最高字节的Cy存入2FH单元 ORG0000HMOVR2 08HMOVR0 37HMOVR1 3FHCLRCLOP MOVA R0ADDCA R1DAAMOV R0 ADECR0DECR1DJNZR2 LOPCLRARLCAMOV2FH ASJMP END 设定循环次数 R0和R1分别指向加数和被加数的首地址 相加 并回存结果 R0和R1分别指向加数和被加数的下一地址 判断循环次数 存进位标志 极值查找程序例 在MCS 51单片机内部RAM的40H 47H单元中存有8个无符号数 设计一段程序找出其中的最大值 并存放到48H单元中 这是一个求最大值的问题 分析 先把 A 40H 然后将 41H 和 A 进行比较 如果 41H A 则 A 41H 然后和下一个字节进行比较 依次类推 最后 A 必定是最大值 ORG0000HMOVR2 07HMOVR0 40HMOVA R0LOOP INCR0MOVB R0CJNEA B NEXNEX JNCNETMOVA BNET DJNZR2 LOOPMOV48H ASJMP END 设定循环次数R1 R0作为数据指针 指向数据区第一个字节 取出下一个字节 存入B 如果 A B 则 A B 次数到否 到则取出 A 48H 2 查表程序设计 程序使用的专用指令 MOVCA A PCMOVCA A DPTR一般情况下 常使用后者程序设计一般规则 先确定表格存放的位置在表格中填入相应的数据查表时先将表格的首地址给DPTR 再将要查表的数据送给A 最后用MOVCA A DPTR 例 假如在MCS 51单片机内部RAM中40H单元内存放的是一个角度 范围0 90 设计一段程序 计算出200 sin 把结果存入41H单元中 结果只取整数 分析 先建立一个相应的数值表格 定义在程序存储器中 利用输入的值进行查表 程序如下 ORG0000HMOVDPTR TABLEMOVA 40HMOVCA A DPTRMOV41H ASJMP TABLE DB0 3 7 10 14 17 21 24 28 31 35 38DB41 45 48 199 200 200END 查表 表格内容 表格的数据是怎么计算出来的 例 假如在MCS 51单片机内部RAM中40H单元内存放的是一个参数x 范围0 10 设计一段程序 计算出5x3 4x2 3x 1 把结果存入41H和42H单元中 分析 先建立一个相应的数值表格 每个为2个字节 定义在程序存储器中 利用输入的值进行查表 程序如下 ORG0000HMOVDPTR TABLEMOVA 40HCLRCRLCA A 2 APUSHACCMOVCA A DPTRMOV41H APOPACCINCAMOVCA A DPTRMOV42H ASJMP TABLE DW0001H 000DH 003FH 00B5H 018DHDW02D1H 04DBH 078DH 0B19H 0F9DH 1537HEND 查表 得到高两位数 表格内容 查表 得到低两位数 例 128种分支程序设计 R3 转移的目的地址序号00 7FH 3 散转子程序设计 例 256种分支程序设计 R3 转移的目的地址序号00 FFH MOVA R3MOVDPTR TABCLRCRLCAJNCLOW128INCDPHLOW128 MOVB AINCAMOVCA A DPTR 取低8位地址PUSHACC 分支首址低8位进栈MOVA BMOVCA A DPTRPUSHACC 分支首址高8位进栈RETTAB DWROUT00 查表程序 表格是事先存放在ROM中的 一般为一串有序的常数 例如平方表 字型码表等 表格可通过伪指令DB来确定 通过查表指令MOVCA A DPTRMOVCA A PC来实现 在LED显示和键盘处理程序中将会用到 例用查表法计算平方 一 ORG0000HMOVDPTR TAB 表首地址送DPTRMOVA 05 被查数字05 AMOVCA A DPTR 查表求平方SJMP TAB DB0 1 4 9 16 25 36 49 64 81END 例用查表法计算平方 二 ORG0000H0000HMOVA 05 05 A0002HADDA 02 修正累加器A0004HMOVCA A PC 查表求平方0005HSJMP 2字节0007H DB0 1 4 9 16 25 36 49 64 81END 执行MOVCA A PC指令时 PC指向SJMP 指令 与表首地址相差2字节 数码管 a b c d e f g dp MSB LSB 一位十六进制数转换8段式数码管显示码 由于数与显示码没有规律 不能通过运算得到 只能通过查表方式得到 一位十六进制数转换8段式数码管显示码 设数放在R2中 查得的显示码也放于R2中 用MOVCA A DPTR查表 显示码表TAB DB3FH 06H 5BH 4FHDB66H 6DH 7DH 07HDB7FH 67H 77H 7CHDB39H 5EH 79H 71H ORG0200HCONVERT MOVDPTR TAB DPTR指向表首址MOVA R2 转换的数放于 MOVCA A DPTR 查表指令转换MOVR2 ARETTAB DB3FH 06H 5BH 4FHDB66H 6DH 7DH 07HDB7FH 67H 77H 7CHDB39H 5EH 79H 71H 在这个例子中 编码是一个字节 只通过一次查表指令就可实现转换 如编码是两个字节 则需要用两次查表指令才能查得编码 第一次取得低位 第二次取得高位 4 滤波子程序 工业控制对象的工作环境一般比较差 干扰源较多 一般计算机控制系统的模拟输入信号中 均含有各种干扰成分 它们来自被测信号源本身 传感器和外界等 消除和抑制干扰的方法很多 对于随机干扰信号 因为不是周期信号 很难用模拟滤波器取得满意的效果 这时 可以用数字滤波的方法予以削弱或滤除 数字滤波器实际上是一种程序滤波或软件滤波 常用的方法有中值滤波 算术平均滤波 加权平均滤波和惯性滤波等 例 编程实现防脉冲干扰平均值滤波 方法一 1 求最大值2 求最小值3 求所有采样值的和4 去掉最大值和最小值5 求平均值 方法二 例 设计一报警处理程序 只有采样值连续3次异常时 系统才进行报警处理 CHECK CLRC 清进位标志位MOVA Amax 读上限报警值SUBBA SAMP 判断是否超过上限报警值JCABNORMAL 超过上限 转ABNORMALMOVA Amin 读下限报警值SUBBA SAMP 判断是否超过下限报警值JNCABNORMAL 超过下限 转ABNORMALCLRFLAG 采样正常 清采样异常标志位AJMPRETU ABNORMAL JBFLAG ABNOR L 上次采样异常 转ABNOR LMOVNUM 02H 上次采样正常 重置允许连续异常次数SETBFLAG 置位采样异常标志位AJMPRETUABNOR L DECNUM 允许采样异常次数减1MOVA NUM 读允许连续采样异常次数JZALARM 允许采样异常次数 0 执行报警处理程序SETBFLAG 置位采样异常标志位AJMPRETUALARM 报警处理程序 RETU RET 5 定时子程序设计 单重循环延时例 假设单片机的fosc 12MHz 计算单片机执行下面程序消耗的时间 DELAY MOVR5 TIME 1机器周期MM NOP 1机器周期DJNZR5 MM 2机器周期RET 2机器周期执行完以上4条语句 所花时间 T 1 1 2 TIME 2 1 s推广计算式 T 机器周期数 循环体机器周期数 循环次数 初始化机器周期数 多重循环延时例 假设单片机的fosc 12MHz 计算单片机执行下面程序消耗的时间 DELAY2 MOVR3 TIME1 1机器周期LOOP1 MOVR2 TIME2 1机器周期LOOP2 NOP 1机器周期DJNZR2 LOOP2 2机器周期DJNZR3 LOOP1 2机器周期RET 2机器周期执行完以上6条语句 所花时间 T 1 1 1 2 TIME2 2 TIME1 2 1 s 循环程序设计 延时程序中延时时间的设定 源程序 指令周期DELAY MOVR3 X H2个T机器DEL2 MOVR4 Y H2个T机器DEL1 NOP1个T机器NOP1个T机器DJNZR4 DEL12个T机器DJNZR3 DEL22个T机器RET 指令周期 机器周期T机器与时钟周期T时钟的关系 T机器 12T时钟 12 1 fosc 1 s 假设晶振频率fosc为12M 延时时间的简化计算结果 1 1 2 X Y 延时时间怎样计算 若想延时100ms 只需修改计数初始值 即 1 1 2 125 200 s 100ms 多字节无符号数加法 设从片内RAM30H单元和40H单元有两个16字节数 把它们相加 结果放于30H单元开始的位置处 设结果不溢出 用R0作指针指向30H单元 用R1作指针指向40H单元 R0 R1 用R2为循环变量 初值为16 在循环体中作16次带进位加 加得的结果放回R0指向的单元 每次修改改变R0 R1指针位置 在第一次循环前应先将CY清零 程序 ORG1000HMOVR0 30HMOVR1 40HMOVR2 16CLRCLOOP MOVA R0ADDCA R1MOV R0 AINCR0INCR1DJNZR2 LOOPEND 例2 有两组BCD码分别存放在23H 22H单元和33H 32H单元 求它们的和并送入43H 42H单元中去 高位在前 低位在后 分析 0011 1000 0110 0101 0001 0001 1000 0111 BCD码83H BCD码11H BCD码78H BCD码56H 例2 有两组BCD码 如 1183H和5678H 分别存放在23H 22H单元和33H 32H单元 求它们的和 并送入43H 42H单元中去 高位在前 低位在后 解 MOVA 22HADDA 32HDAAMOV42H AMOVA 23HADDCA 33HDAAMOV43H ASJMP ORG0000HMOVA 22HADDA 32HDAAMOV42H AMOVA 23HADDCA 33HDAAMOV43H ASJMP END 此条加法指令可否改用带进位的 ADDC ORG2000HCLRCMOVA 22HADDA 32HDAAMOV42H AMOVA 23HADDCA 33HDAAMOV43H ASJMP END 10000011 01010110 00010001 01111000 10000011 01111000 11111011 01100001 00010001 01010110 01100111 01101000 PC PC PC PC PC PC PC PC PC 11111011 01100001 PC 01101000 PC 01100111 01010110 01111000 00010001 10000011 分支程序设计 结构特点 不一定按指令的先后顺序依次运行程序 程序的流向有两个或两个以上分支 根据指定条件选择程序的流向 如 1 分支程序有三种基本形式 即单分支 双分支 多分支 2 分支程序的设计要点如下 1 先建立可供条件转移指令测试的条件 2 选用合适的条件转移指令 3 在转移的目的地址处设定标号 例 设X存在30H单元中 根据下式X 2X 0Y 100X 0求出Y值 将Y值存入31H单元 X X 0分析 根据数据的符号位判别该数的正负 若最高位为0 再判别该数是否为0 分支程序的典型实例 ORG1000HMOVA 30H 取数JBACC7 NEG 负数 转NEGJZZER0 为零 转ZER0ADDA 02H 为正数 求X 2AJMPSAVE 转到SAVE 保存数据ZER0 MOVA 64H 数据为零 Y 100AJMPSAVE 转到SAVE 保存数据NEG DECACPLA 求 X SAVE MOV31H A 保存数据SJMP 设内部RAM20H单元和30H单元中分别存放了两个8位的无符号数X Y 若X Y则让P1 0管脚连接的LED亮 若X Y则让P1 1管脚连接的LED亮 方法1 两个数据做减法SUBB 可根据借位CY来判断两个数的大小 方法2 两个数据做比较CJNE 再根据是否相等和借位CY来判断两个数的大小 分支程序实例 数据比较大小 方法1编程 XDATE20HYDATE30HORG0000HMOVA XCLRCSUBBA YJCL1 X YCLRP1 0SJMPFINISHL1 CLRP1 1FINISH SJMP END XDATE20HYDATE30HORG0000HMOVA XCJNEA Y L0L0 JCL1 X YCLRP1 0SJMPFINISHL1 CLRP1 1FINISH SJMP END 方法2编程 分支程序实例 数据比较大小 两个有符号数的比较 问题1 如何表示有符号数 问题2 有符号数怎样比较大小 1 先判断符号位 负数小 正数大 2 符号相同 则用减法判断是否有借位 比较20H和30H单元两个有符号数的大小 结果按下述规律显示 20H 30H P1 0点亮 20H 30H P1 1点亮 20H 30H P1 2点亮 例 散转程序 散转程序是指通过修改某个参数后 程序可以有三个以上的流向 多用于键盘程序 常用的指令是JMP A DPTR 该指令是把16位数据指针DPTR的内容与累加器A中的8位无符号数相加 形成地址 装入程序计数器PC 形成散转的目的地址 DPTR A PC A中内容为8位无符号数 16位地址数 跳转表首送数据指针 例 根据R7的内容 转向各自对应的操作程序 R7 0 转入OPR0 R7 1 转入OPR1 R7 n 转入OPRn MAIN MOVDPTR JPTABMOVA R7ADDA R7JNCNOADINCDPHNOAD JMP A DPTRJPTAB AJMPOPR0AJMPOPR1AJMPOPR2OPR0 MOV40H 1SJMPFINISHOPR1 MOV40H 2SJMPFINISHOPR2 MOV40H 3FINISH SJMP R7 2 A 修正变址值 判有否进位 有进位则加到高字节地址 转向形成的散转地址人口 直接转移地址表 ORG0000HLJMPMAINORG0100HMAIN MOVA R3MOVDPTR PRGTBLMOVCA A DPTRJMP A DPTRPRGTBL DBPRG0 PRGTBLDBPRG1 PRGTBLDBPRG2 PRGTBLDBPRG3 PRGTBLPRG0 散转程序 入口条件 R3 四个程序段 从内部RAM256B读数从外部RAM256B读数从外部RAM64K读数从外部RAM4K读数 ORG0000HLJMPMAINORG0100HMAIN MOVA R3 1MOVDPTR PRGTBL 3MOVCA A DPTR 1JMP A DPTR 1PRGTBL DBPRG0 PRGTBL DB4DBPRG1 PRGTBLDBPRG2 PRGTBLDBPRG3 PRGTBLPRG0 01000106010A A 4 DPTR 0 x0106 PRG0 MOVA R0SJMPPRGEPRG1 MOVP2 R1MOVXA R0SJMPPRGEPRG2 MOVDPL R0MOVDPH R1MOVXA DPTRSJMPPRGEPRG3 MOVA R1ANLA 0FHANLP2 11110000BORLP2 AMOVXA R0PRGE SJMP 内部RAM读数 外部RAM256B读数 外部RAM64K读数 R1存放高4位地址 屏蔽高4位 P2口高4位可作通用I O口 只送12位地址 R0存放低8位地址从外部RAM读数 循环程序设计 例 编程实现P1口连接的8个LED显示方式如下 从P1 0到P1 7的顺序 依次点亮其连接的LED 子程序 ORG0000HSTART MOVR2 08H 设置循环次数MOVA 11111110B 送显示模式字NEXT MOVP1 A 点亮二极管ACALLDELAYRLA 左移一位 改变显示模式字DJNZR2 NEXT 循环次数减1 不为零 继续点亮SJMPSTART 下面一个二极管DELAY MOVR3 0FFH 延时子程序开始DEL2 MOVR4 0FFHDEL1 NOPDJNZR4 DEL1DJNZR3 DEL2RETEND A 0 A 7 数据传送程序 例 不同存储区域之间的数据传输 将内部RAM30H单元开始的内容传送到外部RAM0100H单元开始的区域 直到遇到传送的内容是0为止 地址指针R0赋初值 R0 A A DPTR 地址指针增1 地址指针DPTR赋初值 A 0 N Y 开始 结束 程序1 所有发光二极管不停地闪动 ORG0000H 程序从地址0000H开始存放START MOVP1 00H 把立即数00H送P1口 点亮所有发光二极管ACALLDELAY 调用延时子程序MOVP1 0FFH 灭掉所有发光二极管ACALLDELAY 调用延时子程序AJMPSTART 重复闪动DELAY MOVR3 7FH 延时子程序DEL2 MOVR4 0FFHDEL1 NOPDJNZR4 DEL1DJNZR3 DEL2RETEND 汇编程序结束 信号灯的控制 程序1流程图 程序2 用开关控制发光二极管的显示方式 ORG0000HMOVP3 00010000B 使P3口锁存器的P3 4置位MOVA P3 读P3口引脚线信号ANLA 00010000B 逻辑与 操作 屏蔽掉无关位JZDDPING 判断P3 4是否接地 若是 跳转到DDPING执行MOVP1 00H 否则 P3 4接高电平 点亮所有发光二极管SJMP DDPING MOVP1 55H P3 4接地 发光二极管交叉亮灭SJMP END A 0 A 0 程序2流程图 程序3 使8个发光二极管顺序点亮 ORG0000HSTART MOVR2 08H 设置循环次数MOVA 0FEH 送显示模式字NEXT MOVP1 A 点亮连接P1 0的发光二极管ACALLDELAYRLA 左移一位 改变显示模式字DJNZR2 NEXT 循环次数减1 不为零 继续点亮下面一个二极管SJMPSTARTDELAY MOVR3 0FFH 延时子程序开始DEL2 MOVR4 0FFHDEL1 NOPDJNZR4 DEL1DJNZR3 DEL2RETEND R4 1 0 R4 1 0 R3 1 0 R3 1 0 R2 1 0 R3 1 0 程序3流程图 八路彩灯控制程序 要求 1 D1 D8八个彩灯按规定顺序依次点亮 间隔1秒 最后全亮 2 按规定顺序依次熄灭 间隔1秒 最后全灭 3 八个灯同时点亮 保持1秒 4 八个灯同时熄灭 保持0 5秒 再将第3 4步重复4遍 最后整个程序再重复N遍 参考程序 一 ORG0000HLJMPMAINORG0100HMAIN MOVR7 7LOOP MOVR6 16MOVR5 4MOVDPTR TABLMOVR4 0LOOP1 MOVA R4MOVCA A DPTRMOVP1 AINCR4LCALLDELAYLCALLDELAYDJNZR6 LOOP1LOOP2 MOVP1 0FFHLCALLDELAYLCALLDELAYMOVP1 00HLCALLDELAYDJNZR5 LOOP2DJNZR7 LOOPSJMP END 子程序的调用与返回 问题 子程序调用 返回到主程序中的正确位置 并接著执行主程序中的后续指令呢 为了解决这个问题 采用了堆栈技术 子程序SUB1 主程序MAIN RET 子程序SUB2 RET 2010 2013 2110 2113 2100 2200 2013 20 13 PC 2113 13 21 堆栈指针SP 堆栈 LCALLSUB1 LCALLSUB2 21 13 20 13 子程序设计注意事项 1 要给每个子程序起一个名字 也就是入口地址的代号 2 要能正确地传递参数 即首先要有入口条件 说明进入子程序时 它所要处理的数据放在何处 如 是放在A中还是放在某个工作寄存器中等 另外 要有出口条件 即处理的结果存放在何处 3 注意保护现场和恢复现场 在子程序使用累加器 工作寄存器等资源时 要先将其原来的内容保存起来 即保护现场 当子程序执行完毕 在返回主程序之前 要将这些内容再取出 送还到累加器 工作寄存器等原单元中 这一过程称为恢复现场 注意 1 入口参数和出口参数的位置2 现场的保护与恢复 子程序的参数传递例 计算平方和c a2 b2ORG0000H 主程序MOVSP 3FH 设置栈底MOVA 31H 取数a存放到累加器A中作为入口参数LCALLSQR 计算a2MOVR1 A 出口参数 平方值存放在A中MOVA 32H 取数b存放到累加器A中作为出口参数LCALLSQR 计算b2ADDA R1 求和MOV33H A 存放结果SJMP 子程序 SQR 功能 通过查表求出平方值y x2 入口参数 x存放在累加器A中 出口参数 求得的平方值y存放在A中 占用资源 累加器A 数据指针DPTRSQR PUSHDPH 保护现场 将主程序中DPTR的高八位放入堆栈PUSHDPL 保护现场 将主程序中DPTR的低八位放入堆栈MOVDPTR TABLE 在子程序中重新使用DPTR 表首地址 DPTRMOVCA A DPTR 查表POPDPL 恢复现场 将主程序中DPTR的低八位从堆栈中弹出POPDPH 恢复现场 将主程序中DPTR的高八位从堆栈中弹出RETTABLE DB0 1 4 9 16 25 36 49 64 81 程序名 BINBCD功能 二进制数转换为BCD码入口参数 要转换的二进制数存放在累加器A中 00H FFH 出口参数 转换后的BCD码存放在B 百位 和A 十位和个位 中BINBCD PUSHPSWMOVB 100DIVAB 除法指令 A B 商在A中 余数在B中PUSHACC 把商 百位数 暂存在堆栈中MOVA 10XCHA B 余数交换到A中 B 10DIVAB A B 商 十位 在A中 余数在B 个位 中SWAPA 十位数移到高半字节ADDA B 十位数和个位数组合在一起POPB 百位数存放到B中POPPSWRET 254 100 02 5454 10 05 04 程序名 FIND 功能 片内RAM中数据检索入口参数 R0指向数据块首地址 R1中为数据块长度 关键字存于累加器A中出口参数 若找到关键字 把关键字在数据块中的序号存放到A中 若找不到关键字 A中存放序号00H占用资源 R0 R1 R2 A PSWFIND PUSHPSWPUSHACCMOVR2 00HLOOP POPACCMOVB AXRLA R0 关键字与数据块中数据进行异或操作INCR0 指向下一个数INCR2 R2中的序号加1JZLOOP1 找到PUSHBDJNZR1 LOOPMOVR2 00H 找不到 R2中存放00LOOP1 MOVA R2POPPSWRET 程序名 MAX功能 查找内部RAM中无符号数据块的最大值入口参数 R1指向数据块的首地址 数据块长度存放在工作寄存器R2中出口参数 最大值存放在累加器A中占用资源 R1 R2 A PSWMAX PUSHPSWCLRA 清A作为初始最大值LP CLRC 清进位位SUBBA R1 最大值减去数据块中的数JNCNEXT 小于最大值 继续MOVA R1 大于最大值 则用此值作为最大值SJMPNEXT1NEXT ADDA R1 恢复原最大值NEXT1 INCR1 修改地址指针DJNZR2 LPPOPPSWRET 排序程序 程序名 BUBBLE功能 将片内RAM数据块由大到小排序入口参数 R0指向数据块首地址 R2存放数据块长度出口参数 仍存放原来位置占用资源 R0 R1 R2 R3 R5 A PSW 00H位 BUBBLLE MOVA R0MOVR1 AMOVA R2MOVR5 ABUBB1 CLR00HDECR5MOVA R1BUB1 INCR1MOVB R1CJNEA B BUB0BUB0 JNCBUB2SETB00HXCHA R1 BUB2 DECR1MOV R1 AINCR1MOVA R1DJNZR5 BUB1MOVA R0MOVR1 AMOVA R2MOVR5 AJB00H BUBB1RET 七 数据的转换 1 ASCII码与二进制数的互相转换 例 编程实现十六进制数表示的ASC1I代码转换成4位二进制数 1位十六进制数 分析 注意到下述关系 字符0 字符9 的ASCII码值为 30H 39H 它们与30H之差恰好为 00H 09H 结果均 0AH 字符A 字符F 的ASCII码值为 41H 46H 它们各自减去37H后恰好为 0AH 0FH 结果均 0AH 转换程序 程序以R1作为入口和出口 ASCHIN MOVA R1 取操作数CLRC 清进位标志位CSUBBA 30H ASCII码减去30H 实现0 9的转换MOVR1 A 暂存结果SUBBA 0AH 结果是否 9 JCLOOP 若 9则转换正确XCHA R1SUBBA 07H 若 9则减37HMOVR1 ALOOP RET 2 BCD码与二进制数的转换 例 4位BCD码整数转换成二进制整数入口参数 BCD码字节地址指针R0 位数存于R2中 出口参数 二进制数存于R3R4中 算法 A 103a3 102 a2 10a1 a0 参考程序如下 BCDA PUSHPSW 现场保护PUSHAPUSHBMOVPSW 08HMOVR3 00HMOVR2 3 BCD码D的位数MOVA R0 a0 R4MOVR4 ABCKB MOVA R3 R3R4 10MOVB 10 R4MULABMOVR4 AXCHA B MOVB 10XCHA R3

温馨提示

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

评论

0/150

提交评论