【单片机C语言救急】为什么这个变量会变成负数了?

[复制链接]
4840|41
手机看帖
扫描二维码
随时随地手机跟帖
henangongda123|  楼主 | 2018-6-10 23:02 | 显示全部楼层 |阅读模式
高手帮忙看一下,这段程序里面,温度转换正确,湿度转换的时候,变量a变成负数了(正数就对了)导致湿度转换错误,什么原因啊?谢谢!
void Tem_Hum_Get(void)
{
        long a;                     //定义一下
        SHT31_Read(SHT31_R_Data,6); //读取SHT31内部温湿度数据
        a = (SHT31_R_Data[0]*256)+SHT31_R_Data[1];
        a = a*175;
        a = a/65535;                //计算温度数值(℃)
        temperature = a-45;         //得到温度数值(℃)
        a = (SHT31_R_Data[3]*256)+SHT31_R_Data[4];
        a = a*100;
        a = a/65535;                //计算湿度数值(%)
        humidity = a;               //得到温度数值(%)
}

变量变负数.png
评论
henangongda123 2018-6-11 21:08 回复TA
@xch :谢谢! 
xch 2018-6-11 18:25 回复TA
SHT31_R_Data[3]*256+SHT31_R_Data[4]; 改成(long) SHT31_R_Data[3]*256L+(long)SHT31_R_Data[4]; 

相关帖子

henangongda123|  楼主 | 2018-6-10 23:04 | 显示全部楼层
SHT31_R_Data[3]、SHT31_R_Data[4]数值是正确的,a应该是+27470,不知道为什么是-27470了!

使用特权

评论回复
icecut| | 2018-6-10 23:59 | 显示全部楼层
用无符号 long
或者数组无符号

使用特权

评论回复
henangongda123|  楼主 | 2018-6-11 08:23 | 显示全部楼层
icecut 发表于 2018-6-10 23:59
用无符号 long
或者数组无符号

晚上我试试,那这个原因是什么?

使用特权

评论回复
一叶倾城wwq| | 2018-6-11 09:48 | 显示全部楼层
楼主我看过你的项目日志,很期待,但这种问题对于你来说不应该是手到擒来的么?这不是C的基本么?你有符号long最高位代表+和-,也许你的采集程序并无问题,是最高符号位的问题,也就是数据类型的问题(我是这样理解的),若有差池,还请楼主指正

使用特权

评论回复
henangongda123|  楼主 | 2018-6-11 09:57 | 显示全部楼层
一叶倾城wwq 发表于 2018-6-11 09:48
楼主我看过你的项目日志,很期待,但这种问题对于你来说不应该是手到擒来的么?这不是C的基本么?你有符号l ...

学生时代专研了单片机两三年,工作后第一年还接触到,第二年开始,已经8年没碰单片机了,呵呵
楼上说的把这个变量定义成无符号型,这个可以解决问题,问题是我想知道我采集的数据都是uchar型的,怎么会突然在这个地方运算后变成负数,感到很诧异!以前都是习惯性定义成无符号的,这个地方考虑到温度有可能是负数,就没有定义成无符号型。

使用特权

评论回复
henangongda123|  楼主 | 2018-6-11 09:58 | 显示全部楼层
一叶倾城wwq 发表于 2018-6-11 09:48
楼主我看过你的项目日志,很期待,但这种问题对于你来说不应该是手到擒来的么?这不是C的基本么?你有符号l ...

你的意思是最高位符号有可能随机?

使用特权

评论回复
caijie001| | 2018-6-11 12:23 | 显示全部楼层
不想要负数就别用有符号的、。。。。。

使用特权

评论回复
henangongda123|  楼主 | 2018-6-11 12:38 | 显示全部楼层
caijie001 发表于 2018-6-11 12:23
不想要负数就别用有符号的、。。。。。

是这个道理,只是我想知道它为什么会变负。

使用特权

评论回复
icecut| | 2018-6-11 12:53 | 显示全部楼层
最高位是1的无符号数都是负数.
你可以打赏了.
比如0xff = 255 = -1

使用特权

评论回复
ruanhongyu| | 2018-6-11 13:19 | 显示全部楼层
“SHT31_R_Data[3]”是什么类型的?“SHT31_R_Data[3]*256”有没有溢出?
你把算式拆成一步一步,看看哪一步有没有溢出。

使用特权

