实验三:流水灯控制实验
姓名:王琳 专业:通信工程 学号:20114125517 成绩: 一 实验目的
1. 掌握keil51软件与protues软件联合仿真调试的方法; 2. 掌握如何用程序与查表方法实现流水效果; 3. 掌握按键去抖动原理及处理方法。
二 实验内容
1. 用protues设计一流水灯控制电路。利用P1口控制8个发光二极管L1-L8。P3.3口接一按键K1。其中74LS240为八反向三态缓冲器/线驱动器。
2.用中断方式编写程序,每按动一次K1键,演示不同的流水效果。若key表示按键次数,则对应流水效果如下: ①key=1:L1-L8全亮;
②key=2:L1-L8先全灭,然后自右向左单管点亮,如此循环; ③key=3:L1-L8先全灭,然后自右向左依次点亮,如此循环; ④key=4:L1-L8先全亮,然后自左向右依次熄灭,如此循环; ⑤key=5:L1-L8先全灭,然后整体闪烁,如此循环;
⑥key=6:L1-L8先全亮,再全灭,之后右面四个灯亮,其余灯熄灭,最后左边四个灯全亮,其余灯熄灭,依此循环。
以上移位及闪烁时间间隔均设置为0.3s。按动六次键后,再按键时,流水效果从头开始循环。
三 实验步骤
1. 用protues设计流水灯控制电路;
2. 在Keilc51中编写流水灯控制程序,编译通过后,与protues联合调试; 3. 按动k1键,观察是否达到演示效果;
4.用中断方式编写程序,功能实现后再改为查询方式,比较二者的区别。
四 实验设计及调试
1. 实验电路
C1D122pfX1U1XTAL1P0.0/AD0P0.1/AD1P0.2/AD2P0.3/AD3P0.4/AD4P0.5/AD5P0.6/AD6P0.7/AD7P2.0/A8P2.1/A9P2.2/A10P2.3/A11P2.4/A12P2.5/A13P2.6/A14P2.7/A15P3.0/RXDP3.1/TXDP3.2/INT0P3.3/INT1P3.4/T0P3.5/T1P3.6/WRP3.7/RD39383736353433322122232425262728101112131415161719CRYSTALD2U2:AP1_0P1_1P1_2P1_324681A0A1A2A3OE74LS240Y0Y1Y2Y318161412LED-YELLOWC218XTAL2D3LED-YELLOWRP1LED-YELLOWD4123456789RESPACK-8LED-YELLOWD7C320uF22pF9RSTLED-YELLOWR110kP1_0P1_1P1_2P1_3P1_4P1_5P1_6P1_7293031PSENALEEAD5U2:BP1_4P1_5P1_6P1_71113151719A0A1A2A3OE74LS240LED-YELLOWD8Y0Y1Y2Y39753D6LED-YELLOW12345678P1.0P1.1P1.2P1.3P1.4P1.5P1.6P1.7AT89C51R2220LED-YELLOW
2. 实验程序 (1)中断方式 #include
#define uint unsigned int #define uchar unsigned char
uchar code table2[ ]={0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; uchar code table3[ ]={0x00,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff}; uchar code table4[ ]={0xff,0x7f,0x3f,0x1f,0x0f,0x07,0x03,0x01,0x00}; uchar code table5[ ]={0x00,0xff};
uchar code table6[ ]={0xff,0x00,0x0f,0xf0}; uint key=0;
void delay(uint t) {
int a;
for(;t>0;t--)
for(a=110;a>0;a--); }
void INT_1() interrupt 2 {
EX1=0;
delay(20); EX1=1;
if(P3^3==0) key++;
if(key>=7) key=1; }
void key2() {
int i;
for(i=0;i<9;i++) {P1=table2[i];
delay(300); } }
void key3() {
int i;
for(i=0;i<9;i++) {P1=table3[i]; delay(300); } }
void key4() {
int i;
for(i=0;i<9;i++) {P1=table4[i]; delay(300); } }
void key5() {
int i;
for(i=0;i<2;i++) {P1=table5[i]; delay(300); } }
void key6() {
int i;
for(i=0;i<4;i++) {P1=table6[i]; delay(300); } }
void main( ) {EA=1 ;
EX1=1; IT1=1; P1=0x00; while(1)
{ switch(key)
{case 1:P1=0xff;break; case 2:key2();break; case 3:key3();break; case 4:key4();break; case 5:key5();break; case 6:key6();break; } } }
(2)查询方式 #include
#define uint unsigned int #define uchar unsigned char uchar code table2[ ]={0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; uchar code table3[ ]={0x00,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff}; uchar code table4[ ]={0xff,0x7f,0x3f,0x1f,0x0f,0x07,0x03,0x01,0x00};
uchar code table5[ ]={0x00,0xff}; uchar code table6[ ]={0xff,0x00,0x0f,0xf0}; uint key=0; sbit k=P3^3;
void delay(uint t) {
int a;
for(;t>0;t--)
for(a=110;a>0;a--); }
void key7() {
if(k==0) {
delay(20); if(k==0) {
key++; } }
if(key>=7) key=1; }
void key1() {
P1=0xff; delay(300); }
void key2() {
int i;
for(i=0;i<9;i++) {P1=table2[i]; delay(300); } }
void key3() {
int i;
for(i=0;i<9;i++) {P1=table3[i]; delay(300); } }
void key4() {
int i;
for(i=0;i<9;i++) {P1=table4[i]; delay(300); } }
void key5() {
int i;
for(i=0;i<2;i++) {P1=table5[i]; delay(300); } }
void key6() {
int i;
for(i=0;i<4;i++) {P1=table6[i]; delay(300); } }
void main( )
{ P1=0X00; while(1) { key7(); switch(key)
{case 1:key1();break; case 2:key2();break; case 3:key3();break; case 4:key4();break; case 5:key5();break; case 6:key6();break; } } }
3. 调试过程
(1)遇到的问题:点击一次按键,LED灯循环显示按键1-6所有状态;
解决方法:添加延时函数。
(2)在中端程序中按动第七次按键时,LED灯显示第六次按键状态,按动八次
按键,从头循环。
解决方法:将“if(key>=7) key=0”改为“if(key>=7) key=1” 4. 实验结果
LED灯按照实验要求进行循环显示。 5. 实验总结
查询方式响应速率明显比中断方式低,且用查询方式编写的流水灯控制程序在运行过程中可能会漏掉按键。
五 思考解答
按键如果不进行去抖动处理,会观察到什么现象? 答:若不进行按键去抖动处理,会出现按一次按键多次响应现象,这样就会漏掉按键,所以LED灯不按照实验要求进行循环。
相关推荐: