找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5532|回复: 2
收起左侧

Char型变量与Bit型变量,如何进行”或运算”。

[复制链接]
ID:418269 发表于 2018-12-2 00:03 | 显示全部楼层 |阅读模式
大神们,本人C语音小白。学习金沙工作时宋雪松老师《手把教你学 51 单片机 -C语音版》遇到不同变量直接的运算问题。
小人看C语言描述 :运算时 都是短字节向长字节转换。如char型变量 & int型变量,进行运算时,是编译器强制将char 转换成int型。

但宋雪松老师讲的如下:连续将key4值通过T0中断,一位一位用“或运算“写入char 型变量keybuf中。这与其他地方对不同变量的运算描述不符,请大神们赐教。小弟拜谢。

void InterruptTimer0() interrupt 1
{  static unsigned char keybuf = 0xFF;  //按键扫描缓冲区,保存一段时间内的扫描值   
    TH0 = 0xF8; TL0 = 0xCD;   
    keybuf = (keybuf << 1) | KEY4;  //只取KEY4为例,缓冲区左移一位,并将当前扫描值移入最低位
    if (keybuf == 0x00)
    { //当连续8次扫描值都为0,即16ms内都只检测到按下状态时,可认为按键已按下
        KeySta = 0;       //按键状态值为按下
    }
    else if (keybuf == 0xFF)
    { //当连续8次扫描值都为1,即16ms内都只检测到弹起状态时,可认为按键已弹起
        KeySta = 1;      //按键状态值为弹起
  }

回复

使用道具 举报

ID:52586 发表于 2018-12-2 02:38 | 显示全部楼层
char 变量与 bit 变量 或运算,也是把 bit 转换成 char

看程序发现,这是个定时器中断,中断间隔为 2ms
KEY4 是个 bit,按下为0,弹起为1
keybuf 是个局部静态变量,其值在函数退出后仍能保存。

程序执行流程:
1,当key被按下后,进入中断,keybuf 当前值为 0xFF
2,由于机械按键存在抖动,所以要去抖,程序中采用了检测8次的方法来去抖
3,keybuf = (keybuf << 1) | KEY4;
    假定这次读出的 KEY4 为0, keybuf 左移一位变成 b1111 1110 然后与 KEY4 或运算
    注意此处进行了转换,将 KEY4 的 bit 类型值转换成 char, 二进制 b0000 0000
    运算结束后, keybuf 结果为 0xFE ,用二进制表示为 1111 1110
    2ms 后,第二次进中断,如果 KEY4 还是 0 ,那么 keybuf 的值为  b1111 1100
4,如果进入中断 8 次,读出的 KEY4 都为 0, 那么 keybuf 的值就变成 0x00
5,由于抖动期间, KEY4 的值会变化 01,所以如果存在抖动,keybuf 的值就不是 b0000 0000
    有可能是  b1100 0001 这样的

评分

参与人数 1黑币 +100 收起 理由
admin + 100 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:357520 发表于 2018-12-2 16:16 | 显示全部楼层
10.1 数字秒表实验10.1.1 不同数据间的类型转换
在C语言中,不同数据类型之间是可以混合运算的。当表达式中的数据类型不一致时,首先转换为同一种类型,然后再进行计算。C语言有两种方法实现类型转换,一是自动类型转换,另外一种是强制类型转换。这块内容是比较繁杂的,因此我们根据我们常用的编程应用来讲部分相关内容。
当不同数据类型之间混合运算的时候,不同类型的数据首先会转换为同一类型,转换的主要原则是:短字节的数据向长字节数据转换。
比如:unsigned char  a ;  unsigned int b;  unsigned int c;  c = a *b;
在运算的过程中,程序会自动全部按照unsigned int型来计算。比如a=10,b=200,c的结果就是2000。那当a=100,b=700,那c是70000吗?新手最容易犯这种错误,大家要注意每个变量的数据类型,c的数据类型是unsigned int型,取值范围是0~65535,70000超过65535溢出了,所以最终c的结果是(70000 - 65536) = 4464。
那要想让c正常获得70000这个结果,需要把c定义成一个unsigned long型。我们如果写成:unsigned char  a=100;  unsigned int  b=700;  unsigned long  c=0;  c = a *b;如果有做过实验的同学,会发现这个c的结果还是4464,这个是个什么情况呢?
大家注意,C语言不同类型运算的时候数值会转换同一类型运算,但是每一步运算都会进行识别判断,不会进行一个总的分析判断。比如我们这个程序,a和b相乘的时候,是按照unsigned int类型运算的,运算的结果也是unsigned int类型的4464,只是最终把unsigned int类型4464赋值给了一个unsigned long型的变量而已。我们在运算的时候如何避免这类问题的产生呢?可以采用强制类型转换的方法。
在一个变量前边加上一个变量类型,并且这个变量类型用小括号括起来,表示把这个变量强制转换成括号里的变量类型。如 c = (unsigned long)a * b;由于强制类型转换运算优先级高于*,所以这个地方的运算是先把a转换成一个unsigned long型的变量,而后与b相乘,根据C语言的规则b会自动转换成一个unsigned long型的变量,而后运算完毕结果也是一个unsigned long型的,最终赋值给了c。
当不同类型变量相互赋值时,短字节的数据向长字节的变量赋值时,值不变,比如unsigned char  a=100;  unsigned int  b=700;  b = a;那么最终b的值就是100了。但是如果我们的程序是unsigned char  a=100;  unsigned int  b=700;  a=b;那么a的值仅仅是取了b的低8位,我们首先要把700变成一个16位的二进制数据,然后取它的低8位出来,也就是188,这就是长字节给短字节赋值的结果。
在51单片机里边,有一种特殊情况,就是bit类型的变量,这个bit类型的强制类型转换,是不符合上边讲的这个原则的,比如bit a = 0;  unsigned char b; a = (bit)b;这个地方要特别注意,使用bit做强制类型转换,不是取b的最低位,而是他会判断b这个变量是0还是非0的值,如果b是0,那么a的结果就是0,如果b是任意非0的其他数字,那么a的结果都是1。

这是咱们站里的学习资料或许对你有帮助
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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