51单片机实验程序.docx

上传人:b****0 文档编号:12608552 上传时间:2023-04-20 格式:DOCX 页数:26 大小:22.58KB
下载 相关 举报
51单片机实验程序.docx_第1页
第1页 / 共26页
51单片机实验程序.docx_第2页
第2页 / 共26页
51单片机实验程序.docx_第3页
第3页 / 共26页
51单片机实验程序.docx_第4页
第4页 / 共26页
51单片机实验程序.docx_第5页
第5页 / 共26页
点击查看更多>>
下载资源
资源描述

51单片机实验程序.docx

《51单片机实验程序.docx》由会员分享,可在线阅读,更多相关《51单片机实验程序.docx(26页珍藏版)》请在冰豆网上搜索。

51单片机实验程序.docx

51单片机实验程序

用查表方式编写y=x13+x23+x33。

(x为0~9的整数)

#include

voidmain()

{

intcodea[10]={0,1,8,27,64,125,216,343,512,729};//将0~9对应的每位数字的三次方的值存入code中,code为程序存储器,当所存的值在0~255或-128~+127之间的话就用char,而现在的值明显超过这个范围,用int较合适。

int的范围是0~65535或-32768~32767。

inty,x1,x2,x3;//此处定义根据习惯,也可写成charx1,x2,x3但是变量y一定要用int来定义。

x1=2;

x2=4;

x3=9;//x1,x2,x3三个的值是自定的,只要是0~9当中的数值皆可,也可重复。

y=a[x1]+a[x2]+a[x3];

while

(1);//单片机的程序不能停,这步就相当于无限循环的指令,循环的内容为空白。

}

//结果的查询在Keilvision软件内部,在仿真界面点击右下角(一般初始位置是右下角)的watch的框架内双击“double-clickorF2toadd”文字输入y后按回车,右侧会显示其16进制数值如0x34,鼠标右键该十六进制,选择第一行的decimal,可查看对应的10进制数。

1、有10个8位二进制数据,要求对这些数据进行奇偶校验,凡是满足偶校验的数据(1的个数为偶数)都要存到内RAM50H开始的数据区中。

试编写有关程序。

#include

voidmain()

{

inta[10]={0,1,5,20,24,54,64,88,101,105};//将所要处理的值存入RAM中,这些可以根据个人随意设定,但建议不要超过0~255的范围。

chari;//定义一个变量

char*q=0x50;//定义一个指针*q指向内部0x50这个地址。

for(i=9;i>=0;i--)//9~0循环,共十次,也可以用for(i=0;i<10;i++)

{

ACC=a[i];//将a[i]的值赋给累加器ACC

if(P==0)//PSW0位上的奇偶校验位,如果累加器ACC内数值1的个数为偶数那么P为0,若为奇数,P为1。

这里的P是大写的。

{

*q=a[i];

q++;//每赋一个值,指针挪一个位置指向下一个。

}

}

while

(1);//同实验一,程序不能停。

}

3.有10个8位带符号二进制数,请将10个数按从小到大的顺序排列,并存到内RAM50H开始的单元中。

#include

voidmain()

{

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;i<10;i++)

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<10;i++)//将已经排好序的数组存入*q指向的地址。

{

*q=a[i];

q++;

}

while

(1);

}

1、基本部分:

(1)P1口做输出口,接八只发光二极管,编写程序,使发光二极管循环点亮。

#include

voiddelay(unsignedcharx)//定义延迟函数,用于后面LED灯亮的持续时间。

{

unsignedchari,j,k;

do

{

for(i=10;i>0;i--)

for(j=100;j>0;j--)

for(k=249;k>0;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,才能正确读入值。

#include

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;//前两个引脚置一是为了让其能获取输入信号,后两个引脚是赋初值,方便后面取反工作。

while

(1)

{

if(!

p1_0)//判断P1.0的引脚是否有变化。

{

p1_2=!

p1_2;//如果P1.0引脚变化,P1.2引脚也跟随变化。

}

if(!

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;i>0;i--)

for(j=100;j>0;j--)

for(k=249;k>0;k--);

}while(--x);

}

main()

{

while

(1)//无限循环里面的内容

{

P1=0XFE;//右移完毕后赋初值,为左移做准备

delay

(1);

while

(1)

{

P1=P1<<1;//如果左移右移是单个灯移动的话,那么这句改为LED=LED<<1|1;就可以了。

delay

(1);

if(P1==0x00)//判断左移是否完毕,完毕break跳出此次的while

break;

}

P1=0x7f;//左移完毕后给P1赋初值,准备右移

delay

(1);

while

(1)

{

P1=P1>>1;//如果左移右移是单个灯移动的话,那么这句改为LED=LED>>1|0x80;就可以了。

delay

(1);

if(P1==0x00)//判断右移是否完毕,完毕后break跳出

break;

}

}

}

(2)利用P1口控制发光二极管LED灯按照下面方式工作:

a)从左到右奇数LED灯依次点亮;

b)从右到左偶数LED灯依次点亮;

c)按照以上步骤重复运行,其中要求灯亮的时间为500ms。

#include//此程序也可以用<<和>>来实现,具体细节可以来问我

