点亮流水灯
- 格式:doc
- 大小:103.50 KB
- 文档页数:7
实验一P1口霓虹灯实验(4学时)一、实验目的⑴了解实验仿真系统的硬件结构,熟练使用实验仿真软件;⑵掌握MCS-51单片机P1口的基本结构和使用方法;⑶学会用C51编写含分支和循环结构的程序。
二、实验预备知识⑴P1口为准双向口,每一位都可独立地定义为输出线或输入线。
⑵本实验中延时子程序采用指令循环来实现,机器周期(12/6MHz)*指令所需机器周期数*循环次数,在系统时间允许的情况下可以采用此方法。
三、实验内容(1)在实验箱上完成:P1作为输出口,接八只发光二极管,编写程序,使发光二极管按照如下顺序点亮:开始→从左往右循环点亮→从右往左循环点亮→从左往右逐个点亮→从右往左逐个熄灭→2个发光二极管分别从中间往两边循环点亮→2个发光二极管分别从两边往中间循环点亮→全部点亮→全部熄灭→开始。
程序如下:#include<reg52.h>#include< intrins.h> 头文件,可以处理循环灯发光的问题#define uchar unsigned char 宏定义#define uint unsigned int 宏定义void delay(uint);void main(void){uint i;uchar temp,temp1,temp2;while(1){temp=0xfe; //从左往右循环点亮for(i=0;i<8;i++){P1=temp;delay(500);temp=_crol_(temp,1); _crol_(c,b)是个函数, 去处理循环移位的, C表示要移位的变量,而b就是表示要移位的的位数(就是一次移位多少位)}temp=0x7f; //从右往左循环点亮for(i=0;i<8;i++){P1=temp;delay(500);temp=_cror_(temp,1);}temp=0xFE; //从左往右逐个点亮for(i=0;i<8;i++){P1=temp;delay(500);temp<<=1;}temp=0x7F; //从右往左逐个熄灭for(i=0;i<8;i++){P1=~temp;delay(500);temp>>=1;}temp1=0xef; //从中间往两边循环点亮 temp2=0xf7;for(i=0;i<4;i++){P1=temp1&temp2;delay(500);temp1=_crol_(temp1,1);temp2=_cror_(temp2,1);}temp1=0x7f; //从两边往中间循环点亮 temp2=0xfe;for(i=0;i<4;i++){P1=temp1&temp2;delay(500);temp1=_cror_(temp1,1);temp2=_crol_(temp2,1);}temp=0x00; //全部点亮P1=temp;delay(500);temp=0xff; //全部熄灭P1=temp;delay(500);}}void delay(uint t) //延时{register uint bt;for(;t;t--)for(bt=110;bt>0;bt--);}(2)用Proteus软件参照实验电路连线并仿真运行,得出与实验箱上相同的软件仿真结果。
所用元器件:单片机AT89C51、发光二极管LED-GREEN(RED、BLUE)、排阻或电阻RESPACK-8(RES)、8位缓冲器74LS244参考仿真电路图:四、程序框图五、实验电路(只连图中粗实线)六、实验步骤P1.O~P1.7用插针连至L1~L8,运行程序后,观察发光二极管闪亮移位情况。
七、思考(1)在C51编程中用查表法实现相同的实验现象。
(利用数组编程)程序如下:#include<reg52.h>#define uchar unsigned char#define uint unsigned intvoid delay(uint);void main(void){uint i;uchar code a[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};uchar code b[]={0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x00};uchar code c[]={0xfe,0xff,0xe7,0xdb,0xbd,0x7e};uchar code d[]={0x00,0xff};while(1){for(i=0;i<8;i++) //从左往右循环点亮{P1=a[i];delay(500);}for(i=6;i>0;i--) //从右往左循环点亮{P1=a[i];delay(500);}for(i=0;i<8;i++) //从左往右逐个点亮{P1=b[i];delay(500);}for(i=6;i>0;i--) //从右往左逐个熄灭{P1=b[i];delay(500);}for(i=0;i<6;i++) //从中间往两边循环点亮{P1=c[i];delay(500);}for(i=4;i>1;i--) //从两边往中间循环点亮{P1=c[i];delay(500);}P1=d[0]; //全部点亮delay(500);P1=d[1]; //全部熄灭delay(500);}}void delay(uint t) //延时{register uint bt;for(;t;t--)for(bt=110;bt>0;bt--);}(2)尝试用单片机内部定时器控制延时以代替软件延时程序实现本实验要求。
程序如下:#include<reg52.h>#include< intrins.h>#define uchar unsigned char#define uint unsigned intuchar num;void Init_Timer0(void) //定时器初始化{TMOD=0x01;TH0=(65536-45872)/256;TL0=(65536-45872)%256;EA=1; //总中断打开ET0=1; //定时器中断打开TR0=1; //定时器开关打开}void main(void){uint i;uchar temp,temp1,temp2;while(1){temp=0xfe; //从左往右循环点亮Init_Timer0();for(i=0;i<8;i++){P1=temp;while(!(num==10));num=0;temp=_crol_(temp,1);}temp=0x7f; //从右往左循环点亮Init_Timer0();for(i=0;i<8;i++){P1=temp;while(!(num==10));num=0;temp=_cror_(temp,1);}temp=0xFE; //从左往右逐个点亮Init_Timer0();for(i=0;i<8;i++){P1=temp;while(!(num==10));num=0;temp<<=1;}temp=0x7F; //从右往左逐个熄灭Init_Timer0();for(i=0;i<8;i++){P1=~temp;while(!(num==10));num=0;temp>>=1;}temp1=0xef; //从中间往两边循环点亮 temp2=0xf7;Init_Timer0();for(i=0;i<4;i++){P1=temp1&temp2;while(!(num==10));num=0;temp1=_crol_(temp1,1);temp2=_cror_(temp2,1);}temp1=0x7f; //从两边往中间循环点亮temp2=0xfe;Init_Timer0();for(i=0;i<4;i++){P1=temp1&temp2;while(!(num==10));num=0;temp1=_cror_(temp1,1);temp2=_crol_(temp2,1);}temp=0x00; //全部点亮Init_Timer0();P1=temp;while(!(num==10));num=0;temp=0xff; //全部熄灭Init_Timer0();P1=temp;while(!(num==10));num=0;}}void Timer0_isr(void) interrupt 1 //定时器中断{TH0=(65536-45872)/256;TL0=(65536-45872)%256;num++;}。