[C语言]

编译器不能理解我用sbit拼合位信息,还是有BUG?

[复制链接]
3825|25
手机看帖
扫描二维码
随时随地手机跟帖
oufuqiang|  楼主 | 2021-6-8 18:39 | 显示全部楼层 |阅读模式
变量:
volatile bdata Hall_val,DRV_val;
sbit ha=Hall_val^2;
sbit hb=Hall_val^1;
sbit hc=Hall_val^0;

拼合:
ha=Ha;hb=Hb;hc=Hc
屏蔽未用的位:
Hall_val&=0x0f;
使用:
DRV_val=hal_drv[Hall_val];

结果,Hall_val的值总是0.
查汇编,发现不能理解

   151:                         ha=Ha;hb=Hb;hc=Hc;
C:0x0389    A2B6     MOV      C,Ha(0xB0.6)
C:0x038B    9212     MOV      ha(0x22.2),C
C:0x038D    A2B3     MOV      C,Hb(0xB0.3)
C:0x038F    9211     MOV      hb(0x22.1),C
C:0x0391    A2B2     MOV      C,Hc(0xB0.2)
C:0x0393    9210     MOV      hc(0x22.0),C
   152:                         Hall_val&=0x0f;
C:0x0395    53230F   ANL      0x23,#0x0F
C:0x0398    752200   MOV      Hall_val(0x22),#0x00
   153:                         DRV_val=hal_drv[Hall_val];

这个各位有什么经验分享指导一下吗?

使用特权

评论回复

相关帖子

linnjing| | 2021-6-8 20:01 | 显示全部楼层
bdata char....

使用特权

评论回复
ayb_ice| | 2021-6-9 08:25 | 显示全部楼层
sbit定义的是位变量,无论怎么运算结果只有1或0

使用特权

评论回复
ayb_ice| | 2021-6-9 08:49 | 显示全部楼层
Ha,Hb,Hc的定义很重要,代码里没有定义,所以看不出具体的问题,你可以用,0,1代替,测试

使用特权

评论回复
oufuqiang|  楼主 | 2021-6-9 08:51 | 显示全部楼层

谢了,又踩到这种坑里面。
看来默认变量是CPU字长这个说法不可信。

使用特权

评论回复
oufuqiang|  楼主 | 2021-6-9 08:52 | 显示全部楼层
ayb_ice 发表于 2021-6-9 08:25
sbit定义的是位变量,无论怎么运算结果只有1或0

是没错,但是我是利用可位寻址的地址,进行散装位数据的拼合。因为画板的时候为了好画,就近用引脚,然后软件这边拼回来。

使用特权

评论回复
kcfoo1| | 2021-6-9 08:58 | 显示全部楼层
用结构体定义位,然后用联合体把结构体和位字节定义在同一内存,这样就既可以单独操作位,也可以操作字节,

使用特权

评论回复
ayb_ice| | 2021-6-9 09:17 | 显示全部楼层
oufuqiang 发表于 2021-6-9 08:51
谢了,又踩到这种坑里面。
看来默认变量是CPU字长这个说法不可信。

没注意这介细节

sbit xxx = yyyy^0;定义的是变量的首地址的位0,

那么对于多字节就有可能出错了(与表面的现象可能不一致)
如果INT型变量,C51占两个字节,且是大端格式,同样的sbit xxx = yyyy^0;,结果是指向了第一个字节的位0,其实就是高位字节的0,定义成sbit xxx = yyyy^8;才是你想要的结果

使用特权

评论回复
zlf1208| | 2021-6-9 09:46 | 显示全部楼层
sbit 对应的是 bit 变量,不是 byte 变量

使用特权

评论回复
henangongda123| | 2021-6-9 09:58 | 显示全部楼层
//全局变量
uchar bdata Send_Byte;        //定义可操作位的一字节发送数据
sbit Bit0 = Send_Byte^0;            //被发送的数据各位定义
sbit Bit1 = Send_Byte^1;
sbit Bit2 = Send_Byte^2;
sbit Bit3 = Send_Byte^3;
sbit Bit4 = Send_Byte^4;
sbit Bit5 = Send_Byte^5;
sbit Bit6 = Send_Byte^6;
sbit Bit7 = Send_Byte^7;
我这样定义的没有问题,keil c51

使用特权

评论回复
逍遥派掌门| | 2021-6-9 14:31 | 显示全部楼层
是你的理解完全错误.
"用sbit拼合位信息",不存在这样东西.所以是你的BUG.

使用特权

评论回复
coody| | 2021-6-9 15:07 | 显示全部楼层
bdata unsigned char,如果你是KEIL 51,默认是int的(有符号16位整数变量)。

使用特权

评论回复
aple0807| | 2021-6-9 16:22 | 显示全部楼层
你这是自创语法,编译器不惯着你而已

使用特权

评论回复
逍遥派掌门| | 2021-6-9 20:54 | 显示全部楼层
kcfoo1 发表于 2021-6-9 08:58
用结构体定义位,然后用联合体把结构体和位字节定义在同一内存,这样就既可以单独操作位,也可以操作字节, ...

开玩笑

使用特权

评论回复
逍遥派掌门| | 2021-6-9 20:56 | 显示全部楼层
coody 发表于 2021-6-9 15:07
bdata unsigned char,如果你是KEIL 51,默认是int的(有符号16位整数变量)。

大神,确定是这样吗?

使用特权

评论回复
ayb_ice| | 2021-6-10 08:24 | 显示全部楼层
Physical bit position 0 refers to bit position 0 of the first byte. Physical bit position 8 refers to bit position 0 of the second byte. Because int variables are stored high-byte first, bit 0 of the integer is located in bit position 0 of the second byte. This is physical bit position 8 when accessed using an sbit data type.

使用特权

评论回复
xiaosun| | 2021-6-10 09:03 | 显示全部楼层
DRV_val是16位的,所以22H=0,23H才是你要的数
按道理DRV_val不应该是0

使用特权

评论回复
oufuqiang|  楼主 | 2021-6-10 11:22 | 显示全部楼层
逍遥派掌门 发表于 2021-6-9 14:31
是你的理解完全错误.
"用sbit拼合位信息",不存在这样东西.所以是你的BUG.

补上变量类型已经解决,不是存不存在的问题

使用特权

评论回复
oufuqiang|  楼主 | 2021-6-10 11:23 | 显示全部楼层
kcfoo1 发表于 2021-6-9 08:58
用结构体定义位,然后用联合体把结构体和位字节定义在同一内存,这样就既可以单独操作位,也可以操作字节, ...

用结构体规范,好移植,但是执行效率不见得高。
控制无刷电机的,效率很重要

使用特权

评论回复
ayb_ice| | 2021-6-10 13:29 | 显示全部楼层
本帖最后由 ayb_ice 于 2021-6-10 13:43 编辑

这样是可以的

volatile int bdata Hall_val,DRV_val;
sbit ha=Hall_val^10;
sbit hb=Hall_val^9;
sbit hc=Hall_val^8;

拼合:
ha=Ha;hb=Hb;hc=Hc
屏蔽未用的位:
Hall_val&=0x07;
使用:
DRV_val=hal_drv[Hall_val];

使用特权

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

本版积分规则

105

主题

1401

帖子

20

粉丝