这是一个练习题:
要求:使用一片74HC595和8个独立按键,每按一次按键,对应点亮一个LED灯,松开按键灯不灭,直到下一个按键按下时切换灯亮。
电路图如下:
74HC595的底层驱动代码如下:
/*********************************************************************
*函数名称:write_74HC595(uint8 dat)
*函数功能:写1字节函数
*函数调用:write_74HC595(uint8 dat);
*参数列表:dat
*返 回 值:无
*结 果:
*备 注:
*********************************************************************/
void write_74HC595(uint8 dat)
{
uint8 i;
for(i=0;i<8;i++)
{
data_in = (dat << i) & 0x80; //从高位开始送数据
shift_clk = 0; //595第一列D触发器时钟
shift_clk = 1; //595第一列D触发器时钟
}
latch_clk = 0; //595第二列D触发器时钟
latch_clk = 1; //595第二列D触发器时钟
}
完整代码如下:
//*******************************头文件声明*******************************
#include<reg52.h>
#include<intrins.h>
typedef unsigned char uint8;
typedef unsigned int uint16;
typedef unsigned long uint32;
//***************************端口定义、数组声明****************************
sbit K1=P2^7;
sbit K2=P2^6;
sbit K3=P2^5;
sbit K4=P2^4;
sbit K5=P2^3;
sbit K6=P2^2;
sbit K7=P2^1;
sbit K8=P2^0;
sbit shift_clk = P1^7; //74HC595的第11脚:shift_clk
sbit latch_clk = P1^4; //74HC595的第12脚:latch_clk
sbit data_in = P1^6; //74HC595的第14脚:data_in
uint8 code LED[9]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0XFF}; //第一个灯到第八个灯点亮、灯全灭数组
//******************************原型函数声明*******************************
void delay(uint16 x_ms);
void write_74HC595(uint8 dat);
//*******************************main主程序********************************
void main()
{
uint8 temp=0; //按键数据缓存
P2=0xff; //P1口初始化
K1=K2=K3=K4=K5=K6=K7=K8=1; //按键初始化
while(1)
{
if(temp==0)
{
write_74HC595(LED[8]); //如果没有按键按下,所有灯灭:0XFF
}
if(K1==0)
{
delay(10); //延时10-20us按键消抖
{
if(K1==0)
while(!K1) //松手检测
temp = 1;
write_74HC595(LED[temp-1]); //K1按下时,点亮第1颗灯
}
}
if(K2==0)
{
delay(10); //延时10-20us按键消抖
{
if(K2==0)
while(!K2) //松手检测
temp = 2;
write_74HC595(LED[temp-1]); //K2按下时,点亮第2颗灯
}
}
if(K3==0)
{
delay(10); //延时10-20us按键消抖
{
if(K3==0)
while(!K3) //松手检测
temp = 3;
write_74HC595(LED[temp-1]); //K3按下时,点亮第3颗灯
}
}
if(K4==0)
{
delay(10); //延时10-20us按键消抖
{
if(K4==0)
while(!K4) //松手检测
temp = 4;
write_74HC595(LED[temp-1]); //K4按下时,点亮第4颗灯
}
}
if(K5==0)
{
delay(10); //延时10-20us按键消抖
{
if(K5==0)
while(!K5) //松手检测
temp = 5;
write_74HC595(LED[temp-1]); //K5按下时,点亮第5颗灯
}
}
if(K6==0)
{
delay(10); //延时10-20us按键消抖
{
if(K6==0)
while(!K6) //松手检测
temp = 6;
write_74HC595(LED[temp-1]); //K6按下时,点亮第6颗灯
}
}
if(K7==0)
{
delay(10); //延时10-20us按键消抖
{
if(K7==0)
while(!K7) //松手检测
temp = 7;
write_74HC595(LED[temp-1]); //K7按下时,点亮第7颗灯
}
}
if(K8==0)
{
delay(10); //延时10-20us按键消抖
{
if(K8==0)
while(!K8) //松手检测
temp = 8;
write_74HC595(LED[temp-1]); //K8按下时,点亮第8颗灯
}
}
}
}
/*********************************************************************
*函数名称:write_74HC595(uint8 dat)
*函数功能:写1字节函数
*函数调用:write_74HC595(uint8 dat);
*参数列表:dat
*返 回 值:无
*结 果:
*备 注:
*********************************************************************/
void write_74HC595(uint8 dat)
{
uint8 i;
for(i=0;i<8;i++)
{
data_in = (dat << i) & 0x80; //从高位开始送数据
shift_clk = 0; //595第一列D触发器时钟
shift_clk = 1; //595第一列D触发器时钟
}
latch_clk = 0; //595第二列D触发器时钟
latch_clk = 1; //595第二列D触发器时钟
}
/*********************************************************************
*函数名称:delay
*函数功能:延时函数
*函数调用:delay(uint16 x_ms);
*参数列表:x_ms
*返 回 值:无
*结 果:延迟时间=1* x_ms(毫秒)
*备 注:
*********************************************************************/
void delay(uint16 x_ms) //延迟 x_ms*1 毫秒
{
uint16 i,j;
for(i=x_ms;i>0;i--)
for(j=114;j>0;j--);
}
最终仿真动画效果如下: