51单片机实验程序Word下载.docx
《51单片机实验程序Word下载.docx》由会员分享,可在线阅读,更多相关《51单片机实验程序Word下载.docx(22页珍藏版)》请在冰豆网上搜索。
![51单片机实验程序Word下载.docx](https://file1.bdocx.com/fileroot1/2022-12/14/9de53379-7922-41e3-b9f5-1ff5c194c0b5/9de53379-7922-41e3-b9f5-1ff5c194c0b51.gif)
//每赋一个值,指针挪一个位置指向下一个。
}
}
//同实验一,程序不能停。
3.有10个8位带符号二进制数,请将10个数按从小到大的顺序排列,并存到内RAM50H开始的单元中。
chardataa[10]={-50,-36,0,-128,1,99,127,89,-89,40};
//将所有值存入RAM中,因为有负数,所以不能用unsignedchar。
因为是char所以假设的数值不要超过-128~+127之外
unsignedchar*q=0x50;
//定义指针*q指向0x50
unsignedchari,j;
chart;
//定义三个变量,用于循环及换位。
在换位时有赋值,所以t要用char不能用unsignedchar。
for(i=0;
for(j=0;
j<
10-i;
j++)//冒泡法,具体可以参考C语言程序设计的书。
if(a[j]>
a[j+1])
{
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
for(i=0;
i++)//将已经排好序的数组存入*q指向的地址。
while
(1);
1、基本部分:
(1)P1口做输出口,接八只发光二极管,编写程序,使发光二极管循环点亮。
voiddelay(unsignedcharx)//定义延迟函数,用于后面LED灯亮的持续时间。
unsignedchari,j,k;
do
for(i=10;
0;
i--)
for(j=100;
j>
j--)
for(k=249;
k>
k--);
while(--x);
main()
P1=0xfe;
//11111110第一个灯亮
while
(1)
delay
(1);
//延时500ms
P1=P1<
<
1|1;
//P1左移一个位即11111101具体crol跟<
的区别与具体细节可联系我与你讲解
if(P1==0XFF)
P1=0XFE;
(2)P1.0、P1.1作输入口接两个拨动开关,P1.2、P1.3作输出口,接两个发光二极管,编写程序读取开关状态,将此状态,在发光二极管上显示出来。
编程时应注意P1.0、P1.1作为输入口时应先置1,才能正确读入值。
sbitp1_0=P1^0;
sbitp1_1=P1^1;
sbitp1_2=P1^2;
sbitp1_3=P1^3;
//程序不能对单个引脚进行编程,需要用sbit定义才可用。
main()
{
p1_0=1;
p1_1=1;
p1_2=1;
p1_3=1;
//前两个引脚置一是为了让其能获取输入信号,后两个引脚是赋初值,方便后面取反工作。
if(!
p1_0)//判断P1.0的引脚是否有变化。
p1_2=!
p1_2;
//如果P1.0引脚变化,P1.2引脚也跟随变化。
p1_1)//判断P1.1的引脚是否有变化。
p1_3=!
p1_3;
//如果P1.1引脚变化,P1.3引脚也跟随变化。
2、扩展部分:
(1)利用P1口控制发光二极管LED灯按照下面方式工作:
a)LED灯从左到右依次点亮;
b)LED灯从右到左依次点亮;
c)按照以上步骤重复运行,其中要求灯亮的时间为500ms。
#include<
voiddelay(unsignedcharx)
{
unsignedchari,j,k;
do
for(i=10;
for(j=100;
for(k=249;
}while(--x);
while
(1)//无限循环里面的内容
//右移完毕后赋初值,为左移做准备
delay
(1);
while
(1)
{
P1=P1<
1;
//如果左移右移是单个灯移动的话,那么这句改为LED=LED<
就可以了。
if(P1==0x00)//判断左移是否完毕,完毕break跳出此次的while
break;
P1=0x7f;
//左移完毕后给P1赋初值,准备右移
P1=P1>
>
//如果左移右移是单个灯移动的话,那么这句改为LED=LED>
1|0x80;
delay
(1);
if(P1==0x00)//判断右移是否完毕,完毕后break跳出
(2)利用P1口控制发光二极管LED灯按照下面方式工作:
a)从左到右奇数LED灯依次点亮;
b)从右到左偶数LED灯依次点亮;
//此程序也可以用<
和>
来实现,具体细节可以来问我
intrins.h>
//当程序中有涉及到_crol_或者_nop_等库函数时,必须添加此头文件。
while
(1)//无限循环括号里的内容
//第一个灯亮,
{
P1=_crol_(P1,2);
//P1左移两个位置
if(P1==0xfe)//判断左移结束
P1=0X7f;
P1=_cror_(P1,2);
//P1右移两个位置
if(P1==0x7f)//判断右移结束
voiddelay(unsignedcharx)//延时函数500ms
while
(1)//无限循环括号里的内容
//赋值,为左移做准备
{
P1=(P1<
1)|0x01;
//P1左移一个位置,补位补的是1。
此处不明白可以找我。
P1=P1<
//P1左移一个位置,补位补的是0。
if(P1==0xaa)//左移结束,跳出循环
//P1赋值,为右移做准备
P1=(P1>
1)|0x80;
//P1右移一个位,补位补的是1,同样的,不明白来找我
P1=P1>
//P1右移一个位
if(P1==0x55)//判断右移是否完毕,退出此次循环。
本实验模拟交通信号灯控制,一般情况下正常显示,有急救车到达时,两个方向交通信号灯全红,以便让急救车通过。
设急救车通过路口时间为5秒,急救车通过后,交通恢复正常,本实验用单次脉冲申请外部中断,表示有急救车通过。
unsignedcharx,y,i,j,k;
//设置
unsignedchard0,d1,d2,d3;
//定义四个变量用于记录中断时的现场,以便恢复现场。
voiddelay(x)//延时函数
for(i=10;
for(j=100;
for(k=249;
while(--x);
zd()interrupt0//定义中断函数,无需声明。
interrupt0表示外部中断0的中断函数
y=P1;
d0=x;
d1=i;
d2=j;
d3=k;
//记录中断时P1的值,延时函数的x,i,j,k也要记录。
P1=0xf6;
//P1应为东西红南北红,所以设为F6。
delay(5);
x=d0;
i=d1;
j=d2;
k=d3;
P1=y;
//现场恢复,包括延时函数中的x,i,j,k。
//P1设定初始状态,两路皆为红灯,此步骤可以忽略。
EA=1;
//开总中断
EX0=1;
//开外部中断0中断。
IT0=1;
//设置外部中断0为下降沿触发有效方式。
IT0=0为低电平有效
while
(1)//下列四种灯亮的状态循环。
P1=0xf3;
//东西绿,南北红
delay(10);
P1=0xf5;
//东西黄,南北红
delay(3);
P1=0xde;
//东西红,南北绿
P1=0xee;
//东西红,南北黄
}
用CPU内部定时器中断方式计时,实现每一秒钟输出状态发生一次反转.
sbitp1_0=P1^0;
//要使用单个引脚应先定义
unsignedchari;
TMOD=0X01;
//t0工作在定时器,工作方式1
TL0=0XB0;
TH0=0X3C;
//设定定时器初值,初值的计算可查看书本P143,此处定时器定时时间为100ms
IE=0X82;
//开EA总中断,开t0中断
TR0=1;
//定时器工作开关开启
i=10;
//设定i作为后面定时一秒的使用
t_0()interrupt1//T0定时/计数器的中断
i--;
//进入一次中断,i的值减一
if(i==0)//当进入10次中断,即i=0的时候,定时时间为1S。
//重新让i=10,使得后面继续定时1S。
p1_0=~p1_0;
//P1.0取反。
//赋定时初值,定时器或计数器必要步骤,除工作方式2外。
利用P1口控制发光二极管LED灯按照下面方式工作:
1)从左到右奇数LED灯依次点亮;
2)从右到左偶数LED灯依次点亮;
3)按照以上步骤重复运行,其中要求灯亮的时间为500ms,由定时器T1实现。
TMOD=0X10;
//设定T1工作在定时器T1,方式1。
同时也会设定T0工作在定时器T0,方式0,但是我们后面没有interrupt1的子函数,所以T0没发挥作用。
IE=0X88;
//开总中断,开T1中断
TL1=0XB0;
TH1=0X3C;
//定时器初值,时间为100ms
TR1=1;
//开定时器T1的开关
i=5;
j=0;
k=0;
//用三个变量来判断时长,循环阶段。
//赋P1初值,第一个灯亮
//等待定时工作完成
t_1()interrupt3//T1的中断子函数
//进入一次,i就减1
TL1=0xB0;
TH1=0x3C;
//每次进入中断定时器的初值就为0,所以需要重装
if(i==0)//500ms后
i=5;
//让i=5,继续定时500ms。
j++;
//j一开始为0,j加一
if(j==4)//如果j等于4,代表P1口左移了四次
j=0;
k=!
k;
//k取反,用于后面左移右移的执行
if(k==0)//P1口左移
if(P1==0xfd)//左移到头了,要右移需要把灯亮的位置变化下
P1=0xbf;
P1=_crol_(P1,2);
if(k!
=0)//P1口右移
if(P1==0xbf)//右移到头了,要右移需要把灯亮的位置变化下
P1=0xfd;
}
P1=_cror_(P1,2);
unsignedchari,j;
//只亮第一个灯
//设置T1的工作方式为1,定时器工作
//中断EA开,ET1开
//初值设定为100ms
//开启工作开关
t_1()interrupt3//T1中断子函数
//赋初值
if(i==0)//时间为500ms
//利用j来判断左移或右移是否结束
if(j<
4)
1|0x01;
//P1口左移两位,且补位是补1。
也可以用P1=P1<
2|0X03代替
if(j==4)//左移结束,赋P1值准备右移
P1=0x7f;
if(j>
4)//右移阶段
1|0X80;
//P1口右移两位,且补位是补1。
也可以用P1=P1>
2|0XC0代替
if(j==8)//右移结束,赋P1值准备左移
P1=0xfe;
j=0;
//最后还要将J恢复为0以便下次循环。
}
8031内部定时计数器T0,按计数器模式和方式1工作,对P3.4(T0)引脚进行计数。
将其数值按二进制数在P1口驱动LED灯上显示出来。
TMOD=0X05;
//T0工作方式1,计数器工作
TL0=0X00;
TH0=0Xff;
//初值设置方法可以参考P143页
//中断EA=1,ET0中断开启
//开启中断开关
P1=~TL0;
//计数器的值存在TL0里面。
每加一个值,所得的值就是以八位二进制形式存在TL0里面的。
}
t_0()interrupt1//T0的计数器中断
利用T0作为定时器,T1作为计数器,将试验箱上的脉冲信号源接到T1引脚,测量出脉冲信号源的频率。
unsignedchari,a;
a=0;
TMOD=0X51;
//设置T0为工作方式1,定时器工作。
T1为工作方式1,计数器工作
ET0=1;
ET1=0;
//这里也可以设置为IE=0x82。
关闭了T1的中断
//时间设定为100ms
TL1=0X00;
TH1=0X00;
//计数器开启最大范围计数
//皆开启开关
while
(1)//等待计数定时工作完成
if(TF1==1)//查询溢出标志位。
a++;
//溢出一次a的值加1
TF1=0;
//将溢出标志位清零
TH1=0x00;
TL1=0X00;
//重新装上计数器初值
t_0()interrupt1//定时器T0的中断子程序
//赋初值
if(i==0)
i=10;
P1=TL1;
//将低位记录的次数赋给P1显示出来。
P2=TH1;
//将高位记录的次数赋给P2显示出来,即一秒内的计数次数,即为频率。
TR0=0;
TR1=0;
//频率读出后关闭T0和T1
//一般情况下,所测频率不能超过500kHz,否则此程序结果有错。
程序频率计算为:
P1和P2的读数转为十进制数字,加上(a*65536)得出频率总和。
利用74ls165读入拨盘开关的状态,利用单片机串行口将状态读入并通过P1口输出到LED,从而实现拨盘开关对LED灯的控制。
sbitP1_6=P1^6;
//实验箱内部已经将P1.6引脚与165的S/L引脚相连,也把P3.6与165的CLK引脚相连
SM0=0;
SM1=0;
REN=1;
//串行口工作方式0,也可用SCON=0x10
ES=1;
//开总中断和串行口中断
I_0()interrupt4//串行口中断子程序
P1_6=0;
//让74LS165将按键的状态读入
P1_6=1;
//让74LS165将读入的8位按键码用串行方式输出,从低位到高位;
P2=SBUF;
//将SBUF缓冲器里的数据读给P2
RI=0;
//RI要由软件置0
利用74ls165读入拨盘开关的状态,利用单片机P3口将状态读入并通过P1口输出到LED,从而实现拨盘开关对LED灯的控制。
sbitp1_6=P1^6;
//与165的内部S/L相连
sbitp3_6=P3^6;
//与165的内部CLK相连
sbitp1_7=P1^7;
//P1.7短路帽扣上时,P1.7与165的QH相连
unsignedchari,x;
p1_6=0;
//数据移入165芯片
p1_6=1;
//数据从165芯片输出
x=p1_7;
//防止第一位丢失
7;
p3_6=0;
p3_6=1;
//内部制造一个上升沿,从而达到数据传输,一个上升沿一个数据。
x=x<
1|p1_7;
//每次左移一个位,空出来的位补P1_7的值
P2=x;
//将移位完的X赋给P2,那么P2上显示的就是按键的二进制状态
利用单片机串行口,实现两个实验台之间的串行通讯。
其中一个实验台作为发送方,另一侧为接收方。
利用发送方的拨盘控制接收方的LED。
甲方:
SM1=1;
SM2=0;
//设定串行口工作方式1,单对单通信,可用SCON=0X40代替
EA=0;
ES=0;
//关串行口中断,关总中断,关定时/计数器T1中断
PCON=0;
//设置SMOD=0,波特率不加倍
TMOD=0X20;
//设置定时/计数器T1为工作方式2,定时器工作
TH