
(8)MCS-51单片机的复位方式主要包括上电方式和按键方式。



SP=07H P0~P3=FFH 其余可以写成全部0,SBUF寄存器是未知数,为上次保留的值,通常也是0

程序 1000H: MOV A,#0DH 1002H: MOVC A,@A+PC 1003H: MOV R0,A
执行后的结果: (A)=02H,(R0)= 02H,PC=1004H
会把程序存储器1031H单元的内容传送累加器A中。



MOV R0,#30HMOV A,@R0MOV @R0,40HMOV 40H,AMOV R0,#60HxxxxxxxxxxMOV R6,#29H; (R6)=29HXCH A,R6; (A)=29H, (R6)=34HSWAP A; (A)=92HXCH A,R6; (A)=34H; (R6)=92HxxxxxxxxxxMOV R0,#72H; XCH A,R0; SWAP A; XCH A,R0;(R0)=27H
xxxxxxxxxxMOV R0,#50H; (R0)=50H MOV A,@R0; (A)=(50H)RL A; (A)=(50H)<<1MOV R1,A; (R1)=(50H)<<1RL A; (A)=((50H)<<2RL A; (A)=((50H)<<3ADD A,R1; (A)=((50H)<<3+ (50H)<<1MOV @R0,A; (50H)=((50H)<<3+ (50H)<<1xxxxxxxxxxMOV DPTR,#2230HMOV A,40HMOVX @DPTR,AxxxxxxxxxxORL P1,#0F8H或者ORL P1,#1111 1000BxxxxxxxxxxMOV R3,#00H; R3初始化为00HMOV A,R2 移位运算只能在A寄存器中RRC A; D0移位到CY中MOV R2,A; 把移位后的值保存到R2MOV A,R3; 此时(A)=00HRLC A; 此时CY移动到第0位到此,只要再重复7次,A寄存器的值就为R2xJB E,E1;首先判断E是不是1,是1跳转到E1标号 JB F,ZERO;表示E=0,F=1,所以同或结果为0JMP ONE;表示E=0,F=1,所以同或结果为0
E1:JB F,ONE;F如果是1,表示E=1,F=1,所以同或结果为1JMP ZERO;F是0,表示E=1,F=0,所以同或结果为0
ZERO:CLR DJMP EXITONE:SETB DEXIT:SJMP $xxxxxxxxxxMOV R0,#20H;RAM的起始地址为20HMOV R1,#31H;总共有31个单元LOOP:CJNE @R0,#0AA,S1;如果@R0 ≠ 0AA,则跳转到S1标号JMP ONES1:INC R0DJNZ R1,LOOPJMP ZERO
ONE:MOV 51H,#01HZERO:JMP EXITEXIT:MOV 51H,#00HSJMP $xxxxxxxxxxvoid main(void){ char i; char *p=0x20; char *p2=0x51; *p2=0x00; for(i=0;i<31;i++) { if(*p==0xaa) { p++; *p2=0x01; break //break 可以跳出for循环 } }}xxxxxxxxxxORG 0000HMOV R0,#10H; 循环次数为16MOV R1,#30H; RAM起始单元MOV DPTR,#3000H;片外RAM起始地址LOOP:MOV A,@R1MOVX @DPTR,AINC DPTRINC R1DJNZ R0,LOOPWAITE:SJMP WAITExxxxxxxxxxvoid main(void){ int i; unsigned char xdata *p=0x3000; /* 指针指向片外RAM3000H单元 */ unsigned char data *ps=0x30; /* 指针指向片内RAM30H单元 */ for(i=0;i<16;i++) { *p= *ps; p++; /* 指针指向下一单元,P指向3001H */ ps++; } }xxxxxxxxxxvoid main(void){ int i; unsigned char xdata *p=0x2000; for(i=0;i<4*1024;i++) { *p=0x55; p++; }}
xxxxxxxxxxMOV IE,#9FHMOV IP,#1CHxxxxxxxxxxMOV IE,#8FHMOV IP,#09H
xxxxxxxxxxsbit led0=P1^0;sbit led1=P1^1;sbit led2=P1^2;sbit led3=P1^3;void delay(int ms){ int i; unsigned char j; for(i=0;i<ms;i++) for(j=0;j<128;j++);//因为一个for循环是8个机器周期}void interrupt_init(void){ IT0=1; //下降沿触发 EX0=1; //外部中断0的开关 EA=1; //总开关Enable all PX0=0; //配置成低优先级 IT1=1; //下降沿触发 EX1=1; //外部中断1的开关 EA=1; //总开关Enable all PX1=1; //配置成高优先级}void int0_service(void) interrupt 0{ while(1) { led0=0;led1=0;led2=0;led3=0; //可以改成P1=0X00 delay(1000); led0=1;led1=1;led2=1;led3=1;//可以改成P1=0X0F delay(1000); }}
void int1_service(void) interrupt 2{ while(1) { led0=0;delay(1000);led0=1; //led0亮1s再熄灭 led1=0;delay(1000);led1=1; //led1亮1s再熄灭 led2=0;delay(1000);led2=1; //led2亮1s再熄灭 led3=0;delay(1000);led3=1; //led3亮1s再熄灭 } }
void main(void) { led0=0;led1=0;led2=0;led3=0;//可以改成P1=0X00 delay(2000); led0=1;led1=1;led2=1;led3=1;//可以改成P1=0X0F interrupt_init(); while(1); }方式2的计算公式为: 计数个数=28-计数初值 计数个数=256-156=100 每来1个负脉冲时间是1ms,所以计数100个负脉冲的时间是100ms

==注意:当管脚周期为超过100ms时候,建议选择方式1,为何呢?因为执行i++运算也会花掉时间==
小于1ms的时候。建议选择方法2,因为方式2是自动重装载计数器。
P1.0输出周期为400us,占空比为10%的方波脉冲,则高电平持续时间为:400us*10%=40us,低电平持续时间为360us。设置定时时间为40us,只需要20个数就能完成需求,故可以工作在方式0,1,2。当定时时间小于256us时候,推荐大家选择方式2,因为他是一个自动重装载定时器/计时器。定时时间40us的选择跟例4很像,当然也可以选择10us,20us。

xxxxxxxxxxsbit P1_0=P1^0;unsigned int i=0; //对中断的个数进行计数void interrupt_init(void){ ET1=1; //定时器1的中断开关 EA=1; //中断总开关 PT1=1; //定时器1配置为高优先级 }
void timer1_init(void){ TMOD=0X20; //设置为方式2,定时器模式,GATE为低电平 TL1=256-20; // 计数20个,机器周期2us,所以是定时40us TH1=TL1 //方式2 TH=TL TR1=1; // 启动定时器1 Timer1 run}//中断方式不用软件清除TF标志位// 100us 来一次中断void timer1_service(void) interrupt 3{ i++;//来一次中断,变量i加1 if(i==9)P1_0=1; if(i==10) { P1_0=0; i=0; }}void main(void){ interrupt_init(); //中断初始化 timer1_init(); //定时器1初始化 P1_0=0; while(1); //死循环,等待中断}
==注意:当管脚周期为超过100ms时候,建议选择方式1,为何呢?因为执行i++运算也会花掉时间==
小于1ms的时候。建议选择方法2,因为方式2是自动重装载计数器。

xxxxxxxxxx//方式1sbit P1_0=P1^0;unsigned int i=0; //对中断的个数进行计数void interrupt_init(void){ ET1=1; //定时器1的中断开关 EA=1; //中断总开关 PT1=1; //定时器1配置为高优先级 }
void timer1_init(void){ TMOD=0X10; //设置为方式1,定时器模式,GATE为低电平 TL1=(65536-50000)%256; // 计数50000个,机器周期1us,所以是定时50ms TH1=(65536-50000)/256; //定时50ms TR1=1; // 启动定时器1 Timer1 run}//中断方式不用软件清除TF标志位// 100us 来一次中断void timer1_service(void) interrupt 3{ i++;//来一次中断,变量i加1 if(i==140)P1_0=1; // 7s/50ms=140 if(i==150)P1_0=0; // 7.5s/50ms=150 if(i==160)P1_0=1; // 8s/50ms=160 if(i==170)P1_0=0; // 8.5s/50ms=170 if(i==180)P1_0=1; // 9s/50ms=180 if(i==190)P1_0=0; // 9.5s/50ms=190 if(i==200)i=0; // 10s/50ms=200 //方式0 1中断到来必须重新写入计数初值 TL1=(65536-50000)%256; // 计数50000个,机器周期1us,所以是定时50ms TH1=(65536-50000)/256; //定时50ms }void main(void){ interrupt_init(); //中断初始化 timer1_init(); //定时器1初始化 P1_0=0; while(1); //死循环,等待中断}xxxxxxxxxx51单片机片内ROM空间大小为8KB,范围为0000-1FFFH,题目要求扩展的外部RAM与内部ROM地址衔接,则外部RAM的起始地址为2000H,而外部RAM的空间大小为8KB,则外部RAM的地址范围为2000H-3FFFH。
xxxxxxxxxxunsigned char xdata *p=0x2000;//定义一个指针void main(void ){ for(i=0;i<100;i++) { *p|=0x0f; //低4位置1 *p=*p|0x0f; p++; } while(1);}

x
unsigned char uart_temp;sbit led=P1^0;unsigned char led_on_str[6]="led on";unsigned char led_off_str[6]="led off";void uart_init(void){ //1 串口初始化 //或者对母亲赋值,SCON=0X50 SM0=0;SM1=1; REN=1; //选择方式1,10位可变波特率,允许接收 PCON=0;//波特率不倍增 //2 定时器初始化 TMOD=0x20; //选择定时器1,方式2 TL1=0X //根据波特率计算公式 TH1=TL1 TR1=1; //3 中断初始化 ES=1; EA=1; PS=1;}void SendOneByte(unsigned char c){ SBUF = c; //发送数据 while(!TI); //等待发送完毕,TI=1 TI = 0; //必须软件清零}
void uart_service(void) interrupt 4{ unsigned char i; if(RI==1) //判断是否是接收中断 { RI=0; //必须软件清零 uart_temp=SBUF; //取出数据 if(uart_temp==0x00) { led=1; //发光二极管亮,同时发送led on 字符 for(i=0;i<6;i++) { SendOneByte(led_on_str[i]); } } if(uart_temp==0xFF) { led=0; //发光二极管亮,同时发送led on 字符 for(i=0;i<7;i++) { SendOneByte(led_off_str[i]); } } } }void main(void){ uart_init(); while(1);}

xxxxxxxxxxunsigned char uart_temp;void uart_init(void){ //1 串口初始化 //或者对母亲赋值,SCON=0X50 SM0=0;SM1=1; REN=1; //选择方式1,10位可变波特率,允许接收 PCON=0;//波特率不倍增 //2 定时器初始化 TMOD=0x20; //选择定时器1,方式2 TL1=0X //根据波特率计算公式 TH1=TL1; TR1=1; //3 中断初始化 ES=1; EA=1; PS=1;}void SendOneByte(unsigned char c){ SBUF = c; //发送数据 while(!TI); //等待发送完毕,TI=1 TI = 0; //必须软件清零}
void uart_service(void) interrupt 4{ unsigned char i; if(RI==1) //判断是否是接收中断 { RI=0; //必须软件清零 uart_temp=SBUF; //取出数据 SendOneByte(uart_temp); } }void main(void){ uart_init(); //串口初始化 while(1);}