普中开发板 请教大家一个74LS165的问题
时间:10-02
整理:3721RD
点击:
/*******************************************************************************
* 标题: 学习板的按钮输入 控制对应的继电器输出和LED灯 *
* 1. 通过本例程了解74HC165(并入串出) 的基本原理和使用 *
* 2. 了解掌握SPI总线接口的工作原理及一般编程方法。 *
* 3. 懂的74HC165在C语言中是如何操作 *
* *
********************************************************************************/
#include <reg52.H>
#include <intrins.h>
#define NOP() _nop_() /* 定义空指令 */
//SPI 接口
sbit CLK = P3^6; //串行时钟
sbit IN_PL = P1^6; //把数据加载到锁存器中
sbit IN_Dat = P1^7; //数据通过P1.7脚移进单片机内处理
sbit RELAY = P1^4;
sbit BEEP = P1^5;
unsigned char bdata Key;
sbit K0=Key^0; //位定义
sbit K1=Key^1; //位定义
sbit K2=Key^2; //位定义
sbit K3=Key^3; //位定义
sbit K4=Key^4;
sbit K5=Key^5;
sbit K6=Key^6;
sbit K7=Key^7;
bit M0 ,K0J; //位定义
unsigned long ReHC74165(void); //函数声名
void beep();
/********************************************************
* 主函数 *
* *
********************************************************/
main()
{
while(1)
{
unsigned long Input=ReHC74165();//调用165驱动程序
Key=Input&0xff; //将数据传给位变量
RELAY = 1;
P2 = 0xff; //清除
//实现脉冲输入 大家仔细体会
if(K0&K0J)M0=~M0;
K0J=~K0;
if(M0) {RELAY = 0; P2 = 0x7f; }//实现脉冲输入
if(K1) {beep(); P2 = 0xbf; }//K1 为1时开启蜂鸣器和2个灯
if(K2) {beep(); P2 = 0xdf; }
if(K3) {beep(); P2 = 0xef; }
if(K4) {beep(); P2 = 0xf7; }
if(K5) {beep(); P2 = 0xfb; }
if(K6) {beep(); P2 = 0xfd; }
if(K7) {beep(); P2 = 0xfe; }
}
}
/**********************************************************
* *
* 蜂鸣器 (让蜂鸣器发出动听声音) *
************************************************************/
void beep()
{
unsigned char i , j;
for (i=0;i<2;i++)
{
for (j = 0; j<255; j++) {_nop_();}
BEEP=!BEEP; //BEEP取反
}
BEEP=1; //关闭蜂鸣器
}
/*************************此部分为74HC165的驱动程序使用SPI总线连接*************************************/
/*********************************************************************************************************
** 函数名称: 74HC165
** 功能描述:
** 管脚描述:请参考相关的芯片资料(学习光盘中以配)
*********************************************************************************************************/
unsigned long ReHC74165(void)
{
unsigned char i;
unsigned int indata;
IN_PL=0;
NOP(); //短暂延时 产生一定宽度的脉冲
IN_PL=1; //将外部信号全部读入锁存器中
NOP();
indata=0; //保存数据的变量清0
for(i=0; i<8; i++)
{
indata=indata<<1; //左移一位
if(IN_Dat==1)indata=indata+1; //如果IN_Dat检测到高电平 保存数据的变量加1
CLK=0; //时钟置0
NOP();
CLK=1; //时钟置1
}
return(~indata); //将保存数据的变量取反后返回
}
IN_PL上升沿后,for循环中IN_Dat只检测到一次高电平吗?返回的indata值为多少?CLK上升沿起什么作用呀?
有时间的话,帮忙解答下,谢谢~~~~
* 标题: 学习板的按钮输入 控制对应的继电器输出和LED灯 *
* 1. 通过本例程了解74HC165(并入串出) 的基本原理和使用 *
* 2. 了解掌握SPI总线接口的工作原理及一般编程方法。 *
* 3. 懂的74HC165在C语言中是如何操作 *
* *
********************************************************************************/
#include <reg52.H>
#include <intrins.h>
#define NOP() _nop_() /* 定义空指令 */
//SPI 接口
sbit CLK = P3^6; //串行时钟
sbit IN_PL = P1^6; //把数据加载到锁存器中
sbit IN_Dat = P1^7; //数据通过P1.7脚移进单片机内处理
sbit RELAY = P1^4;
sbit BEEP = P1^5;
unsigned char bdata Key;
sbit K0=Key^0; //位定义
sbit K1=Key^1; //位定义
sbit K2=Key^2; //位定义
sbit K3=Key^3; //位定义
sbit K4=Key^4;
sbit K5=Key^5;
sbit K6=Key^6;
sbit K7=Key^7;
bit M0 ,K0J; //位定义
unsigned long ReHC74165(void); //函数声名
void beep();
/********************************************************
* 主函数 *
* *
********************************************************/
main()
{
while(1)
{
unsigned long Input=ReHC74165();//调用165驱动程序
Key=Input&0xff; //将数据传给位变量
RELAY = 1;
P2 = 0xff; //清除
//实现脉冲输入 大家仔细体会
if(K0&K0J)M0=~M0;
K0J=~K0;
if(M0) {RELAY = 0; P2 = 0x7f; }//实现脉冲输入
if(K1) {beep(); P2 = 0xbf; }//K1 为1时开启蜂鸣器和2个灯
if(K2) {beep(); P2 = 0xdf; }
if(K3) {beep(); P2 = 0xef; }
if(K4) {beep(); P2 = 0xf7; }
if(K5) {beep(); P2 = 0xfb; }
if(K6) {beep(); P2 = 0xfd; }
if(K7) {beep(); P2 = 0xfe; }
}
}
/**********************************************************
* *
* 蜂鸣器 (让蜂鸣器发出动听声音) *
************************************************************/
void beep()
{
unsigned char i , j;
for (i=0;i<2;i++)
{
for (j = 0; j<255; j++) {_nop_();}
BEEP=!BEEP; //BEEP取反
}
BEEP=1; //关闭蜂鸣器
}
/*************************此部分为74HC165的驱动程序使用SPI总线连接*************************************/
/*********************************************************************************************************
** 函数名称: 74HC165
** 功能描述:
** 管脚描述:请参考相关的芯片资料(学习光盘中以配)
*********************************************************************************************************/
unsigned long ReHC74165(void)
{
unsigned char i;
unsigned int indata;
IN_PL=0;
NOP(); //短暂延时 产生一定宽度的脉冲
IN_PL=1; //将外部信号全部读入锁存器中
NOP();
indata=0; //保存数据的变量清0
for(i=0; i<8; i++)
{
indata=indata<<1; //左移一位
if(IN_Dat==1)indata=indata+1; //如果IN_Dat检测到高电平 保存数据的变量加1
CLK=0; //时钟置0
NOP();
CLK=1; //时钟置1
}
return(~indata); //将保存数据的变量取反后返回
}
IN_PL上升沿后,for循环中IN_Dat只检测到一次高电平吗?返回的indata值为多少?CLK上升沿起什么作用呀?
有时间的话,帮忙解答下,谢谢~~~~
indata=0xfe,还是等于0呀
IN_PL只需要一个上升沿就可以锁存8为数据了,每次CLK的一次上升沿可以移出一位数据,然后8位的数据就存在indata中了
indata不是清零了吗?for循环中当i=0时,indata=0;i=1, indata=3; i=2, indata=7; i=7, indata=255;然后返回值input=0了?
或者只检测到一次IN_Dat=1;indata=1,然后返回值input=0xfe。不知道怎样理解?
if(IN_Dat==1)indata=indata+1; 一看就知道你这句话你没看明白
IN_Dat是165移出来的数据,等于1时indata才加1,
所以返回值不是0xfe,而是165的8位并行数据值
你找找165的数据手册看看就明白了
理解了,谢谢~~~
啊啊啊啊啊啊啊啊啊啊
74165不是上升沿传输数据吗,第一个循环里最后一句时钟才上升是不是不能传输,为什么数据不会少一位?很不明白,有人能帮忙解答下吗
我也在纠结这个问题
谢谢各位大侠的资料!