评论回复
henangongda123|  楼主 | 2018-6-11 13:33 | 显示全部楼层
//全局变量
uchar Display = 0;
uchar DS3231_R_Data[7];       //定义、保存读取DS3231数据寄存器值
uchar DS3231_W_Data[7];       //定义、保存写入DS3231数据寄存器值
uchar sec_r,min_r,hour_r,day_r,month_r,year_r,week_r;//定义、保存DS3231读取的年月日时分秒等时间数据
uchar sec_w=00,min_w=15,hour_w=21,day_w=7,month_w=6,year_w=18,week_w=4;//定义、保存写入DS3231的年月日时分秒等时间数据
uchar SHT31_R_Data[6];        //定义、保存读取SHT31数据值
char temperature;             //定义、保存SHT31读取的温度数值
char humidity;                //定义、保存SHT31读取的湿度数值

使用特权

评论回复
henangongda123|  楼主 | 2018-6-11 13:34 | 显示全部楼层
ruanhongyu 发表于 2018-6-11 13:19
“SHT31_R_Data[3]”是什么类型的?“SHT31_R_Data[3]*256”有没有溢出?
你把算式拆成一步一步,看看哪一 ...

看楼下,uchar型,考虑过溢出,所以a才设置成long型(足够了)

使用特权

评论回复
henangongda123|  楼主 | 2018-6-11 13:38 | 显示全部楼层
icecut 发表于 2018-6-11 12:53
最高位是1的无符号数都是负数.
你可以打赏了.
比如0xff = 255 = -1

实际上,我把SHT31_R_Data[3]、SHT31_R_Data[4]这两个数值显示到液晶屏上分别是111、30,湿度值=((111*256+30)*100)/65535=43.4%。

使用特权

评论回复
一叶倾城wwq| | 2018-6-11 13:39 | 显示全部楼层
henangongda123 发表于 2018-6-11 09:58
你的意思是最高位符号有可能随机?

随机这种说法不靠谱,你把无符号的东西放在了有符号里面,编译器隐式类型转换,在小弟看来是如此,楼主可以试试long变量 = (long)uchar变量看看十进制数和二进制数有没有变化就知道了。题外话:楼主的经验很丰富嘛,都工作这么久了,厉害,还有楼主说的在学校钻研很令小弟羡慕的说

使用特权

评论回复
henangongda123|  楼主 | 2018-6-11 13:51 | 显示全部楼层
一叶倾城wwq 发表于 2018-6-11 13:39
随机这种说法不靠谱,你把无符号的东西放在了有符号里面,编译器隐式类型转换,在小弟看来是如此,楼主可 ...

"编译器隐式类型转换"感觉应该是跟编译器有关系,如果把long定义成无符号的,肯定可以解决问题,但是问题的根源还是不清楚啊,上面icecut说的我还是不太明白,远离“技术”好些年了,哈哈

使用特权

评论回复
ruanhongyu| | 2018-6-11 14:07 | 显示全部楼层
henangongda123 发表于 2018-6-11 13:34
看楼下,uchar型,考虑过溢出,所以a才设置成long型(足够了)

我不知道你的编译器把常数“256”当做什么类型的。如果“SHT31_R_Data[3]*256”就已经溢出了,那跟a的类型就没关系了。那你先把所有变量都换成有符号的long,如果结果变正确了,那就能说明是数据溢出了。

使用特权

评论回复
henangongda123|  楼主 | 2018-6-11 14:12 | 显示全部楼层
ruanhongyu 发表于 2018-6-11 14:07
我不知道你的编译器把常数“256”当做什么类型的。如果“SHT31_R_Data[3]*256”就已经溢出了,那跟a的类 ...

溢出不太可能,这个函数里面,你仔细看,上面几行温度数据处理程序和下面的几行湿度数据处理程序是一样的,温度转换的结果正确,湿度就不行;而且我一步步的仿真看,上面温度处理的时候,a是正数,一到湿度那行后就变负数!

使用特权

评论回复
一叶倾城wwq| | 2018-6-11 14:30 | 显示全部楼层
henangongda123 发表于 2018-6-11 13:51
"编译器隐式类型转换"感觉应该是跟编译器有关系,如果把long定义成无符号的,肯定可以解决问题,但是问题 ...

抱歉楼主,刚才的回复我没仔细看你的程序,现在我个人而言是你的同一个缓冲区(变量)重复使用,没有清空导致存了垃圾信息在里面,你可以多试几次,如果a的值是会变化的,那就没跑了,你可以试下在得到温度值后a=0;//清空  还有初始化变量这步楼主也省掉了,这是不严谨的

使用特权

评论回复
XZL| | 2018-6-11 14:36 | 显示全部楼层
应该定义成无符号数据

使用特权

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

本版积分规则

42

主题

2116

帖子

19

粉丝