cnt是无符号整形,第二个for循环cnt>-1的判断不对,当cnt为0后,再次执行--,cnt变为255 |
Hephaestus 发表于 2022-7-9 01:28 第8行放在第6行之前我试过了,就是将unsigned int i=0;放在while(1)之前,编译不通过,我用的是stc8g1ko8a,P3口有4个I/O,我的(抄楼主的)程序如下 #include <STC8G.H> //#define char //#define unsigned int void main() { P3M0=0x00; P3M1=0x00; P5M0=0X00; P5M1=0X00; while(1) { unsigned int i=0; char led4=0; for(led4=0;led4<4;led4++) { P3=~(0x01<<led4); for(i=0;i<40000;i++); } for(led4=4;led4>0;led4--) { P3=~(0x08>>(4-led4)); for(i=0;i<40000;i++); } } } |
定义的数据类型就不对,Unsigned int, 不可能出现-1. 程序的循环设计需要重新修改一下 |
这是一个【数据类型】的问题!参见下面7楼的解答吧。 |
没人注意到第8行是语法错误吗? 在C89标准里面,任何变量的定义必须放在可执行语句之前,也就是第8行应该放在第6行前面。 只有C99标准才会支持第8行的写法,但是编译器都是默认不支持C99,要打开相关的编译开关。 第一行说明楼主用的是C51而不是支持C99标准的MDK,C51至今依然不支持C99标准,所以楼主的代码根本不可能通过编译。 |
把unsigned int i=0;放到while(1)里面就可以循环左右移动了 |
tzs233 发表于 2022-7-6 15:23 1 再补充一点补码的知识,负数在计算机中会用补码来表示 负整数的补码计算是将其原码除符号位外的所有位 取反后加1,比如-1的补码为其绝对值1(0000 0001)->所有位取反(1111 11110) -> 加1(1111 1111)即255 2、接上一点,此时cnt=255 又满足了for循环中cnt>-1判定条件,因此它就会一一直循环下去无法退出。 3、然后循环体内(7-cnt) 也会产生负数,这样和你想要的结果会完全不同。如在cnt=255时 7- cnt=-248 补码 为0x08,即实际向右循环移动了8位之后变成0x80,外面又取反了一次变成 0x7f。 即P2 = 0x7f 4. 最后出现问题不要慌哈 可以借助编译器仿真调试设置断点、变量调试查看。都是这么过来的。 |
你的第二个循环cnt永远减不到-1,一直减,还是0,无法正常结束循环 |
for(cnt=8;cnt>0;cnt--) |
你的第二个for循环变量类型不对,定义unsigned char是无符号数,不能设定比较负数 |
问问楼主,这个程序修改后能循环了吗?我也是刚学,有好多的东西都一知半解的,不是很明白。 |
for循环中 -1溢出unsigned char 的范围 当cnt=0 时满足>-1 的条件 此时再减一次就变成255,emmm 后面的自然会出错。 |
hb_lhw 发表于 2022-7-6 09:48 我,很赞同。 |
xuyaqi 发表于 2022-7-6 11:28 正解! |
for(cnt=7;cnt>-1;cnt--)改为for(cnt=7;cnt>0;cnt--),unsigned char cnc 不可能是负数。 |
你的aa每次左移一位,左移完8次之后没有归 1,所以只能循环一次 |
cnt是unsigned char,永远大于-1,所以一直在for语句循环了。 |
把unsigned char cnt=0;改成char cnt=0; |
因为你移出去的数据,再也回不来了。你用环移指令试试? |
unsigned char cnt=0,应该在放在while(1) 循环上面 |