74HC165级联篇(四)
前面的文章已详细讲述了74HC165级联的原理和工作过程,下面以两片74HC165级联来检测16个轻触按键的状态为例,当按键被按下时点亮对应的LED。
直接贴出代码,相应的语句已做好注释,结合起前面的文章,相信也很容易理解。
/*** 74hc165.h ***/
#ifndef _74HC165_H
#define _74HC165_H
#include "allhead.h"
sbit HC165_PL = P2^5; //PL 并行数据输入使能,低电平有效
sbit HC165_CLK = P2^7;//CP 时钟,上升沿触发
sbit HC165_OUT = P2^4; //Q7 串行数据输出
sbit HC165_CE = P2^6;//CE 时钟使能,低电平有效
void _74hc165_init(void);
void _74hc165_read_2byte(uchar date[2]);
#endif
/*** 74hc165.c ***/
#include "74hc165.h"
//初始化74hc165
void _74hc165_init(void)
{
HC165_CE = 0; //初始化使能时钟,后面就不需再使能
HC165_PL = 1; //PL拉高,不读取按键状态
HC165_CLK = 1; //时钟拉高,便于产生上升沿
}
//读取两个74HC165级联
void _74hc165_read_2byte(uchar date[2])
{
uchar i;
uint temp = 0;
HC165_PL = 0; //PL拉低,读取按键状态
HC165_PL = 1; //PL拉高,停止按键读取
if(HC165_OUT == 1) //等于1即并行输入D7引脚的按键被按下
temp |= 0x01; //最低位置1表示按键被按下,反之则没按键被按下
for(i = 0; i < 15; i ++) //因为最高位不用移位即可读取,故循环(16-1)次,依次把次高位移到最高位,第一级74HC165优先读取
{
temp = temp << 1;
HC165_CLK = 0; //HC165_CLK = 0 ——> HC165_CLK = 1 产生上升沿,次高位D(n-1)移到高位D(n)
_nop_();
_nop_();
HC165_CLK = 1;
if(HC165_OUT == 1)
temp |= 0x01;
}
//将16位数据分离为两个8位数据
date[0] = (uchar)(temp & 0x00ff);//第二级74HC165的数据
date[1] = (uchar)((temp >> 8) & 0x00ff);//第一级74HC165的数据
}
/*** main.c ***/
#include "allhead.h"
#include "74hc165.h"
#include "74hc595.h"
#include "delay.h"
sbit LED = P1^0;
uchar keyadata = 0;
uchar keystate[1] = {0};
uchar key2state[2]={0,0};
void main(void)
{
_74hc165_init();//74HC165初始化
_74hc595_init();//74HC595初始化
while(1)
{
LED =0;
_74hc165_read_2byte(key2state);//读取两级74HC165的数据,即16个按键的状态
_74hc595_send_mult_byte(key2state,2);//将读取回来的按键状态发送给74HC595点亮LED
}
}
proteus仿真结果如下图:
proteus仿真文件下载:
下载地址:https://pan.baidu.com/s/1FrhTHa5Cbt-WX39GuQ-p5Q
提取码:8rjt