矿石收音机论坛

 找回密码
 加入会员

QQ登录

只需一步,快速开始

搜索
12
返回列表 发新帖
楼主: 乙猪

请教:以下三种单片机传输8字节数的方法,有何区别??

[复制链接]
     
发表于 2022-6-9 21:17:29 | 显示全部楼层
本帖最后由 ssffzz1 于 2022-6-9 21:20 编辑
天天爱玛丽 发表于 2022-6-9 20:43
这个写法是错的,没有转为bit,
需要用(bit)//C51 或 !!转为bit
放在一句的思路是对的


谢指正,但是依照我的看法 & 操作之后,只有 1 或者 0两种值, 不用bit强制转换,也是1 或者 0两个值.
直接赋值应该可以,这里隐含着有自动类型转换.

这句不完善, & 0x80,就不是1 0 两种值,而是 0x80  0x00 两种值,因此 !! 方法稳妥.

当然实际如何还要看在机器上跑的结果.我对51并不是很熟悉,有可能有偏颇.

补充:
想了下,高位先出的话,还是你的做法对.加!! 转换为 0 1 ,妥当.谢了!我那个说法不完善,低位先出没问题.

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

     
发表于 2022-6-9 21:24:34 | 显示全部楼层
本帖最后由 天天爱玛丽 于 2022-6-9 21:30 编辑
ssffzz1 发表于 2022-6-9 21:17
谢指正,但是依照我的看法 & 操作之后,只有 1 或者 0两种值, 不用bit强制转换,也是1 或者 0两个值.
直接 ...


C语言中&是位与运算,例如dat&0x80,得到的结果是0x80或0x00,任何编译器都是这个结果。
需要强转为位类型

你已经自己更正了问题,我回复稍比你的晚了一点,好在看法是一致的。
!!操作在linux源代码中用的很多,它会把任意变量变成逻辑变量0或1,即使逻辑变量表示为非0或0,
经!!操作之后也是1或0,用在楼主此处相得益彰,滴很

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

     
发表于 2022-6-9 21:30:17 | 显示全部楼层
天天爱玛丽 发表于 2022-6-9 21:24
C语言中&是位与运算,例如dat&0x80,得到的结果是0x80或0x00,任何编译器都是这个结果。
需要强转为位类 ...

是的,没问题.

我不太清楚  编译器 或者51CPU 自动转换为bit类型的时候是个啥操作,0x80有可能转成1,也有可能转成0,这个. 所以还是用!! 稳妥.

!! 这个用法,移植性没问题的,十二分标准的C语言操作.

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2022-6-9 21:36:19 来自手机 | 显示全部楼层
没想到还有这么多方法。
回复 支持 反对

使用道具 举报

     
发表于 2022-6-9 22:01:42 | 显示全部楼层
天天爱玛丽 发表于 2022-6-9 21:24
C语言中&是位与运算,例如dat&0x80,得到的结果是0x80或0x00,任何编译器都是这个结果。
需要强转为位 ...

感谢:

我手里没有51的单片机或者模拟器,不过我用sdcc编译器看了下代码

C:代码
#include<stdio.h>
#include<8051.h>

__sbit y;
unsigned char x;

void
t(void)
{
  y= x;
}

汇编代码:
_t:
        ar7 = 0x07
        ar6 = 0x06
        ar5 = 0x05
        ar4 = 0x04
        ar3 = 0x03
        ar2 = 0x02
        ar1 = 0x01
        ar0 = 0x00
;        1.c:10: y= x;
;        assignBit
        mov        a,_x
        add        a,#0xff
        mov        _y,c
;        1.c:11: }
        ret

从sdcc编译器的动作来看,貌似是可以正确转换的,我对51的汇编不太熟悉但大概我的理解是

mov a,_x   // 参数x送入a寄存器
add a,#0xff  // a + 0xff ,如果a非0,必将导致溢出,如果a为0,那么不会溢出
mov _y,c // c寄存器保存的是add算数运算的溢出位.

所以上面的代码大概率是正常的.

// 这个地方我不太了解在sdcc里c寄存器是不是cy标志,所以上面的分析未必正确.

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

     
发表于 2022-6-9 23:03:03 | 显示全部楼层
本帖最后由 天天爱玛丽 于 2022-6-9 23:09 编辑
ssffzz1 发表于 2022-6-9 22:01
感谢:

我手里没有51的单片机或者模拟器,不过我用sdcc编译器看了下代码


在keilC51的环境下测试,你说的是对的,
DIN = dat & 0x80;
DIN的值就是1或0,
51单片机有位寄存器,C51对于左值为位类型的赋值语句,都使用位类型运算,结果已经是位类型,无需再转换。
PS:
这个结论只在51平台下有效,
本着移植性原则,建议还是应该强转为位。

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

     
发表于 2022-6-9 23:32:57 | 显示全部楼层
天天爱玛丽 发表于 2022-6-9 23:03
在keilC51的环境下测试,你说的是对的,
DIN = dat & 0x80;
DIN的值就是1或0,

赞同.

单片机多用于工控环境,代码稳定可移植为首要考虑的问题,因此不应片面追求性能而采用一些小技巧.
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2022-6-10 01:14:52 | 显示全部楼层
在keil 中测试了一下,
DIN = !!(dat&0x80)    code最长。
DIN=CY                    code最短。

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

     
发表于 2022-6-12 12:13:46 | 显示全部楼层
虽然大家都不看好第1种写法,但是我比较赞同第1种和第4种写法,虽然会增加编译后的代码执行时间,但是方便移植和阅读。今天MCU的性价比,已经不太需要追求性能而采用一些技巧了。

评分

2

查看全部评分

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入会员

本版积分规则

小黑屋|手机版|矿石收音机 ( 蒙ICP备05000029号-1 )

蒙公网安备 15040402000005号

GMT+8, 2025-4-28 18:24

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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