#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单片机中的读-修改–写 *** 作,并举例说明。等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)