标题: 单片机新手求教74HC595位移程序的执行分析,百思不得其解 [打印本页]

作者: yanyongtom    时间: 2018-8-19 21:37
标题: 单片机新手求教74HC595位移程序的执行分析,百思不得其解
在编写74HC595芯片编程时,位移问题百思不得其解:
typedef unsigned char u8;
sbit SER=p3^4;

void SendTo595(u8 indata){
        u8 i=0;
        for(;i<8;i++){         
                SER=indata>>7;
                indata=indata<<1;
                }

如果我传入的indata=1001 1001,将indata>>7,是不是变成0000 0001,再把移位后的数值赋值给SER,那不是SER=0吗?但显示结果是1,这是为什么呢?


作者: trm999    时间: 2018-8-20 03:45
10011001右移7位是0000001
作者: trm999    时间: 2018-8-20 03:47
0000001是U8数据,赋值给位数据取最后一位就是1
作者: mrhan1992    时间: 2018-8-20 08:45
1001 1001 右移7位后得到数值 0000 0001,这个数值是2进制数,那最后一位代表2^0(2的0次方),也就是右移后得到一个2的0次方数,那么最后的结果就是1了(2的0次方等于1)。
作者: yanyongtom    时间: 2018-8-20 10:21
trm999 发表于 2018-8-20 03:47
0000001是U8数据,赋值给位数据取最后一位就是1

给位数据赋值,不是取第一位吗?难道是取最后一位?
作者: yanyongtom    时间: 2018-8-20 10:24
mrhan1992 发表于 2018-8-20 08:45
1001 1001 右移7位后得到数值 0000 0001,这个数值是2进制数,那最后一位代表2^0(2的0次方),也就是右移 ...

0000 0001=2^0,这个我明白,我只是奇怪,为什么右移后是把末位赋值人SER,而不是首位赋值给SER
作者: HC6800-ES-V2.0    时间: 2018-8-20 13:01
yanyongtom 发表于 2018-8-20 10:24
0000 0001=2^0,这个我明白,我只是奇怪,为什么右移后是把末位赋值人SER,而不是首位赋值给SER

很正常啊。
因为SER是一位,一个八位赋值给一位,自动取低位。同理,一个十六位赋值给八位,同样,自动取低八位。以此可以类推的。
作者: yanyanlw    时间: 2018-8-20 14:32
确实,一个字节的数值赋值给一个比特,选最低位赋值。
作者: yun_knight    时间: 2018-8-20 14:52
10011001右移7位是0000001
作者: linfeng211    时间: 2018-8-20 15:39
indata右移7位等于00000001
作者: linfeng211    时间: 2018-8-20 15:44
10011001右移7位是0000001,取最后一位,所以SEG=1啊
作者: cjm82    时间: 2018-8-20 16:38
indata= 1001 1001;
SER = indata>>7;
可以这么理解
这两句执行后,indata右移7位后(0000 0001)的最低位赋值给SER,即SER = 1,
然后这两句执行过程中,indata并没有重新赋值,indata的值仍然是1001 1001.
如需要移位操作后将移位后的值赋予原变量,
应该是
indata >>= 7;
关于74HC595适合用来与74HC165配合来用做IO口扩展
我这有当年我学习该芯片的一些程序,楼主可以参考下
bdata u8 out_data;
sbit ds = PX^X;               
sbit shcp = PX^X;          //74hc595时钟引脚
sbit mr = PX^X;            //74HC595清零引脚,低电平有效,可直接接VCC
sbit stcp = PX^X;         //相当于片选信号
sbit stcp2 = PX^X;
sbit buf = out_data^7;
void tran(u8 dat)
{
        u8 i = 0;
        shcp = 0;
        out_data = dat;
        while(i<8)
        {
                ds = buf;
                shcp = 1;
                _nop_();
                _nop_();
                shcp = 0;
                out_data<<=1;
                i++;
        }
}

void tran_data(u8 dat,u8 which)
{
        tran(dat);
        if(which == 0)
        {
                stcp = 0;
                _nop_();
                _nop_();
                stcp = 1;
        }

        if(which == 1)
        {
                stcp2 = 0;
                _nop_();
                _nop_();
                stcp2 = 1;
       
        }
}

74HC595可以多片并联,时钟信号SHCP,串行数据DS端并在一起,用STCP脚作片选.

1.png (25.67 KB, 下载次数: 41)

参考电路

参考电路

作者: cjm82    时间: 2018-8-20 16:41
我以前用74HC595的代码
bdata u8 out_data;
sbit ds = P4^0;
sbit shcp = P4^1;
sbit mr = P4^2;
sbit stcp = P4^3;
sbit stcp2 = P4^4;
sbit buf = out_data^7;

void tran(u8 dat)
{
        u8 i = 0;
        shcp = 0;
        out_data = dat;
        while(i<8)
        {
                ds = buf;
                shcp = 1;
                _nop_();
                _nop_();
                shcp = 0;
                out_data<<=1;
                i++;
        }
}

void tran_data(u8 dat,u8 which)
{
        tran(dat);
        if(which == 0)
        {
                stcp = 0;
                _nop_();
                _nop_();
                stcp = 1;
        }

        if(which == 1)
        {
                stcp2 = 0;
                _nop_();
                _nop_();
                stcp2 = 1;
       
        }
}
附件是参考电路

1.png (25.67 KB, 下载次数: 39)

1.png





欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1