oufuqiang 发表于 2021-6-8 18:39

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

变量:
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的值总是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;

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

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

linnjing 发表于 2021-6-8 20:01
bdata char....

谢了,又踩到这种坑里面。
看来默认变量是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;
页: [1] 2
查看完整版本: 编译器不能理解我用sbit拼合位信息,还是有BUG?