找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2134|回复: 35
收起左侧

请问C语言比较数YEAR为什么不能大于255,大于会出错(之前的举例程序有问题)

  [复制链接]
ID:769545 发表于 2022-6-30 12:50 | 显示全部楼层 |阅读模式
bit volatile ADCY@((unsigned)&sbstatus*8+0;
unsigned short  YEAR;
ADCY=0;YEAR=2000;

for(;;)
{

  YEAR=YEAR+1;
   if(YEAR>=2020)
   ADCY=1;

}


请教一下大神们:unsigned short  YEAR;改为unsigned char  YEAR;就可以编译通过,是不是比较的数据只能用一个8位数据?用16位的数据是不可以直接比较的。我用PICC9.83编译
回复

使用道具 举报

ID:887371 发表于 2022-6-30 15:02 | 显示全部楼层
我用PICC9.83编译你的代码,二者都可以编译通过,并且编译结果(分析汇编代码)是正确的。
用unsigned char会有警告。警告信息如下:
Warning [766] FER039.C; 38. degenerate signed comparison
Warning [766] FER039.C; 38. degenerate signed comparison
Warning [1090] FER039.C; 32. variable "_year" is not used


通常编译器是不会有问题的,你应该检查你的代码。
回复

使用道具 举报

ID:401564 发表于 2022-6-30 17:10 | 显示全部楼层
我这只有XC8的,但楼上已经帮你测试过了,并没有问题,那就像他说的那样,检查一下你自己的代码
试想一下你也能明白这个道理的,再垃圾的编译器,它也不会到连一个16位数大小都不能比较的地步吧,那三角函数,浮点运算怎么办呢?
回复

使用道具 举报

ID:883242 发表于 2022-6-30 21:15 | 显示全部楼层
出什么错都不贴出来,让大家盲猜?
回复

使用道具 举报

ID:61140 发表于 2022-6-30 21:24 | 显示全部楼层
你只是定义一个变量的东东,这个变量定义不能用8位变量,不然只能小于255,也可以用unsigned int 定义一个变量
回复

使用道具 举报

ID:844772 发表于 2022-7-1 09:48 | 显示全部楼层
我没有试过,但如果unsigned short 通过不了,我会用 unsigned int 替代的,毕竟给单片机的编译器嘛。
回复

使用道具 举报

ID:1037856 发表于 2022-7-1 10:11 | 显示全部楼层
sizeof(unsignd short),看一下这个类型是不是16位
回复

使用道具 举报

ID:887371 发表于 2022-7-1 11:35 | 显示全部楼层
zjswuyunbo 发表于 2022-7-1 10:11
sizeof(unsignd short),看一下这个类型是不是16位

PICC中short是16位。
picc.png

回复

使用道具 举报

ID:329625 发表于 2022-7-1 19:35 | 显示全部楼层
数据是8位的
回复

使用道具 举报

ID:769545 发表于 2022-7-2 10:39 | 显示全部楼层

我发现PICC编译器,运算的数据是可以用16位或浮点数,比较数据大小却只能是8位,是这样的吗?我是新手。
回复

使用道具 举报

ID:769545 发表于 2022-7-2 10:42 | 显示全部楼层
datouyuan 发表于 2022-6-30 15:02
我用PICC9.83编译你的代码,二者都可以编译通过,并且编译结果(分析汇编代码)是正确的。
用unsigned cha ...

我的意思是我发现PICC编译器,能运算浮点数和16位数据,比较数据却只能8位。是不是设置有问题
回复

使用道具 举报

ID:769545 发表于 2022-7-2 10:45 | 显示全部楼层
xiaoyuxinke 发表于 2022-6-30 21:24
你只是定义一个变量的东东,这个变量定义不能用8位变量,不然只能小于255,也可以用unsigned int 定义一个变量

我的意思啊PICC编译器,浮点数和16位数据运算都不会出错,比较数据8位(char)就正常,16位(int)就出错。
回复

使用道具 举报

ID:887371 发表于 2022-7-2 10:54 | 显示全部楼层
hym8085hym 发表于 2022-7-2 10:39
我发现PICC编译器,运算的数据是可以用16位或浮点数,比较数据大小却只能是8位,是这样的吗?我是新手。

有点烦了。
出现问题,竟然怀疑编译器有问题,而不怀疑自己的代码。
你这新手太牛逼了。
回复

使用道具 举报

ID:883242 发表于 2022-7-2 12:11 | 显示全部楼层
hym8085hym 发表于 2022-7-2 10:42
我的意思是我发现PICC编译器,能运算浮点数和16位数据,比较数据却只能8位。是不是设置有问题

1)你用的是什么单片机?
2)报错的内容必须贴出来,一句“编译不通过”无法给出足够的信息。
3)最好把代码贴出来。
回复

使用道具 举报

ID:769545 发表于 2022-7-2 13:40 | 显示全部楼层
datouyuan 发表于 2022-6-30 15:02
我用PICC9.83编译你的代码,二者都可以编译通过,并且编译结果(分析汇编代码)是正确的。
用unsigned cha ...

