例4—4用汇编语言编写程序,实现将数据00H~0FH写入片内RAM30H~3FH,然后将数据依次读出来,在P1.0~P1.3引脚用发光二极管显示出来,设二极管的阴极与P1口相连。ORG0000H;复位后PC的起始地址为0000HLJMPMAIN;跳转到用户程序真正的起始地址0030HORG0030HMAIN:MOVR0,#10H;准备传送16个数据,设置循环次数为16MOVR1,#30H;使传送的数据指针R1指向首地址30HMOVA,#00HLOOP;MOV@R1,A;传送16个数据INCR1INCADJNZR0,LOOPNEXT:MOVR0,#10H;准备显示16个数据,设置循环次数为16MOVR1,#30H;使显示的数据指针R1指向首地址30HLOOP1:MOVA,@R1;显示16个数据LCALLDISPLAY;调用显示子程序INCR1DJNZR0,LOOP1LJMP$;原地循环;显示子程序DISPLAY:MOVDPTR,#TABLE;表格首址赋值给DPTRMOVCA,@A+DPTR;查表MOVP1,A;显示数据LCALLDELY1S;调用软件延时子程序RET;延时子程序DELY1S:MOVR5,#10H;循环10D2:MOVR6,#200H;循环200D1:MOVR7,#248DJNZR7,$DJNZR6,D1DJNZR5,D2RETTABLE:DB0FFH,0FEH,0FDH,0FCH,0FBH;用发光二极管显示数字0~4DB0FAH,0F9H,0F8H,0F7H,0F6H;用发光二极管显示数字5~9DB0F5H,0F4H,0F3H,0F2H,0F1H,0F0H;用发光二极管显示数字A~FEND例4-9将片内RAM60H开始的16个单元赋值00到16,再讲片内RAM60H开始的16个单元传送到片外RAM1000H开始单元。ORG0000HLJMPMAINORG0060HMAIN:MOVR0,#10HMOVR1,#60HMOVA,#00HLOOP;MOV@R1,AINCR1INCADJNZR0,LOOP1MOVR0,#10HMOVR1,#60HMOVDPTR,#1000HLOOP1:MOVA,@R1MOVX@DPTR,AINCAINCDPTRDJNZR0,DPTRSJMP$#includereg52.h#defineucharunsignedcharuchardatatext1[16]_at_0x60;ucharxdatatext2[16]_at_0x1000;voidmain(void){uchari;for(i=0;i16;i++)text1[i]=i;for(i=0;i16;i++)text2[i]=text1[i];while(1);}4-25对ATC51单片机的片外数据存储器进行读写,首先将数据00H~0FH写入片外数据存储器的3000H~300FH,然后将数据一次读出来,存储到片内60H~6FH.#includereg52.hvoidmain{unsignedintaddr;charaddr1,I;addr=0x3000,addr1=0x60;for(i=0;i16;i++){*((charxdata*)addr++)=i;}Addr=0x3000;For(i=0;i=16;i++){*((charidata*)addr1++)=*((charidata*)addr++);}while(1);}例4-17当开关S闭合时上面4个发光二极管先亮,下面4个后亮,当开关S打开时仅下面4个发光二极管亮。#includereg52.hSbitk=P3^4;Voidmain(){while(1){if(k==0){P1=0xf0;}P1=ox0f;}}例4-19假设从键盘输入数据x,请编写一程序,判断x大于0、等于0、还是小于0,并输出如下判断结果:1x0Y=0x=0-1x0#includestdio.h{charx,y;scanf(“%d”,&x)if(x0)y=1;elseif(x==0)y=0;elsey=-1;printf(“x=%d/n”,x,y);while(1)}6-4要求单片机主程序控制P2口所接的8段共阴极数码管个依次点亮。。。。。。。。数码管开始亮灭闪烁8.各段一次循环点亮。#includereg51.h#includeintrins.h#defineuintunsignedint#defineucharunsignedcharucharI,aa;voiddelay(uintz);viodmain(){EA=1;EX=1;IT=1;aa=1;P3=0xff;while(1){P2=aa;Delay(1000)Aa=_crol_(aa,1);}}voiddelay(unitz){unitx,y;For(x=z;x0;x--)For(y=110;y0;y--);}voidexter0()interrupt0{For(i=8;i0;i--){P2=0x7f;Delay(500);P2=0x00;Delay(500);}}例7-5已知晶振频率fosc=12MHz,编写在P2.0引脚上产生100ms的方波程序。晶振频率fosc=12MHz,Tcy=12/fosc=1us,选择定时计数器T1的方式1.确定计算初值(2^n-x)=(2^16-X)×1us=50usX=65536-50000=15536=3CB0H即TH1=3CH,TL1=B0HTMOD初始化GATE(TMOD.7)=0,C/T(TMOD.6)=0,M1(TMOD.5)=0,M0(TMOD.4)=1,定时器/计数器0没有使用,相应的各个状态随意,均取为0,则(TMOD)=10H.#includereg51.h#defineuintunsignedintsbitfangbo=P2^0;voidmain(){TMOD=0x10;TH1=0x3C;TL1=0xB0;EA=1;ET1=1;TR1=1;while(1);}Voidtimer1()interrupt3{TH1=(65536-50000)/256;TL1=(65536-50000)%256;fangbo=~fangbo;}例8-1单片机与74HC164电路。。。。在所在74HC164的并行输出引脚接了8只发光二极管,要求利用74HC164的串入并出功能,将发光二极管依次点亮,并不断循环。ORG0000HLJMPMAINORG0023H;串行口中断入口LJMPSBR;转入串行口中断服务程序ORG2000H;主程序起始地址MAIN:MOVSCON,#00H;串行口方式0初始化MOVA,#80H;最左一位发光二极管先亮MOVIE,#90HCLRP1.0;关闭并行输出MOVSBUF,A;开始串行输出LOOP:SJMP$;等待中断SBR:SETBP1.0;启动并行输出ACALLDELAY;显示延迟一段时间CLRTI;清发送中断标志RRA;准备右边一位显示CLRP1.0;关闭并行输出MOVSBUF,A;再一次串行输出RETI;中断返回#includereg52.h#includeintrins.h#defineuintunsignedint#defineucharunsignedcharvoiddelay(uintx){uchari;while(x--){For(i=0;i110;i++);}}voidmain(){Ucharc=0x80;SCON=0x00;while(1){c=_crol_(c,1);SBUF=c;while(TI==0);TI=0;Delay(400);}}例8-2电路连接如图8-30所示,在AT89C51单片机串行口外接了一片8位并入/串出移位寄存器74HC165,P2口外接了8只发光二极管,74HC165并行输入端连接8位拨码开关,要求编写程序将拨码开关的动作用发光二极管表示出来,开关打在ON位置时二极管亮,打在OFF位置时二极管不亮。ORG0000HLJMPMAINORG0023HLJMPSBRORG0060HMAIN:MOVSCON,#10HMOVIE,#90HCLRP1.0SETBP1.0LOOP:SJMP$ORG0100HSBR:MOVA,SBUFMOVP2,ACLRRIACALLDELAYCLRP1.0SETBP1.0RETIEND