打印

单片机关于bit的问题

[复制链接]
1884|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
单片机中
sbit dat=P0^0;   就可直接操作地址0x80的第零位了。


现在我想接收到外面的1个bit数据,就直接对bdata中0x20~0x2F的128位即00~0x7f中的任意位赋值,就好像是定义了一个bit 数组一样,可以随意对数组中的某个数进行操作(当然bit是不可以定义成数组的)。
如:收到第一个bit数据,就把他写在上图对应的0x00里,第二位就放在0x01中如此类推,当我收完8个bit就是一个字节时,就直接读取20H的值就能得到整个字节了,省略接收过程的移位等操作,提高效率
不知道上述如何来实现呢?


相关帖子

沙发
望断云山| | 2014-5-18 13:07 | 只看该作者
51貌似没有提供位操作的间接寻址,楼主的想法估计不能实现

使用特权

评论回复
板凳
dirtwillfly| | 2014-5-18 14:00 | 只看该作者

太复杂了,既然要操作8个bit,直接读或写整个字节就可以啊

使用特权

评论回复
地板
yjyzg11707|  楼主 | 2014-5-18 14:25 | 只看该作者
dirtwillfly 发表于 2014-5-18 14:00
太复杂了,既然要操作8个bit,直接读或写整个字节就可以啊

直接读或写整个字节的话就要每次收到一个bit就要对原来的数据进行整合,这样就变慢了。

使用特权

评论回复
5
dirtwillfly| | 2014-5-18 15:23 | 只看该作者
yjyzg11707 发表于 2014-5-18 14:25
直接读或写整个字节的话就要每次收到一个bit就要对原来的数据进行整合,这样就变慢了。 ...

不会,这样更快。

使用特权

评论回复
6
xuyaqi| | 2014-5-18 20:47 | 只看该作者
51单片机是有16个字节可以直接位寻址的,ARM Cortex‐M3也有类似功能。

位操作.jpg (282.28 KB )

位操作.jpg

使用特权

评论回复
7
xuyaqi| | 2014-5-18 20:50 | 只看该作者
至于原理那是芯片的硬件逻辑,制造芯片时已经完成。

使用特权

评论回复
8
huangxz| | 2014-5-18 21:04 | 只看该作者
如果使用物理移位那是不慢的。移位不是一个一个移,而是一次移8比bit的

使用特权

评论回复
9
xuyaqi| | 2014-5-18 21:22 | 只看该作者
位操作有的情况下还是很有用的,如果位标志直接读写位地址会快很多,速度要求不严格也就无所谓了。

使用特权

评论回复
10
xuyaqi| | 2014-5-18 21:25 | 只看该作者
c51定义位变量:
bdata unsigned char byte;
sbit bit0 = byte^0;
sbit bit1 = byte^1;
sbit bit2 = byte^2;
sbit bit3 = byte^3;
sbit bit4 = byte^4;
sbit bit5 = byte^5;
sbit bit6 = byte^6;
sbit bit7 = byte^7;

使用特权

评论回复
11
望断云山| | 2014-5-18 21:36 | 只看该作者
我猜想楼主要的是这样的功能
mov @r0,bit
inc r0
r0中是位地址,bit是位地址或者位值
但是51没有这样的指令

使用特权

评论回复
12
yjyzg11707|  楼主 | 2014-5-18 22:52 | 只看该作者
望断云山 发表于 2014-5-18 21:36
我猜想楼主要的是这样的功能
mov @r0,bit
inc r0

是的,就是要实现这样的功能

使用特权

评论回复
13
yjyzg11707|  楼主 | 2014-5-18 22:55 | 只看该作者
xuyaqi 发表于 2014-5-18 21:25
c51定义位变量:
bdata unsigned char byte;
sbit bit0 = byte^0;

这样是可以直接位操作,但是我是要连续收数据,最好是能循环改变位地址,

使用特权

评论回复
14
mcu5i51| | 2014-5-19 16:04 | 只看该作者
理论和想法都可行,只是对于可以提高效率就不理想了;
51中位操作只能直接寻址操作,就是一个字节你需要写8个位操作指令,根据接收计数器去执行相应的指令
相比循环位移的话要差一些;
位操作用于特定固定位的操作会有优势,比如判断一些特定位的状态,无序(固定)的位复制等;
例如,可以用于端口映射
sbit A_0 =        ACC^0;
sbit A_1 =        ACC^1;
sbit A_2 =        ACC^2;
sbit A_3 =        ACC^3;
sbit A_4 =        ACC^4;
sbit A_5 =        ACC^5;
sbit A_6 =        ACC^6;
sbit A_7 =        ACC^7;
void Disp_SetSeg(u8 tmp)         //设置段显示数据
{       
        ACC = tmp;
        LS1 = A_0;
        LS2 = A_1;       
        LS3 = A_2;       
        LS4 = A_3;
        LS5 = A_4;       
        LS6 = A_5;       
        LS7 = A_6;       
        LS8 = A_7;       
}
以上代码可以任意端口定义IO,效率低于直接同一端口赋值,高于类似 if(dat & 0x01) LEDS1 = 1;else LEDS = 0;的代码

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

16

帖子

1

粉丝