#include//当程序中有涉及到_crol_或者_nop_等库函数时,必须添加此头文件。

voiddelay(unsignedcharx)

{

unsignedchari,j,k;

do

{

for(i=10;i>0;i--)

for(j=100;j>0;j--)

for(k=249;k>0;k--);

}while(--x);

}

main()

{

while

(1)//无限循环括号里的内容

{

P1=0xfe;//第一个灯亮,

while

(1)

{

delay

(1);

P1=_crol_(P1,2);//P1左移两个位置

if(P1==0xfe)//判断左移结束

break;

}

P1=0X7f;

while

(1)

{

delay

(1);

P1=_cror_(P1,2);//P1右移两个位置

if(P1==0x7f)//判断右移结束

break;

}

}

}

 

#include

voiddelay(unsignedcharx)//延时函数500ms

{

unsignedchari,j,k;

do

{

for(i=10;i>0;i--)

for(j=100;j>0;j--)

for(k=249;k>0;k--);

}while(--x);

}

main()

{

while

(1)//无限循环括号里的内容

{

P1=0xfe;//赋值,为左移做准备

delay

(1);

while

(1)

{

P1=(P1<<1)|0x01;//P1左移一个位置,补位补的是1。

此处不明白可以找我。

P1=P1<<1;//P1左移一个位置,补位补的是0。

delay

(1);

if(P1==0xaa)//左移结束,跳出循环

break;

}

P1=0X7f;//P1赋值,为右移做准备

delay

(1);

while

(1)

{

P1=(P1>>1)|0x80;//P1右移一个位,补位补的是1,同样的,不明白来找我

P1=P1>>1;//P1右移一个位

delay

(1);

if(P1==0x55)//判断右移是否完毕,退出此次循环。

break;

}

}

}

 

本实验模拟交通信号灯控制,一般情况下正常显示,有急救车到达时,两个方向交通信号灯全红,以便让急救车通过。

设急救车通过路口时间为5秒,急救车通过后,交通恢复正常,本实验用单次脉冲申请外部中断,表示有急救车通过。

#include

unsignedcharx,y,i,j,k;//设置

unsignedchard0,d1,d2,d3;//定义四个变量用于记录中断时的现场,以便恢复现场。

voiddelay(x)//延时函数

{

do

{

for(i=10;i>0;i--)

for(j=100;j>0;j--)

for(k=249;k>0;k--);

}

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。

}

main()

{

P1=0xf6;//P1设定初始状态,两路皆为红灯,此步骤可以忽略。

delay

(1);

EA=1;//开总中断

EX0=1;//开外部中断0中断。

IT0=1;//设置外部中断0为下降沿触发有效方式。

IT0=0为低电平有效

while

(1)//下列四种灯亮的状态循环。

{

P1=0xf3;//东西绿,南北红

delay(10);

P1=0xf5;//东西黄,南北红

delay(3);

P1=0xde;//东西红,南北绿

delay(10);

P1=0xee;//东西红,南北黄

delay(3);

}

}

1、基本部分:

用CPU内部定时器中断方式计时,实现每一秒钟输出状态发生一次反转.

#include

sbitp1_0=P1^0;//要使用单个引脚应先定义

unsignedchari;

voidmain()

{

TMOD=0X01;//t0工作在定时器,工作方式1

TL0=0XB0;

TH0=0X3C;//设定定时器初值,初值的计算可查看书本P143,此处定时器定时时间为100ms

IE=0X82;//开EA总中断,开t0中断

TR0=1;//定时器工作开关开启

i=10;//设定i作为后面定时一秒的使用

while

(1);

}

t_0()interrupt1//T0定时/计数器的中断

{

i--;//进入一次中断,i的值减一

if(i==0)//当进入10次中断,即i=0的时候,定时时间为1S。

{

i=10;//重新让i=10,使得后面继续定时1S。

p1_0=~p1_0;//P1.0取反。

}

TL0=0XB0;

TH0=0X3C;//赋定时初值,定时器或计数器必要步骤,除工作方式2外。

}

 

2、扩展部分:

利用P1口控制发光二极管LED灯按照下面方式工作:

1)从左到右奇数LED灯依次点亮;

2)从右到左偶数LED灯依次点亮;

3)按照以上步骤重复运行,其中要求灯亮的时间为500ms,由定时器T1实现。

#include

#include

unsignedchari,j,k;

voidmain()

{

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=0xfe;//赋P1初值,第一个灯亮

while

(1);//等待定时工作完成

}

t_1()interrupt3//T1的中断子函数

{

i--;//进入一次,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);

}

}

}

#include

unsignedchari,j;

voidmain()

{

i=5;

j=0;

P1=0xfe;//只亮第一个灯

TMOD=0X10;//设置T1的工作方式为1,定时器工作

IE=0X88;//中断EA开,ET1开

TL1=0XB0;

TH1=0X3C;//初值设定为100ms

TR1=1;//开启工作开关

while

(1);//等待定时工作完成

}

t_1()interrupt3//T1中断子函数

