c51单片机程序实例

c51单片机程序实例,第1张

#include<reg51h>

#define uchar unsigned char

uchar tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};  //0到9

uchar num,cnt,disn;

uchar keyval,disk;

uchar led[]={1,2,3,4};

void dealdat(uchar a)

{

led[0]=0;

led[1]=0;

led[2]=0;

led[3]=0;

led[a]=disk;

}

void delay(unsigned int a)

{

unsigned int i,j;

for(i=0;i<a;i++)

for(j=0;j<1000;j++);

}

void t0isr() interrupt 1

{

TH0=(65536-5000)/256;

TL0=(65536-5000)%256;

switch(num)

{

case 0:P2=0x01;break;

case 1:P2=0x02;break;

case 2:P2=0x04;break;

case 3:P2=0x08;break;

default:break;

}

P0=~tab[led[num]];

num++;

num&=0x03;

cnt++;

if(cnt>100)

{

cnt=0;

disn++;

disn%=4;

dealdat(disn);

}

}

uchar kbscan(void)

{

unsigned char sccode,recode;

P3=0x0f;  //发0扫描,列线输入

if ((P3 & 0x0f) != 0x0f)  //有键按下

{

// delay(20);   //延时去抖动

if ((P3&0x0f)!= 0x0f)

{

sccode = 0xef;    //逐行扫描初值

while((sccode&0x01)!=0)

{

    P3=sccode;

if((P3&0x0f)!=0x0f)

{

    recode=(P3&0x0f)|0xf0;

return((~sccode)+(~recode));

 }

        else

sccode=(sccode<<1)|0x01;

}

}

}

return 0;  //无键按下,返回0

}

void getkey(void)

{

unsigned char key;

key=kbscan();

if(key==0){keyval=0xff;return;}

switch(key)

{

case 0x11:keyval=7;break;

case 0x12:keyval=4;break;

case 0x14:keyval=1;break;

case 0x18:keyval=10;break;

case 0x21:keyval=8;break;

case 0x22:keyval=5;break;

case 0x24:keyval=2;break;

case 0x28:keyval=0;break;

case 0x41:keyval=9;break;

case 0x42:keyval=6;break;

case 0x44:keyval=3;break;

case 0x48:keyval=11;break;

case 0x81:keyval=12;break;

case 0x82:keyval=13;break;

case 0x84:keyval=14;break;

case 0x88:keyval=15;break;

default:keyval=0xff;break;

}

}

main()

{

TMOD=0x11;

TH0=(65536-5000)/256;

TL0=(65536-5000)%256;

TR0=1;

ET0=1;

EA=1;

while(1)

{

getkey();

if(keyval!=0xff)disk=keyval;

delay(10);

}

}

我前几天刚在网上看到的,不知道对你有没有用》

1. 闪烁灯

1. 实验任务

如图411所示:在P10端口上接一个发光二极管L1,使L1在不停地一亮一灭,一亮一灭的时间间隔为02秒。

2. 电路原理图

图411

3. 系统板上硬件连线

把“单片机系统”区域中的P10端口用导线连接到“八路发光二极管指示模块”区域中的L1端口上。

4. 程序设计内容

(1). 延时程序的设计方法

作为单片机的指令的执行的时间是很短,数量大微秒级,因此,我们要求的闪烁时间间隔为02秒,相对于微秒来说,相差太大,所以我们在执行某一指令时,插入延时程序,来达到我们的要求,但这样的延时程序是如何设计呢?下面具体介绍其原理:

如图411所示的石英晶体为12MHz,因此,1个机器周期为1微秒

机器周期 微秒

MOV R6,#20 2个机器周期 2

D1: MOV R7,#248 2个机器周期 2 2+2×248=498 20×

DJNZ R7,$ 2个机器周期 2×248 498

DJNZ R6,D1 2个机器周期 2×20=40 10002

因此,上面的延时程序时间为10002ms。

由以上可知,当R6=10、R7=248时,延时5ms,R6=20、R7=248时,延时10ms,以此为基本的计时单位。如本实验要求02秒=200ms,10ms×R5=200ms,则R5=20,延时子程序如下:

DELAY: MOV R5,#20D1: MOV R6,#20D2: MOV R7,#248DJNZ R7,$DJNZ R6,D2DJNZ R5,D1RET

(2). 输出控制

如图1所示,当P10端口输出高电平,即P10=1时,根据发光二极管的单向导电性可知,这时发光二极管L1熄灭;当P10端口输出低电平,即P10=0时,发光二极管L1亮;我们可以使用SETB P10指令使P10端口输出高电平,使用CLR P10指令使P10端口输出低电平。

