前言
因为开发板上的外设较多所以引脚复用是不可避免的,这块开发板使用的方案是4片74HC573锁存器,加一片74HC138译码器芯片和一片双输入的与非门芯片。锁存器的输入端接了单片机的P0口,使能信号由与非门芯片控制,而与非门芯的输入一路接了138译码器,另一路接了统一接到了单片机的P42号引脚。138译码器的ABC对应单片机的引脚为P25、P26、P27。
.............直接上代码吧
锁存器使能函数
/****************************************************************
* 函 数 名 : hc138_init
* 函数功能 : 使能选中的锁存器
* 参数 : 使能n锁存器
* 返回值 : 无
******************************************************************/
void hc138_init(unsigned char n)
{
switch(n)
{
//led灯
case 4:
P2=(P2&0x1f)|0x80;
break;
//蜂鸣器,继电器
case 5:
P2=(P2&0x1f)|0xa0;
break;
//数码管的位选
case 6:
P2=(P2&0x1f)|0xc0;
break;
//数码管的段选
case 7:
P2=(P2&0x1f)|0xe0;
break;
//失能所用锁存器
default:P2=(P2&0x1f);
break;
}
}
数码管
/*****数码管数组*****/
unsigned char code smg_dm[]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,//0-9不带点
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,//0-9带点
0xff
};
/******延迟函数*****/
void delay_ms(unsigned int z)
{
unsigned int i,j;
for(i=z;i>0;i--)
for(j=800;j>0;j--);
}
/*****控制数码管位选与段选*****/
void smg_SetOne(unsigned char pos,unsigned char value)
{
P0=0x01<<(pos-1);//位选
hc138_init(6);//使能锁存器,更新输出电平
hc138_init(0);//失能锁存器,锁存输出电平
P0=smg_dm[value];//段选
hc138_init(7);
hc138_init(0);
delay_ms(2);//延时
P0=0;//熄灭数码管所有的位与段码,即消隐
hc138_init(6);
hc138_init(0);
P0=0xff;
hc138_init(7);
hc138_init(0);
}
/***** 应用 *****/
void main(void)
{
char i=0;
while(1)
{
for(i=0;i<8;i++)
smg_SetOne(i+1,i);//动态扫描显示12345678
}
}
led灯
unsigned char LED_State =0xff;//保存LED灯的状态
/**** 初始化LED,LED全灭 ******/
void LED_Init(void)
{
P0=0xff;
hc138_init(4);
hc138_init(0);
}
/****整体控制 dat:led灯的状态(对应位1灭,0亮) ******/
void LED_SetEntierty(unsigned char dat)
{
P0 = dat;
hc138_init(4);//使能led灯锁存器
hc138_init(0);//失能锁存器
LED_State = dat;
}
/****按位控制 num:要操作led灯的位,bat:led灯的状态(0灭,1亮) ******/
void LED_SetOne(unsigned char num,bit dat)
{
if(dat==0) LED_State |= 0x01<<(num-1);
else LED_State &= ~(0x01<<(num-1));
LED_SetEntierty(LED_State);
}
/**** 应用 ******/
void main(void)
{
char i=0,j=0;
LED_Init();//熄灭所有led
delay_ms(1500);
LED_SetEntierty(0Xaa);//间隔点亮led
while(1)
{
LED_SetOne(1,1); //LED1以0.2s频率闪烁
delay_ms(200);
LED_SetOne(1,0);
delay_ms(200);
}
}
蜂鸣器、继电器
sbit Relay = P0^4; //继电器,为1时打开继电器,且上电默认值为1
sbit BUZZ = P0^6; //蜂鸣器,写1时打开,且上电默认值为1
bit Relay_State=0,BUZZ_State=0;//保存蜂鸣器、蜂鸣器的状态
/**** 初始化关闭蜂鸣器、蜂鸣器 ******/
void Relay_BUZZ_Init(void)
{
Relay =0;
BUZZ = 0;
hc138_init(5);//使能锁存器
hc138_init(0);//失能锁存器
}
/**** 蜂鸣器 1打开,0关闭 ******/
void BUZZ_Set(char dat)
{
BUZZ_State = dat;//更新蜂鸣器的状态
Relay = Relay_State;//输出更新后的电平
BUZZ = BUZZ_State; //输出更新后的电平
hc138_init(5);//使能锁存器
hc138_init(0);//失能锁存器
}
/**** 继电器 1打开,0关闭 ******/
void Relay_Set(char dat)
{
Relay_State = dat;
Relay = Relay_State;//输出更新后的电平
BUZZ = BUZZ_State; //输出更新后的电平
hc138_init(5);//使能锁存器
hc138_init(0);//失能锁存器
}
/**** 应用 ******/
void main(void)
{
Relay_BUZZ_Init();//初始化关闭蜂鸣器、蜂鸣器
while(1)
{
BUZZ_Set(1);//打开蜂鸣器
delay_ms(1000);
BUZZ_Set(0);//关闭蜂鸣器
delay_ms(1000);
Relay_Set(1);//打开继电器
delay_ms(1000);
Relay_Set(0);//关闭继电器
delay_ms(1000);
}
}