普中开源电子分享网

 找回密码
 立即注册
搜索
查看: 1278|回复: 0

[已解决] 记录并分享通过595串-并芯片实验学到的知识点-十六进制数给 sbit赋值的实现

[复制链接]

14

主题

48

帖子

258

积分

中级会员

Rank: 3Rank: 3

积分
258
发表于 2023-4-24 13:12:34 | 显示全部楼层 |阅读模式
本帖最后由 zhong_zhiqi 于 2023-4-24 13:16 编辑

    在“P97- IO扩展(串转并)-74HC595--软件编程”这一节视频中,为了使用实验板上的74HC595来驱动8x8 LED点阵,需要逐位对P3.4管脚赋值,由于C语言不可以使用二进制数赋值,所以只能使用十六进制数赋值,视频中的代码是:
...【循环8此用来将8位依次赋给寄存器】...
SER=dat>>7;
dat<<=1;
...【SRCLK上升沿】...

     此处在讲解右移和左移后,带出了一个问题:十六进制数究竟如何给一个sbit位进行赋值的?这个算是C51的一个特有的,标准C语言书籍里没有的。视频中的讲解似乎是告诉大家赋值时的十六进制数的最低位会赋值到sbit变量中,那么紧跟着的左移呢?讲解的不甚了了,于是带着这个问题通过不同的代码来验证想法:

* 如果顺着“十六进制数的最低位会赋值到sbit变量中”的思想,那么当第一次循环十六进制数的最高位右移7位移入移位寄存器后,第二次循环次高位右移6位可不可以,以此类推第三位右移5位。。。。直到最低位不移,这样减少移位的操作减少单片机的执行步骤可不可以呢?例如以下的代码:
        for(i=7; i>=0; i--)
        {
                SER=dat>>i;
...【SRCLK上升沿】...
        }
答案是否定的,8x8 LED显示出的结果与预期不一致,继续分析;

* 再分解一下视频中先右移7位再左移一位的实际效果:就是通过两次高、低位补零的过程中,只保留了操作位的值1或0,而将操作位以外的位都变为0,所以再实验一下以下代码:
        i=128;
        j=7;
        while((i>=1) && (j>=0))
        {
                SER=(dat&i)>>j; // 依次对操作位做按位与操作,来保留操作位,其余位置0,再右移7、6、5、4...0位
...【SRCLK上升沿】...
                i/=2;
                j-=1;               
        }
答案是肯定的,8x8 LED显示出的结果与预期一致,那么如果先右移再按位与应该也是可行的:

* 以下代码就是先把操作位移到最低位后再每次都按位与一下:
        for(i=7; i>=0; i--)
        {
                SER=(dat>>i)&0x01;
...【SRCLK上升沿】...
        }

答案是肯定的,8x8 LED显示出的结果与预期一致;

* 再发散一下思考,如果只对操作位做按位与,不做右移会怎么样呢?
        for(i=128; i>=1; i=i/2)
        {        
                SER=dat&i;
...【SRCLK上升沿】...
        }

答案是肯定的,8x8 LED显示出的结果与预期一致。

【结论】通过以上实验可以得出,用一个十六进制数给sbit变量赋值时:1- 如果此十六进制数为0(所有位都是0),则sbit为0;2- 如果此十六进制数任何一位为1时,则sbit为1。因此十六进制数中为1的位在不在最低位不重要,重要的是十六进制数是0还是非0。
回复

使用道具 举报

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

本版积分规则

关闭

站长推荐上一条 /1 下一条

Archiver|手机版|小黑屋|普中开源电子分享网 粤ICP备16123577号-2

GMT+8, 2024-5-3 22:38 , Processed in 0.180631 second(s), 30 queries .

Powered by 论坛搭建 X3.4

Copyright © 2001-2021, Tencent Cloud.

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