5. 程序框图

如图412所示

图412

6. 汇编源程序ORG 0START: CLR P10LCALL DELAYSETB P10LCALL DELAYLJMP STARTDELAY: MOV R5,#20 ;延时子程序,延时02秒D1: MOV R6,#20D2: MOV R7,#248DJNZ R7,$DJNZ R6,D2DJNZ R5,D1RETEND7. C语言源程序#include <AT89X51H>sbit L1=P1^0;void delay02s(void) //延时02秒子程序{unsigned char i,j,k;for(i=20;i>0;i--)for(j=20;j>0;j--)for(k=248;k>0;k--);}void main(void){while(1){L1=0;delay02s();L1=1;delay02s();}}

2. 模拟开关灯

1. 实验任务

如图421所示,监视开关K1(接在P30端口上),用发光二极管L1(接在单片机P10端口上)显示开关状态,如果开关合上,L1亮,开关打开,L1熄灭。

2. 电路原理图

图421

3. 系统板上硬件连线

(1). 把“单片机系统”区域中的P10端口用导线连接到“八路发光二极管指示模块”区域中的L1端口上;

(2). 把“单片机系统”区域中的P30端口用导线连接到“四路拨动开关”区域中的K1端口上;

4. 程序设计内容

(1). 开关状态的检测过程

单片机对开关状态的检测相对于单片机来说,是从单片机的P30端口输入信号,而输入的信号只有高电平和低电平两种,当拨开开关K1拨上去,即输入高电平,相当开关断开,当拨动开关K1拨下去,即输入低电平,相当开关闭合。单片机可以采用JB BIT,REL或者是JNB BIT,REL指令来完成对开关状态的检测即可。

(2). 输出控制

如图3所示,当P10端口输出高电平,即P10=1时,根据发光二极管的单向导电性可知,这时发光二极管L1熄灭;当P10端口输出低电平,即P10=0时,发光二极管L1亮;我们可以使用SETB P10指令使P10端口输出高电平,使用CLR P10指令使P10端口输出低电平。

5. 程序框图

图422

6. 汇编源程序 ORG 00HSTART: JB P30,LIGCLR P10SJMP STARTLIG: SETB P10SJMP STARTEND

7. C语言源程序#include <AT89X51H>sbit K1=P3^0;sbit L1=P1^0;void main(void){while(1){if(K1==0){L1=0; //灯亮}else{L1=1; //灯灭}}}

3. 多路开关状态指示

1. 实验任务

如图431所示,AT89S51单片机的P10-P13接四个发光二极管L1-L4,P14-P17接了四个开关K1-K4,编程将开关的状态反映到发光二极管上。(开关闭合,对应的灯亮,开关断开,对应的灯灭)。

2. 电路原理图

图431

3. 系统板上硬件连线

