《单片机原理与接口技术》源代码.docx
- 文档编号:27478656
- 上传时间:2023-07-02
- 格式:DOCX
- 页数:60
- 大小:70.82KB
《单片机原理与接口技术》源代码.docx
《《单片机原理与接口技术》源代码.docx》由会员分享,可在线阅读,更多相关《《单片机原理与接口技术》源代码.docx(60页珍藏版)》请在冰豆网上搜索。
《单片机原理与接口技术》源代码
《单片机原理与接口技术》源代码
【例4.7】将一个字节内的两个BCD十进制数拆开并变成相应的ASCII码,存入两个RAM单元。
设两个BCD数已放在内部RAM的20H单元,变换后的ASCII码放在21H和22H单元并让高位十进制BCD数存放在21H单元。
MOVR0,#22H;R0←22H
MOV@R0,#00H;22H清零
MOVA,20H;两个BCD数送A
XCHDA,@R0;低位BCD数送至22H单元
ORL22H,#30H;完成低位转换
SWAPA;高位BCD放至低4位
ORLA,#30H;完成高位转换
MOV21H,A;存数
RET
【例4.8】16位二进制数求补程序。
设16位二进制数存放在R1、R0,求补以后的结果则存放于R3、R2。
MOVA,R0;低8位送A
CPLA;取反
ADDA,#1;加1
MOVR2,A;送回
MOVA,R1;高8位送A
XRLA,#7FH;符号位不变,其余位取反
ADDCA,#0;加进位
MOVR3,A;结果送回
RET
【例4.9】将十六进制数转换为ASCII码。
设十六进制数存放在R0寄存器的低4位,转换后的ASCII码仍送回R0寄存器。
MOVA,R0
ANLA,#0FH
MOVDPTR,#ASCTAB
MOVCA,@A+DPTR
MOVR0,A
RET
ASCTAB:
DB'0','1','2','3','4'
DB'5','6','7','8','9'
DB'A','B','C','D','E','F'
END
【例4.10】按下式的要求给Y赋值。
ORG1000H
XDATA30H
YDATA31H
MOVA,X;A←X
JNBACC.7,PLUS;若X>0,则转PLUS
MOVA,#0FFH;若X<0,则Y=-1
SJMPDONE
PLUS:
MOVA,#01H;若X>0,则Y=1
DONE:
MOVEY,A;存函数值
SJMP$
END
【例4.11】按照下式的要求给Y赋值。
ORG0000H
XDATA30H
YDATA31H
MOVA,X;A←X
MOVR0,#0FFH;先设X<0,R0=FFH
JBACC.7,DONE;若X<0,则转DONE
MOVR0,#0
JZDONE
MOVR0,#01H;若X>0,R0=1
PLUS:
MOVR0,#01H;若X>0,则Y=1
DONE:
MOVY,R0;存函数值
SJMP$
END
【例4.12】128分支程序。
根据R3的值(00H-7FH),分支到128个不同的分支入口。
MOVA,R3;取地址序号送A
RLA;A←A×2
MOVDPTR,#BRTAB;地址表首地址送DPTR
JMP@A+DPTR;转入转移表内
BRTAB:
AJMPROUT00;地址表
AJMPROUT01
┇
AJMPROUT127
END
【例4.13】编程根据R3(0~3)的值,转向相应的操作程序。
ORG0000H
MOVA,R3
MOVDPTR,#ADTAB;地址表首地址送DPTR
MOVCA,@A+DPTR;偏移地址送A
MOVDPTR,#ROUT0;首地址送DPTR
JMP@A+DPTR;转至序号对应的分支
ROUT0:
┇
SJMPDONE
ROUT1:
┇
SJMPDONE
ROUT2:
┇
SJMPDONE
ROUT3:
┇
DONE :
RET
ADTAB:
DB0,ROUT1-ROUT0,ROUT2-ROUT0,ROUT3-ROUT0
END
【例4.14】编程根据R3的值,转向相应的操作程序。
ORG0000H
MOVA,R3
RLA
MOVR1,A;存2倍序号至R1
MOVDPTR,#ADTAB
MOVCA,@A+DPTR;转移地址高8位送A
XCHA,R1;转移址高8位送R1,2倍序号送A
INCA;2倍序号加1,以便取低8位转移地址
MOVCA,@A+DPTR;取低8位转移地址
MOVDPL,A;低8位转移地址送DPL
MOVDPH,R1;高8位转移地址送DPH
CLRA;A清零
JMP@A+DPTR;转移
ROUT0:
┇
LJMPDONE
ROUT1:
┇
LJMPDONE
ROUT2:
┇
LJMPDONE
ROUT3:
┇
LJMPDONE
DONE:
┇
ADTAB:
DWROUT0,ROUT1,ROUT2,ROUT3;入口地址表
END
【例4.15】从BLOCK单元开始存放一组无符号数,一般称为一个数据块。
数据块长度放在LEN单元,编写一个求和程序,将和存入SUM单元,假设和不超过8位二进制数。
MOVA,#LEN;数据块长度送A
JZDONE;若长度为0,存结果
MOVR1,#BLOCK;数据块首址送Rl
MOVR2,A
CLRA;清累加器
LOOP:
ADDA,@R1;循环做加法
INCR1;修改地址指针
CHECK:
DJNZR2,LOOP
DONE:
MOVSUM,A;存和
END
【例4.16】一组十六进制数转换为ASCII码。
每个字节内存放两个十六进制数。
十六进制数据块首地址存于R0寄存器,存放ASCII码区域的首地址存于R1寄存器,数据块长度存于R2寄存器。
程序执行后R0和R1仍应指向原来的位置。
MOVTEMP,R0;暂存指针值
MOVTEMP+1,R1
LOOP:
MOVA,@R0;取二个十六进制数
ANLA,#0FH;保留低4位
ADDA,#19;第一次地址调整
MOVCA,@A+PC;第一次查表
MOV@R1,A;存第一次转换结果
INCR1
MOVA,@R0;重新取出被转换数
SWAPA;准备处理高4位
ANLA,#0FH
ADDA,#10;第二次地址调整
MOVCA,@A+PC;第二次查表
MOV@R1,A;存第二次转换结果
INCR1;修改指针
INCR0
DJNZR2,LOOP;R2≠0再循环
MOVR0,TEMP;恢复指针原值
MOVR1,TEMP+1
RET
ASCTAB:
DB‘123456789ABCDEF’
TEMP:
DATA20H
END
【例4.17】用程序实现C=a2+b2,假设a、b的平方均小于128,a存在内部RAM41H单元,b存在内部RAM42H 单元,C存入内部RAM33H单元。
MOVSP,#3FH;设置堆栈指针
MOVA,31H;取a
LCALLCSQR;求a的平方值
MOVR1,A;将子程序出口参数(a的平方值)送R1
MOVA,32H;取b
LCALLCSQR;求b的平方值
ADDA,R1;求和
MOV33H,A;送结果
SJMP$
ORG2400H
CSQR:
MOVDPTR,#TAB;子程序
MOVCA,@A+DPTR
RET
TAB:
DB0,1,4,9,16,25,36,49,64,81,100,121
【例4.19】多字节带符号数加法,假定被加数和加数的低位字节地址分别存放在R0和R1中,R3中存放字节数,求和并将其存放于被加数所在的单元,和的字节数仍放在R3中。
SDADD:
CLR07H;进位位清零
MOVA,R0;保存原始地址
MOVR2,A
MOVA,R3
MOVR7,A
CLRC
LP1:
MOVA,@R0;相加
ADDCA,@R1
MOV@R0,A
INCR0;修改地址指针
INCR1
DJNZR7,LP1;循环控制
JBOV,ERR;若有溢出,转到ERR处理
DECR0
MOVA,@R0
JNB0E7H,LP2;和为负,置标志位
SETB07H
LP2:
MOVA,R2
MOVR0,A;恢复原始地址
┇
ERR:
┇
END
图4.10多字节带符号数加法运算流程图
【例4.20】两个16位无符号数相乘,设R7R6存被乘数,R5R4存乘数,乘积存入以R0开始的单元(低位积先存)。
START:
MOVA,R6
MOVB,R4
MULAB;两个低8位相乘
MOV@R0,A;低位积dbL存入内存
MOVR3,B;bdH暂存R3
MOVA,R7
MOVB,R4
MULAB;第二次相乘
ADDA,R3;bdH+adL
MOVR3,A;暂存R3
MOVA,B
ADDCA,#0;adH+
MOVR2,A;暂存R2
MOVA,R6
MOVB,R5
MULAB;第三次相乘
ADDA,R3;dbH+adL+bcL
INCR0;积指针加1
MOV@R0,A;积之第15—8位存入
MOVR1,#0
MOVA,R2
ADDCA,B;adH+bcH+CY
MOVR2,A;暂存R2
JNCNEXT
INCR1;若有进位存入R1
NEXT:
MOVA,R7
MOVB,R5
MULAB;第四次相乘
ADDA,R2; adH+bcH+acL
INCR0
MOV@R0,A;积之第23—16位存入
MOVA,B
ADDCA,R1
INCR0
MOV@R0,A;积之第31—24位
RET
【例4.21】双字节二进制数转换为BCD数。
设R3R2中分别存放一个16位二进制数的高8位和低8位,将其转换为BCD数,并存入寄存器R6(万位)、R5(千位、百位)、R4(十位、个位)中。
BTOBCD:
CLRA
MOVR4,A
MOVR5,A
MOVR7,A
MOVR7,#10H
LP0:
CLRC
MOVA,R2
RLCA
MOVR2,A
MOVA,R3
RLCA
MOVR3,A
MOVA,R4
ADDCA,R4
DAA
MOVR4,A
MOVA,R5
ADDCA,R5
DAA
MOVR5,A
MOVA,R6
ADDCA,R6
DAA
MOVR6,A
DJNZR7,LP0
RET
【例4.22】要求的定时时间分别为5s、l0s和20s并设计一个1s延时子程序DELAY,则不同定时的调用情况表示如下:
MOVR0,#05H;5s延时
LOOP1:
LCALLDELAY
DJNZR0,LOOP1
MOVR0,#0AH;10s延时
LOOP2:
LCALLDELAY
DJNZR0,LOOP2
MOVR0,#14H;20s延时
LOOP3:
LCALLDELAY
DJNZR0,LOOP3
【例4.23】内部RAM20H单元开始存放8个无符号8位二进制数,找出其中的最大数。
MOVR0,#20H;数据区首地址
MOVR7,#08H;数据区长度
MOVA,@R0;读第一个数
DECR7
LOOP0:
INCR0
MOV2AH,@R0;读下一个数
CJNEA,2AH,CHK;数值比较
CHK:
JNCLOOP1;A值大转移
MOVA,@R0;大数送A
LOOP1:
DJNZR7,LOOP0;继续
MOV2BH,A;极值送2BH单元
HERE:
AJMPHERE;停止
【例4.24】假定8个数连续存放在20H为首地址的内部RAM单元中,使用冒泡法进行升序排序编程。
SORT:
MOVR0,#20H;数据存储区首单元地址
MOVR7,#07H;各次冒泡比较次数
CLRTR0;互换标志清零
LOOP:
MOVA,@R0;取前数
MOV2BH,A;存前数
INCR0
MOV2AH,@R0;取后数
CLRC
SUBBA,@R0;前数减后数
JCNEXT;前数小于后数,不互换
MOV@R0,2BH
DECR0
MOV@R0,2AH;两个数交换位置
INCR0;准备下一次比较
SETBTR0;置互换标志
NEXT:
DJNZR7,LOOP;返回,进行下一次比较
JBTR0,SORT;返回,进行下一轮冒泡
HERE:
SJMP$;排序结束
【例5.1】初识C51。
#include
#definePORTP1//宏定义,用PORT指代P1
voidDelay(intn);//函数声明
voidmain()//主函数
{
intt;//变量声明
t=300;//变量赋初值
PORT=0;//PORT初值为0
/*以下程序段实现每次将PORT的内容加1,直到PORT的值不再小于0xff为止*/
while(PORT<0xff)
{
PORT=PORT+1;
Delay(t);//函数调用
}
}
voidDelay(intn)//函数定义
{
inti,j,k;//变量声明
for(i=0;i {for(j=0;j<10;j++) { k=1; } } } 【例5.2】在C51中调用汇编语言程序。 (1)创建C51源程序ex5_2.C如下: #include #defineT0x50ff//定义符号常量T externvoiddelay(intt);//说明被调用的汇编语言函数 voidmain()//主函数 { P1=0x00;//P1端口初值为0 /*以下程序段实现每次将P1的内容加1,直到P1的值不再小于0xf3为止*/ while(PORT<0xf3) { P1=P1+1; delay(T);//调用汇编语言源程序实现延时 } } 创建汇编语言函数文件delay.a51如下: NAMEDELAY ? PR? _delay? DELAYSEGMENTCODE;根据函数名的命名规则定义程序代码段 PUBLIC_delay RSEG? PR? _delay? DELAY;定义可重定位段 _delay: MOVA,R6;延时参数通过R7R6传递 LP1: MOVR6,A LP2: DJNZR6,LP2 DJNZR7,LP1 RET END 【例5.3】在C51中直接嵌入汇编语言语句 #include voidmain()//主函数 { unsignedlongi; P1=0x00;//P1端口初值为0 /*以下程序段实现每次将P1的内容加1,直到P1的值不再小于0xff为止*/ while(P1<0xff) { P1=P1+1; for(i=0;i<0xff;i++) #pragmaasm//嵌入汇编语言语句实现延时 MOVR7,0xff;延时参数通过R7R6传递 LP1: MOVR6,0x50 LP2: DJNZR6,LP2 DJNZR7,LP1 #pragmaendasm } } 用位操作实现。 【例6.2】允许单片机串行口输入/接收中断请求,而禁止其他中断源的中断申请。 试根据该条件,用字节操作和位操作两种方法实现IE寄存器的初始化。 字节操作法: MOVIE,#90H;字节操作送控制字 位操作法: SETBEA;CPU开中断 SETBES;禁止串行口中断 CLREXl;禁止外部中断1中断 CLREX0;禁止外部中断0中断 CLRETl;允许定时器/计数器T1中断 CLRET0;允许定时器/计数器T0中断 【例6.3】设定单片机串行口1,定时器0、1,外部中断0和1,5个中断源中断优先级,要求将其中的2个定时器中断源T0和T1设置为高优先级,其他3中断源设定为低优先级。 试用两种方法实现中断系统的初始化。 (1)字节操作 MOVIP,#0AH;字节法输入控制字 (2)位操作 SETBPT0;2个定时/计算器为高优先级 SETBPTl CLRPS;串行口、2个外部中断源为低优先级中断 CLRPX0 CLRPXl 【例6.5】设单片机响应外部中断1的中断请求,并且中断级为低优先级,采用电平触发方式。 试编写符合题意的初始化程序段。 解: 据题设条件有如下主程序段: ┇ SETBEA;CPU开中断 SETBEX1;允许CPU响应外部中断源1 CLRPX1;设置外部中断源1优先级为低级 CLRIT1;设置外部中断源1外电平触发方式 ┇ 【例6.6】已知键盘通过适当的接口电路和外部中断0相连。 每次键盘提出中断申请时,要求CPU读入键盘输入的字符,并存储在片内RAM20H内存单元。 假设硬件电路设计和主程序设计已经完成;并且中断服务程序中只保护寄存器A,B的值。 请设计中断服务程序。 KEYBOARD: CLREA;CPU关中断 PUSHB;现场保护 PUSHACC; SETBEA;CPU开中断 MOVDPTR,#3000H;中断处理。 将端口地址写入DPTR MOVXA,@DPTR;读入键盘输入字符 MOV20H,A;将字符送内存单元#2001H CLREA;CPU关中断 POPACC;现场恢复 POPB SETBEA;CPU开中断 RETI;中断返回,恢复断点 【例6.7】设计利用外部中断1的信号采集系统,已知系统主程序存储于程序存储器从0100H开始的区域,外部中断1的服务程序存储在从2000H开始的区域,试设计主程序和中断服务程序。 ORG0000H LJMPstart ORG0013H LJMPintex1 ORG0100H start: MOVSP,#55H;主程序。 主要做初始化工作 ┇ SETBEA;中断服务程序。 CPU开中断 SETBEX1;允许CPU响应外部中断源1 CLRPX1;设置外部中断源1优先级为低级 SETBIT1;设置外部中断源1下降沿触发方式 ┇ ORG2000H intex1: PUSHACC …;相关中断处理过程代码 POPACC RETI;中断返回 【例6.8】利用定时/计数器的计数方式,实现对彩灯的闪烁控制。 假设单片机外部已经设计一个时钟发生电路(频率可调),要求每个时钟周期的下跳沿控制彩灯的亮和灭。 彩灯功率很小,可以直接由单片机I/O口线驱动。 请设计该控制系统的完整程序。 ORG0000H LJMPMAIN;跳到主程序 ORG000BH LJMPTIMER;跳转到中断服务程序 MAIN: MOVSP,#60H;初始化堆栈指针 MOVTMOD,#06H;设置T0为工作模式2 MOVTL0,#0FFH;给计数器设置初值 MOVTH0,#0FFH SETBTR0;启动T0,开始计数 SETBET0;允许T0中断 SETBEA;CPU开中断 IDLE: NOP;等待 AJMPIDLE TIMER: CLREA;CPU关中断 PUSHB;现场保护 PUSHACC; SETBEA;CPU开中断 CPLP1.1;P1.1取反 ┇;其他处理 CLREA;CPU关中断 POPACC;现场恢复 POPB; SETBEA;CPU开中断 RETI;中断返回,恢复断点 【例6.9】设单片机外接5个外部中断源,其优先级顺序依次为: IR0、IRl、……IR4。 利用软件查询法实现该中断系统的扩展,并满足优先级队列要求。 ORG0000H LJMPMAIN;跳到主程序 ORG0003H LJMPINTR0;跳转到外部中断源0的中断服务程序 ORG0013H LJMPINTR1;跳转到外部中断源1的中断服务程序 MAIN: MOVSP,#60H;初始化堆栈指针 CLRIT0;外部中断源0为电平触发 SETBEX0;允许外部中断源0中断申请响应 CLRIT1;外部中断源1为电平触发 SETBEX1;允许外部中断源1中断申请响应 SETBEA;CPU开中断 IDLE: NOP;等待 AJMPIDLE ;--------------------------
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单片机原理与接口技术 单片机 原理 接口 技术 源代码