找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3384|回复: 6
收起左侧

单片机IO口扩展(并转串)编程疑问

[复制链接]
ID:417740 发表于 2018-11-11 21:00 | 显示全部楼层 |阅读模式
哪位大神能帮我看看,以下程序中  下划线黑体加粗的问题  
/**************************************************************************************
*                              单片机IO扩展--74HC165实验                                                                                                  *
实现现象:下载程序后,按下独立按键可以点亮对应的led
                        K1--led1
***************************************************************************************/
#include "reg52.h"                         //此文件中定义了单片机的一些特殊功能寄存器
#include "intrins.h"
typedef unsigned int u16;          //对数据类型进行声明定义
typedef unsigned char u8;
//--定义使用的IO口--//
#define GPIO_LED P0
sbit    IN_PL   = P1^6;   
sbit    IN_Data = P1^7;    //数据通过P1.7脚移进单片机内处理
sbit    SCK    = P3^6;
/*******************************************************************************
* 函 数 名         : Read74HC165
* 函数功能: 使用165读取一个字节数据
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
u8 Read74HC165(void)
{  
  u8 i;
  u8 indata;
               
   IN_PL = 0;
   _nop_();        //短暂延时 产生一定宽度的脉冲
   IN_PL = 1;           //将外部信号全部读入锁存器中
   _nop_();

   indata=0;   //保存数据的变量清0  
   for(i=0; i<8; i++)
    {
          indata = indata<<1;           //左移一位
          SCK = 0;   //时钟置0         
      _nop_();
          indata |= IN_Data;   //为什么要有或运算,不能直接赋值吗?????
      SCK = 1;   //时钟置1         
        }

   return(indata);         
}


/*******************************************************************************
* 函 数 名       : main
* 函数功能                 : 主函数
* 输    入       : 无
* 输    出             : 无
*******************************************************************************/
void main()
{        
        u8 h165Value;

        GPIO_LED = 0;
        while(1)
        {
                h165Value = Read74HC165();
                if(h165Value != 0xFF)
                {
                        GPIO_LED = ~h165Value;
                }        
        }                        
}


回复

使用道具 举报

ID:111634 发表于 2018-11-12 08:49 | 显示全部楼层
本帖最后由 zl2168 于 2018-11-13 23:15 编辑

给你介绍几个165参考案例
实例25  74HC165串行输入8/16数据信号

Proteus仿真一下,确认有效
实例25 74HC165串行输入8-16位数据信号.rar (78.82 KB, 下载次数: 20)
回复

使用道具 举报

ID:310519 发表于 2018-11-12 09:30 | 显示全部楼层
比如,indata接收了第1位数据,值为“1” ,这时,indata值为#00000001;

然后向左移1位,为接收下一个数据做准备,这时,indata值为#00000010;

indata开始接收了第2位数据,值为“1” 。

如果直接赋值,indata值为#00000001,接收的第1位数据就没有了;

如果 indata |= IN_Data;  indata值为#00000011,成功接收第二位;

后面重复,直到接收完8位数据。
回复

使用道具 举报

ID:265792 发表于 2018-11-12 13:44 | 显示全部楼层
给你几个例子参考看看,不难的
回复

使用道具 举报

ID:417740 发表于 2018-11-12 16:10 | 显示全部楼层
diy1997 发表于 2018-11-12 09:30
比如,indata接收了第1位数据,值为“1” ,这时,indata值为#00000001;

然后向左移1位,为接收下一个 ...

谢谢,谢谢!
我有一个疑问,将值“1”赋值给一个字节,就是将00000001付给这个字节,不是说只把1赋给字节的最后一位(不会影响其他的前七位),对吧,我之前一直觉得一个管脚的0和1只会影响所改字节的最后一位,所以之前想的是错的。


回复

使用道具 举报

ID:417740 发表于 2018-11-14 10:18 | 显示全部楼层
zl2168 发表于 2018-11-12 08:49
给你介绍几个165参考案例
实例25  74HC165串行输入8/16位数据信号

谢谢!
回复

使用道具 举报

ID:662171 发表于 2020-4-15 16:37 | 显示全部楼层
不能直接赋值,以下为个人理解,IN_Data一次只能输出一个状态的值,和indata进行“或”运算后将状态保存在最低位,之后进行移位,最低位的值移到次低位,最低位补零,上升沿后,IN_Data输出下一个状态的值,和indata“或”运算后接着保存在最低位,,以此类推,得到8位状态值。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表