(1. 把“单片机系统”区域中的P10-P13用导线连接到“八路发光二极管指示模块”区域中的L1-L4端口上;

(2. 把“单片机系统”区域中的P14-P17用导线连接到“四路拨动开关”区域中的K1-K4端口上;

4. 程序设计内容

(1. 开关状态检测

对于开关状态检测,相对单片机来说,是输入关系,我们可轮流检测每个开关状态,根据每个开关的状态让相应的发光二极管指示,可以采用JB P1X,REL或JNB P1X,REL指令来完成;也可以一次性检测四路开关状态,然后让其指示,可以采用MOV A,P1指令一次把P1端口的状态全部读入,然后取高4位的状态来指示。

(2. 输出控制

根据开关的状态,由发光二极管L1-L4来指示,我们可以用SETB P1X和CLR P1X指令来完成,也可以采用MOV P1,#1111XXXXB方法一次指示。

5. 程序框图

读P1口数据到ACC中

ACC内容右移4次

ACC内容与F0H相或

ACC内容送入P1口

<![endif]-->

图432

6. 方法一(汇编源程序)ORG 00HSTART: MOV A,P1ANL A,#0F0HRR ARR ARR ARR AORl A,#0F0HMOV P1,ASJMP STARTEND7. 方法一(C语言源程序)#include <AT89X51H>unsigned char temp;void main(void){while(1){temp=P1>>4;temp=temp | 0xf0;P1=temp;}}8. 方法二(汇编源程序)ORG 00HSTART: JB P14,NEXT1CLR P10SJMP NEX1NEXT1: SETB P10NEX1: JB P15,NEXT2CLR P11SJMP NEX2NEXT2: SETB P11NEX2: JB P16,NEXT3CLR P12SJMP NEX3NEXT3: SETB P12NEX3: JB P17,NEXT4CLR P13SJMP NEX4NEXT4: SETB P13NEX4: SJMP STARTEND9. 方法二(C语言源程序)#include <AT89X51H>void main(void){while(1){if(P1_4==0){P1_0=0;}else{P1_0=1;}if(P1_5==0){P1_1=0;}else{P1_1=1;}if(P1_6==0){P1_2=0;}else{P1_2=1;}if(P1_7==0){P1_3=0;}else{P1_3=1;}}}

先给你,传不上 太多了

按照我的理解来说,读 *** 作:从需要的寄存器中读出需要的数据。修改 *** 作:这里可以指处理读到的数据吗?写 *** 作:把修改的数据或者其他的数据写进需要的寄存器中。举例:(1)控制两片DS18B20温度传感器,这时需要读出两片传感器的序列号,然后存入存储器中(某存储芯片),然后再从该存储器中读出来写入某指令去监测需要的那块单片机。(2)从时钟芯片DS1302中读出年月日数据,写入自己的函数中,来显示出来。

楼上的程序是我在>

两条线短路,那么如果中间没有其他元器件,接入到IO口的话,那么电平高度一致,对于单片机而言,不是很好判定的,单片机只能判断出高低,如果这个高低有所差别的话,就无法准确界定了。比如4V和45V单片机都认为是高。

CHECK:

JB P10,CK1

JB P11,CKN

CKY: ;11 OR 00 短路

SETB C

RET

CK1:

JB P11,CKY

CKN: ;10 OR 01 不短路

CLR C

RET

符号定义表

符号 含义

Rn R0~R7寄存器n=0~7

Direct 直接地址,内部数据区的地址RAM(00H~7FH)

SFR(80H~FFH) B,ACC,PSW,IP,P3,IE,P2,SCON,P1,TCON,P0

@Ri 间接地址Ri=R0或R1 8051/31RAM地址(00H~7FH) 8052/32RAM地址(00H~FFH)

#data 8位常数

#data16 16位常数

Addr16 16位的目标地址

Addr11 11位的目标地址

Rel 相关地址

bit 内部数据RAM(20H~2FH),特殊功能寄存器的直接地址的位

指令介绍

指令 字节 周期 动作说明

一、算数运算指令

1.ADD A,Rn 1 1 将累加器与寄存器的内容相加,结果存回累加器

2.ADD A,direct 2 1 将累加器与直接地址的内容相加,结果存回累加器

3.ADD A,@Ri 1 1 将累加器与间接地址的内容相加,结果存回累加器

4.ADD A,#data 2 1 将累加器与常数相加,结果存回累加器

5.ADDC A,Rn 1 1 将累加器与寄存器的内容及进位C相加,结果存回累加器

6.ADDC A,direct 2 1 将累加器与直接地址的内容及进位C相加,结果存回累加器

7.ADDC A,@Ri 1 1 将累加器与间接地址的内容及进位C相加,结果存回累加器

8.ADDC A,#data 2 1 将累加器与常数及进位C相加,结果存回累加器

9.SUBB A,Rn 1 1 将累加器的值减去寄存器的值减借位C,结果存回累加器

10.SUBB A,direct 2 1 将累加器的值减直接地址的值减借位C,结果存回累加器

11.SUBB A,@Ri 1 1 将累加器的值减间接地址的值减借位C,结果存回累加器

12.SUBB A,#data 2 1 将累加器的值减常数值减借位C,结果存回累加器

13.INC A 1 1 将累加器的值加1

14.INC Rn 1 1 将寄存器的值加l

15.INC direct 2 1 将直接地址的内容加1

16.INC @Ri 1 1 将间接地址的内容加1

17.INC DPTR 1 1 数据指针寄存器值加1

说明:将16位的DPTR加1,当DPTR的低字节(DPL)从FFH溢出至00H时,会使高字节(DPH)加1,不影响任何标志位

18.DEC A 1 1 将累加器的值减1

19.DEC Rn 1 1 将寄存器的值减1

20.DEC direct 2 1 将直接地址的内容减1

21.DEC @Ri 1 1 将间接地址的内容减1

22.MUL AB 1 4 将累加器的值与B寄存器的值相乘,乘积的低位字节存回累加器,高位字节存回B寄存器

说明:将累加器A和寄存器B内的无符号整数相乘,产生16位的积,低位字节存入A,高位字节存入B寄存器。如果积大于FFH,则溢出标志位(OV)被设定为1,而进位标志位为0

23.DIV AB 1 4 将累加器的值除以B寄存器的值,结果的商存回累加器,余数存回B寄存器

说明:无符号的除法运算,将累加器A除以B寄存器的值,商存入A,余数存入B。执行本指令后,进位位(C)及溢出位(OV)被清除为0

24.DA A 1 1 将累加器A作十进制调整,

若(A) 3-0>9或(AC)=1,则(A) 3-0←(A)3-0+6

若(A) 7-4>9或 (C)=1,则(A) 7-4←(A)7-4+6

二、逻辑运算指令

25.ANL A,Rn 1 1 将累加器的值与寄存器的值做AND的逻辑判断,结果存回累加器

26.ANL A,direct 2 1 将累加器的值与直接地址的内容做AND的逻辑判断,结果存回累加器

27.ANL A,@Ri 1 1 将累加器的值与间接地址的内容做AND的逻辑判断,结果存回累加器

28.ANL A,#data 2 1 将累加器的值与常数做AND的逻辑判断,结果存回累加器

29.ANL direct,A 2 1 将直接地址的内容与累加器的值做AND的逻辑判断,结果存回该直接地址

30.ANL direct,#data 3 2 将直接地址的内容与常数值做AND的逻辑判断,结果存回该直接地址

31.ORL A,Rn 1 1 将累加器的值与寄存器的值做OR的逻辑判断,结果存回累加器

32.ORL A,direct 2 1 将累加器的值与直接地址的内容做OR的逻辑判断,结果存回累加器

33.ORL A,@Ri 1 1 将累加器的值与间接地址的内容做OR的逻辑判断,结果存回累加器

34.ORL A,#data 2 1 将累加器的值与常数做OR的逻辑判断,结果存回累加器

35.ORL direct,A 2 1 将直接地址的内容与累加器的值做OR的逻辑判断,结果存回该直接地址

36.ORL direct,#data 3 2 将直接地址的内容与常数值做OR的逻辑判断,结果存回该直接地址

37.XRL A,Rn 1 1 将累加器的值与寄存器的值做XOR的逻辑判断,结果存回累加器

38.XRL A,direct 2 1 将累加器的值与直接地址的内容做XOR的逻辑判断,结果存回累加器

39.XRL A,@Ri 1 1 将累加器的值与间接地扯的内容做XOR的逻辑判断,结果存回累加器

40.XRL A,#data 2 1 将累加器的值与常数作XOR的逻辑判断,结果存回累加器

41.XRL direct,A 2 1 将直接地址的内容与累加器的值做XOR的逻辑判断,结果存回该直接地址

42.XRL direct,#data 3 2 将直接地址的内容与常数的值做XOR的逻辑判断,结果存回该直接地址

43.CLR A 1 1 清除累加器的值为0

44.CPL A 1 1 将累加器的值反相

45.RL A 1 1 将累加器的值左移一位

46.RLC A 1 1 将累加器含进位C左移一位

47.RR A 1 1 将累加器的值右移一位

48.RRC A 1 1 将累加器含进位C右移一位

49.SWAP A 1 1 将累加器的高4位与低4位的内容交换。(A)3-0←(A)7-4

数据转移指令

50.MOV A,Rn 1 1 将寄存器的内容载入累加器

51.MOV A,direct 2 1 将直接地址的内容载入累加器

52.MOV A,@Ri 1 1 将间接地址的内容载入累加器

53.MOV A,#data 2 1 将常数载入累加器

54.MOV Rn,A 1 1 将累加器的内容载入寄存器

55.MOV Rn,direct 2 2 将直接地址的内容载入寄存器

56.MOV Rn,gdata 2 1 将常数载入寄存器

57.MOV direct,A 2 1 将累加器的内容存入直接地址

58.MOV direct,Rn 2 2 将寄存器的内容存入直接地址

59.MOV direct1, direct2 3 2 将直接地址2的内容存入直接地址1

60.MOV direct,@Ri 2 2 将间接地址的内容存入直接地址

61.MOV direct,#data 3 2 将常数存入直接地址

62.MOV @Ri,A 1 1 将累加器的内容存入某间接地址

63.MOV @Ri,direct 2 2 将直接地址的内容存入某间接地址

64.MOV @Ri,#data 2 1 将常数存入某间接地址

65.MOV DPTR,#data16 3 2 将16位的常数存入数据指针寄存器

66.MOVC A,@A+DPTR 1 2 (A) ←((A)+(DPTR))

累加器的值再加数据指针寄存器的值为其所指定地址,将该地址的内容读入累加器

67.MOVC A,@A+PC 1 2 (PC)←(PC)+1;(A)←((A)+(PC))累加器的值加程序计数器的值作为其所指定地址,将该地址的内容读入累加器

68.MOVX A,@Ri 1 2 将间接地址所指定外部存储器的内容读入累加器(8位地址)

69.MOVX A,@DPTR 1 2 将数据指针所指定外部存储器的内容读入累加器(16位地址)

70.MOVX @Ri,A 1 2 将累加器的内容写入间接地址所指定的外部存储器(8位地址)

71.MOVX @DPTR,A 1 2 将累加器的内容写入数据指针所指定的外部存储器(16位地址)

72.PUSH direct 2 2 将直接地址的内容压入堆栈区

73.POP direct 2 2 从堆栈d出该直接地址的内容

74.XCH A,Rn 1 1 将累加器的内容与寄存器的内容互换

75.XCH A,direct 2 1 将累加器的值与直接地址的内容互换

76.XCH A,@Ri 1 1 将累加器的值与间接地址的内容互换

77.XCHD A,@Ri 1 1 将累加器的低4位与间接地址的低4位互换

布尔代数运算

78.CLR C 1 1 清除进位C为0

79.CLR bit 2 1 清除直接地址的某位为0

80.SETB C 1 1 设定进位C为1

81.SETB bit 2 1 设定直接地址的某位为1

82.CPL C 1 1 将进位C的值反相

83.CPL bit 2 1 将直接地址的某位值反相

84.ANL C,bit 2 2 将进位C与直接地址的某位做AND的逻辑判断,结果存回进位C

85.ANL C,/bit 2 2 将进位C与直接地址的某位的反相值做AND的逻辑判断,结果存回进位C

86.ORL C,bit 2 2 将进位C与直接地址的某位做OR的逻辑判断,结果存回进位C

87.ORL C,/bit 2 2 将进位C与直接地址的某位的反相值做OR的逻辑判断,结果存回进位C

88.MOV C,bit 2 1 将直接地址的某位值存入进位C

89.MOV bit,C 2 2 将进位C的值存入直接地址的某位

90.JC rel 2 2 若进位C=1则跳至rel的相关地址

91.JNC rel 2 2 若进位C=0则跳至rel的相关地址

92.JB bit,rel 3 2 若直接地址的某位为1,则跳至rel的相关地址

93.JNB bit,rel 3 2 若直接地址的某位为0,则跳至rel的相关地址

94.JBC bit,rel 3 2 若直接地址的某位为1,则跳至rel的相关地址,并将该位值清除为0

程序跳跃

95.ACALL addr11 2 2 调用2K程序存储器范围内的子程序

96.LCALL addr16 3 2 调用64K程序存储器范围内的子程序

97.RET 1 2 从子程序返回

98.RETI 1 2 从中断子程序返回

99.AJMP addr11 2 2 绝对跳跃(2K内)

100.LJMP addr16 3 2 长跳跃(64K内)

101.SJMP rel 2 2 短跳跃(2K内)-128~+127字节

102.JMP @A+DPTR 1 2 跳至累加器的内容加数据指针所指的相关地址

103.JZ rel 2 2 累加器的内容为0,则跳至rel所指相关地址

104.JNZ rel 2 2 累加器的内容不为0,则跳至rel所指相关地址

105.CJNE A,direct,rel 3 2 将累加器的内容与直接地址的内容比较,不相等则跳至rel所指的相关地址

106.CJNE A,#data,rel 3 2 将累加器的内容与常数比较,若不相等则跳至rel所指的相关地址

107.CJNE @Rn,#data,rel 3 2 将寄存器的内容与常数比较,若不相等则跳至rel所指的相关地址

108.CJNE @Ri,#data,rel 3 2 将间接地址的内容与常数比较,若不相等则跳至rel所指的相关地址

109.DJNZ Rn,rel 2 2 将寄存器的内容减1,不等于0则跳至rel所指的相关地址

110.DJNZ direct,rel 3 2 将直接地址的内容减1,不等于0则跳至rel所指的相关地址

111.NOP 1 1 无动作

以上就是关于c51单片机程序实例全部的内容,包括:c51单片机程序实例、求 单片机简单的C语言程序例子(越多越好)、简述51单片机中的读-修改–写 *** 作,并举例说明。等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9320866.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-27
下一篇 2023-04-27

发表评论

登录后才能评论

评论列表(0条)

保存