很奇怪:pic16f884芯片就不会出错;PIC16F676在中断地方比较就会出错,不在中断地方比较就不会出错。
回复

使用道具 举报

ID:769545 发表于 2022-7-2 13:42 | 显示全部楼层
datouyuan 发表于 2022-7-2 10:54
有点烦了。
出现问题,竟然怀疑编译器有问题,而不怀疑自己的代码。
你这新手太牛逼了。

用PIC16F884芯片就可以通过;用PIC16F676芯片在中断的地方比较就会出错,正常的程序里面不会出错!奇怪的是这个
回复

使用道具 举报

ID:883242 发表于 2022-7-2 14:49 | 显示全部楼层
PIC16F676只有64bytes RAM,哪里经得起你这么瞎折腾?
回复

使用道具 举报

ID:401564 发表于 2022-7-2 15:56 | 显示全部楼层
PIC16F676只有64个字节的RAM,比传统8051的128个字节还少
而且,PIC16F676只有8级的硬件堆栈,不知道你对硬件堆栈了解与否?
如果不了解,那就告诉你几个要注意的点
1,函数可以多,但尽量少在函数中调用函数,而你调用的函数中又有调用其它函数的情况
2,中断函数只做一些必需要做的操作,只要能在主函数做的事情,不要在中断中进行,中断函数只做清除中断标志位,或者置位某个标志,用于告诉主程序:这个中断被触发了
我没有认真看这个单片机的数据手册,不知道有没有堆栈满复位功能,如果有,那就使能这个功能,你程序运行后不断复位的,就说明你的代码不行
回复

使用道具 举报

ID:769545 发表于 2022-7-7 10:19 | 显示全部楼层
Y_G_G 发表于 2022-7-2 15:56
PIC16F676只有64个字节的RAM,比传统8051的128个字节还少
而且,PIC16F676只有8级的硬件堆栈,不知道你对硬件 ...

我之前是用汇编的。想学习C语言,实际上这个程序我定义的RAM不多,提示是不够用。就是不明白C语言的程序是怎么影响到RAM.按理定义是不影响RAM数量的呀
回复

使用道具 举报

ID:879348 发表于 2022-7-7 10:38 | 显示全部楼层
PIC应该不会,只有一些低端单片机才会使用精简C
回复

使用道具 举报

ID:401564 发表于 2022-7-7 10:40 | 显示全部楼层
hym8085hym 发表于 2022-7-7 10:19
我之前是用汇编的。想学习C语言,实际上这个程序我定义的RAM不多,提示是不够用。就是不明白C语言的程序 ...

你用汇编,就更应该知道RAM和堆栈了,特别是PIC这种使用硬件堆栈的单片机
8级硬件堆栈在汇编上还行,但到了C,函数调用得多了就不知道到底用了几层了,很容易就溢出了
RAM更不用说了,像STC的8051一般都有扩展的SRAM,大多情况下还是够用的
PIC16F676就真真的只有64个字节了,没用过这个单片机,实在不了解64个字节的RAM到底能干多少活
回复

使用道具 举报

ID:887371 发表于 2022-7-7 10:43 | 显示全部楼层
hym8085hym 发表于 2022-7-7 10:19
我之前是用汇编的。想学习C语言,实际上这个程序我定义的RAM不多,提示是不够用。就是不明白C语言的程序 ...
这代码太多问题了。
1.不要大量使用volatile 绝对定位变量。
2.能用自动变量就不要用全局变量。
3.中断服务中使用函数。
4.多处代码逻辑混乱。
5.picc的特有语法使用错误。你这代码功能我猜测是2位数码管显示,只需要标准C语言就能完成,完全不需要用到picc的特有语法。虽然你没定义几个变量,因语法出错,编译提示定义的变量超出了极限。

楼主应要花几天学习下C语言基础。


你在另一个帖子里有完整代码,错误太多。

按理定义是不影响RAM数量,但你错误的代码会。
回复

使用道具 举报

ID:769545 发表于 2022-7-7 11:07 | 显示全部楼层
Y_G_G 发表于 2022-7-7 10:40
你用汇编,就更应该知道RAM和堆栈了,特别是PIC这种使用硬件堆栈的单片机
8级硬件堆栈在汇编上还行,但到了 ...

之前用汇编,所以内存我控制的很严格;中断里面用到的RAM是不能被优化,所以需要固定地址;我发现又奇怪的是:固定地址编译能通过,如果没固定地址,就提示内存不够,程序都一样的。以下的定义都是用在中断里面的;
能通过的定义:
unsigned char volatile LSEC @ 0X24;
unsigned char volatile HSEC @ 0X25;
unsigned char volatile DIP0 @ 0X26;
unsigned char volatile DIP1 @ 0X27;
unsigned char volatile WEI @ 0X30;
如果以下定义:
unsigned char volatile LSEC ;
unsigned char volatile HSEC ;
unsigned char volatile DIP0 @ 0X26;
unsigned char volatile DIP1 @ 0X27;
unsigned char volatile WEI @ 0X30;
就提示出错:could not find space (1 byte) for variable _HSEC
回复

