要求
在单片机综合训练平台上实现蜂鸣器与继电器的基本控制。首先让8路LED指示灯闪烁3遍后熄灭,接着依次点亮LED指示灯,继电器吸合一会儿后断开,然后依次熄灭LED指示灯,蜂鸣器鸣叫一会儿后关闭,程序循环实现上述功能。
电路图:
ULN2003
注意里面是非门:输入0输出1。
代码
#include"reg52.h"
//首先让8路LED指示灯闪烁3遍后熄灭,接着依次点亮LED指示灯
//继电器吸合一会儿后断开
//然后依次熄灭LED指示灯
//蜂鸣器鸣叫一会儿后关闭,程序循环实现上述功能。
sbit HC138_A = P2^5;
sbit HC138_B = P2^6;
sbit HC138_C = P2^7;
void Delay(unsigned int t)
{
while(t--);
while(t--);
}
void LEDRunning()
{
unsigned char i;
HC138_C = 1;
HC138_B = 0;
HC138_A = 0; //LED锁存器打通
for(i=0;i<3;i++) //8路LED闪烁3遍后熄灭
{
P0=0x00; //LED整体点亮
Delay(60000);
Delay(60000);
P0=0xff; //LED整体熄灭
Delay(60000);
Delay(60000); //相当于一个灯的闪烁
}
for(i=1; i<=8; i++) //从1开始,依次点亮LED灯
{
P0=0xff << i; //先是全灭,再移i位点亮
Delay(60000);
Delay(60000);
}
HC138_C = 1; //继电器吸合
HC138_B = 0;
HC138_A = 1;
P0=0x10; //P04输入高电平
Delay(60000);
Delay(60000);
P0=0x00; //继电器关闭
HC138_C = 1; //LED锁存器打通
HC138_B = 0;
HC138_A = 0;
for(i=1; i<=8; i++)
{
P0=~(0xff << i); //取反,从1开始依次熄灭
Delay(60000);
Delay(60000);
}
HC138_C = 1; //继电器吸合
HC138_B = 0;
HC138_A = 1;
P0=0x40; //P06输入高电平
Delay(60000);
Delay(60000);
P0=0x00;
}
void InitSystem() //关闭蜂鸣器、继电器
{
HC138_C = 1;
HC138_B = 0;
HC138_A = 1;
P0=0x00;
}
void main()
{
while(1)
{
InitSystem();
LEDRunning();
}
}
注意:
1.一开始要求关闭蜂鸣器、继电器的过程,避免造成乱叫
2. P04输出高电平:0x10;P06输出高电平:0x40
代码优化
#include"reg52.h"
//首先让8路LED指示灯闪烁3遍后熄灭,接着依次点亮LED指示灯
//继电器吸合一会儿后断开
//然后依次熄灭LED指示灯
//蜂鸣器鸣叫一会儿后关闭,程序循环实现上述功能。
sbit HC138_A = P2^5;
sbit HC138_B = P2^6;
sbit HC138_C = P2^7;
void Delay(unsigned int t)
{
while(t--);
while(t--);
}
void InitHC138(unsigned char n) //选择锁存器
{
switch(n)
{
case 4:
P2 = (P2 & 0x1f) | 0x80;
// HC138_C = 1;
// HC138_B = 0;
// HC138_A = 0;
break;
case 5:
P2 = (P2 & 0x1f) | 0xa0;
// HC138_C = 1;
// HC138_B = 0;
// HC138_A = 1;
break;
case 6:
P2 = (P2 & 0x1f) | 0xc0;
// HC138_C = 1;
// HC138_B = 1;
// HC138_A = 0;
break;
case 7:
P2 = (P2 & 0x1f) | 0xe0;
// HC138_C = 1;
// HC138_B = 1;
// HC138_A = 1;
break;
}
}
void OutPutP0(unsigned char channel,unsigned char dat)
{
InitHC138(channel);
P0 = dat;
}
void LEDRunning()
{
unsigned char i;
// InitHC138(4); //LED锁存器打通
for(i=0;i<3;i++) //8路LED闪烁3遍后熄灭
{
OutPutP0(4,0x00); //LED整体点亮
// P0=0x00;
Delay(60000);
Delay(60000);
P0=0xff; //LED整体熄灭
Delay(60000);
Delay(60000); //相当于一个灯的闪烁
}
for(i=1; i<=8; i++) //从1开始,依次点亮LED灯
{
OutPutP0(4,(0xff << i));
// P0=0xff << i; //先是全灭,再移i位点亮
Delay(60000);
Delay(60000);
}
OutPutP0(5,0x10);
// InitHC138(5); //继电器吸合
// P0=0x10; //P04输入高电平
Delay(60000);
Delay(60000);
OutPutP0(5,0x00);
// P0=0x00; //继电器关闭
// InitHC138(4); //LED锁存器打通
for(i=1; i<=8; i++)
{
OutPutP0(4,~(0xff << i));
// P0=~(0xff << i); //取反,从1开始依次熄灭
Delay(60000);
Delay(60000);
}
OutPutP0(5,0x40);
// InitHC138(5); //蜂鸣器吸合
// P0=0x40; //P06输入高电平
Delay(60000);
Delay(60000);
P0=0x00;
}
void InitSystem() //关闭蜂鸣器、继电器
{
OutPutP0(5,0x00);
// InitHC138(5); //蜂鸣器、继电器吸合
// P0=0x00;
}
void main()
{
while(1)
{
InitSystem();
LEDRunning();
}
}
对于代码的优化,主要为2个部分:
1.对于锁存器的选择
//LED锁存器打通
HC138_C = 1;
HC138_B = 0;
HC138_A = 0;
可以利用函数,进一步优化为:
void InitHC138(unsigned char n) //选择锁存器
{
switch(n)
{
case 4:
P2 = (P2 & 0x1f) | 0x80;
// HC138_C = 1;
// HC138_B = 0;
// HC138_A = 0;
break;
case 5:
P2 = (P2 & 0x1f) | 0xa0;
// HC138_C = 1;
// HC138_B = 0;
// HC138_A = 1;
break;
case 6:
P2 = (P2 & 0x1f) | 0xc0;
// HC138_C = 1;
// HC138_B = 1;
// HC138_A = 0;
break;
case 7:
P2 = (P2 & 0x1f) | 0xe0;
// HC138_C = 1;
// HC138_B = 1;
// HC138_A = 1;
break;
}
}
2.对于P0以及P04、P06的赋值
void OutPutP0(unsigned char channel,unsigned char dat)
{
InitHC138(channel);
P0 = dat;
}
OutPutP0(5,0x40);
// InitHC138(5); //蜂鸣器吸合
// P0=0x40; //P06输入高电平
Delay(60000);
Delay(60000);
OutPutP0(5,0x00);
// P0=0x00;