{

i--;

TL1=0XB0;

TH1=0X3C;//赋初值

if(i==0)//时间为500ms

{

i=5;

j++;//利用j来判断左移或右移是否结束

if(j<4)

{

P1=P1<<1|0x01;

P1=P1<<1|0x01;//P1口左移两位,且补位是补1。

也可以用P1=P1<<2|0X03代替

}

if(j==4)//左移结束,赋P1值准备右移

{

P1=0x7f;

}

if(j>4)//右移阶段

{

P1=P1>>1|0X80;

P1=P1>>1|0X80;//P1口右移两位,且补位是补1。

也可以用P1=P1>>2|0XC0代替

}

if(j==8)//右移结束,赋P1值准备左移

{

P1=0xfe;

j=0;//最后还要将J恢复为0以便下次循环。

}

}

}

1、基本部分:

8031内部定时计数器T0,按计数器模式和方式1工作,对P3.4(T0)引脚进行计数。

将其数值按二进制数在P1口驱动LED灯上显示出来。

#include

voidmain()

{

TMOD=0X05;//T0工作方式1,计数器工作

TL0=0X00;

TH0=0Xff;//初值设置方法可以参考P143页

IE=0X82;//中断EA=1,ET0中断开启

TR0=1;//开启中断开关

while

(1)

{

P1=~TL0;//计数器的值存在TL0里面。

每加一个值,所得的值就是以八位二进制形式存在TL0里面的。

}

}

t_0()interrupt1//T0的计数器中断

{

TL0=0X00;

TH0=0Xff;

}

2、扩展部分:

利用T0作为定时器,T1作为计数器,将试验箱上的脉冲信号源接到T1引脚,测量出脉冲信号源的频率。

#include

unsignedchari,a;

voidmain()

{

a=0;

i=10;

TMOD=0X51;//设置T0为工作方式1,定时器工作。

T1为工作方式1,计数器工作

EA=1;

ET0=1;

ET1=0;//这里也可以设置为IE=0x82。

关闭了T1的中断

TL0=0XB0;

TH0=0X3C;//时间设定为100ms

TL1=0X00;

TH1=0X00;//计数器开启最大范围计数

TR0=1;

TR1=1;//皆开启开关

while

(1)//等待计数定时工作完成

{

if(TF1==1)//查询溢出标志位。

{

a++;//溢出一次a的值加1

TF1=0;//将溢出标志位清零

TH1=0x00;

TL1=0X00;//重新装上计数器初值

}

}

}

t_0()interrupt1//定时器T0的中断子程序

{

TL0=0XB0;

TH0=0X3C;//赋初值

i--;

if(i==0)

{

i=10;

P1=TL1;//将低位记录的次数赋给P1显示出来。

P2=TH1;//将高位记录的次数赋给P2显示出来,即一秒内的计数次数,即为频率。

TR0=0;

TR1=0;//频率读出后关闭T0和T1

}

}

//一般情况下,所测频率不能超过500kHz,否则此程序结果有错。

程序频率计算为:

P1和P2的读数转为十进制数字,加上(a*65536)得出频率总和。

1、基本部分:

利用74ls165读入拨盘开关的状态,利用单片机串行口将状态读入并通过P1口输出到LED,从而实现拨盘开关对LED灯的控制。

#include

sbitP1_6=P1^6;//实验箱内部已经将P1.6引脚与165的S/L引脚相连,也把P3.6与165的CLK引脚相连

voidmain()

{

SM0=0;

SM1=0;

REN=1;//串行口工作方式0,也可用SCON=0x10

EA=1;

ES=1;//开总中断和串行口中断

while

(1);

}

I_0()interrupt4//串行口中断子程序

{

P1_6=0;//让74LS165将按键的状态读入

P1_6=1;//让74LS165将读入的8位按键码用串行方式输出,从低位到高位;

P2=SBUF;//将SBUF缓冲器里的数据读给P2

RI=0;//RI要由软件置0

}

2、扩展部分:

利用74ls165读入拨盘开关的状态,利用单片机P3口将状态读入并通过P1口输出到LED,从而实现拨盘开关对LED灯的控制。

#include

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;

main()

{

while

(1)

{

p1_6=0;//数据移入165芯片

p1_6=1;//数据从165芯片输出

x=p1_7;//防止第一位丢失

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

{

p3_6=0;

p3_6=1;//内部制造一个上升沿,从而达到数据传输,一个上升沿一个数据。

x=x<<1|p1_7;//每次左移一个位,空出来的位补P1_7的值

}

P2=x;//将移位完的X赋给P2,那么P2上显示的就是按键的二进制状态

}

}

 

1、基本部分:

利用单片机串行口,实现两个实验台之间的串行通讯。

其中一个实验台作为发送方,另一侧为接收方。

利用发送方的拨盘控制接收方的LED。

甲方:

#include

voidmain()

{

SM0=0;

SM1=1;

SM2=0;//设定串行口工作方式1,单对单通信,可用SCON=0X40代替

EA=0;

ES=0;

ET1=0;//关串行口中断,关总中断,关定时/计数器T1中断

PCON=0;//设置SMOD=0,波特率不加倍

TMOD=0X20;//设置定时/计数器T1为工作方式2,定时器工作

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1