使用道具 举报

ID:401564 发表于 2022-7-7 12:00 | 显示全部楼层
hym8085hym 发表于 2022-7-7 11:07
之前用汇编,所以内存我控制的很严格;中断里面用到的RAM是不能被优化,所以需要固定地址;我发现又奇怪 ...

我用的是XC8编译器,没有用过PICC
这个单片机只有8级硬件堆栈,中断的话,PC程序计数器用两个,那就只剩下6级堆栈了
在中断中基本就不能再使用其它函数了,只能做清除标志位之类的操作了
至于,volatile变量,没有那个必要,这种事情留给编译器去做,你没有充分理解硬件和代码如何执行的情况下,盲目的用volatile,只会弄巧成拙
回复

使用道具 举报

ID:769545 发表于 2022-7-7 12:30 | 显示全部楼层
Y_G_G 发表于 2022-7-7 12:00
我用的是XC8编译器,没有用过PICC
这个单片机只有8级硬件堆栈,中断的话,PC程序计数器用两个,那就只剩下6 ...

我后续用你的编译器试试。谢谢您的回复。
回复

使用道具 举报

ID:121859 发表于 2022-7-7 13:30 | 显示全部楼层
if(YEAR>=2020)是没有问题的,问题可能出在你的ADCY这个位变量上。
回复

使用道具 举报

ID:401564 发表于 2022-7-7 20:04 | 显示全部楼层
hym8085hym 发表于 2022-7-7 12:30
我后续用你的编译器试试。谢谢您的回复。

没叫你用XC8呀
我只是我说不没有用过PICC而已
我用XC8是因为买的书上面用的是XC8,所以,就跟着学了
你要学的是C语言方面编程
你倒是可以看一下CCS编译器,这个函数就很多了,像什么PWM,延时,读写SD卡都有的
回复

使用道具 举报

ID:887371 发表于 2022-7-8 10:49 | 显示全部楼层
hym8085hym 发表于 2022-7-7 12:30
我后续用你的编译器试试。谢谢您的回复。

楼主还是在怀疑编译器。
都已经多次指出是楼主代码问题,和编译器无关。

另外楼主懂汇编,应该对比分析编译出来的汇编代码,也可以优化自己的C代码。
回复

使用道具 举报

ID:962286 发表于 2022-7-9 10:15 | 显示全部楼层
hym8085hym 发表于 2022-7-7 11:07
之前用汇编,所以内存我控制的很严格;中断里面用到的RAM是不能被优化,所以需要固定地址;我发现又奇怪 ...

你把volatile修饰和强制@地址去掉,让编译器自由分配地址,估计就好了。

另外:新手不要轻易怀疑编译器问题,尤其是一个经过十多年考验的已经相当成熟的编译器。多从自己身上找问题,可以减少不必要的时间浪费。
回复

使用道具 举报

ID:769545 发表于 2022-7-9 10:48 | 显示全部楼层
datouyuan 发表于 2022-7-8 10:49
楼主还是在怀疑编译器。
都已经多次指出是楼主代码问题,和编译器无关。

奇怪的是:和汇编一样固定地址就编译没问题,编译提示内存用的不多。不固定地址编译就提示内存不够;想不明白啊
回复

使用道具 举报

ID:1038923 发表于 2022-7-9 11:20 | 显示全部楼层
定义的unsighed int 最大就是255吧,你超过了当然要出错了。如果担心这个问题直接定义Long int
回复

使用道具 举报

ID:883242 发表于 2022-7-9 13:48 | 显示全部楼层
liu1337 发表于 2022-7-9 11:20
定义的unsighed int 最大就是255吧,你超过了当然要出错了。如果担心这个问题直接定义Long int

懂就回答不懂就算了,你的回复错漏连篇就没有对的地方。

8楼已经贴出来unsigned int是16位,最大是65535。

c语言的优点是你就算是超过范围也不可能在编译阶段报错,楼主的问题你再看一遍。
回复

使用道具 举报

ID:401564 发表于 2022-7-9 19:02 | 显示全部楼层
这只是一个很简单的问题呀,为什么就折腾了十来天呢?
就那么几十行代码,只要这穿牛角尖,几天就能解决问题
1,不要在中断中有函数,中断只做中断标志位的清除
2,不要给变量自己加上volatile,标准C写就行
3,能用局部变量就不要用全局变量,全局变量在整个程序运行中是一直占用RAM的,局部变量就不一样了
回复

使用道具 举报

ID:950946 发表于 2022-7-9 23:54 | 显示全部楼层
本帖最后由 dwb123 于 2022-7-10 16:50 编辑

0-255是8位宽,256就不是了
回复

使用道具 举报

ID:950946 发表于 2022-7-9 23:57 | 显示全部楼层
0-255是8位大于255不就是9位了
回复

使用道具 举报

ID:1037510 发表于 2022-7-12 11:40 | 显示全部楼层
255 的二进制是1111 1111 ,再加1是啥?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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