标题: C语言_crol_()函数不能实现循环移位 [打印本页]

作者: mjalk    时间: 2021-4-7 18:16
标题: C语言_crol_()函数不能实现循环移位
总程序

问题

在每次执行后P0的值变化:0xFE 0xFD 0xF9 0xF1 0xE1 0xC1 0x81 0x01 0x00 之后就一直是0x00
求解。

作者: 人人学会单片机    时间: 2021-4-7 19:08
循环之前是先读一次IO口状态,然后再移位的。假设你外围拉低或者拉高了 结果就变了。
这个细节问题,只有人人学会单片机 这个视频教程讲过。其他老师录制的都没讲
作者: 707794433    时间: 2021-4-7 19:10
程序中断都没开
作者: jjkk11    时间: 2021-4-8 00:17
都移为0了,再移不也是0吗?加上if(P0==0){P0=0xfe;} 或者加一个移位计数,移到8次后重新赋值P0=0xfe
作者: mjalk    时间: 2021-4-8 10:13
707794433 发表于 2021-4-7 19:10
程序中断都没开

我配置了IE呀
作者: mjalk    时间: 2021-4-8 10:15
jjkk11 发表于 2021-4-8 00:17
都移为0了,再移不也是0吗?加上if(P0==0){P0=0xfe;} 或者加一个移位计数,移到8次后重新赋值P0=0xfe

关键他每次移位后的值不对呀,0xfd(11111101)之后应该是fb(11111011)呀
作者: mjalk    时间: 2021-4-8 10:38
人人学会单片机 发表于 2021-4-7 19:08
循环之前是先读一次IO口状态,然后再移位的。假设你外围拉低或者拉高了 结果就变了。
这个细节问题,只有 ...

啥意思
作者: ANT1987    时间: 2021-4-8 13:52
if(P0==0X00)
{P0=0Xff;}
作者: mjalk    时间: 2021-4-8 17:45
ANT1987 发表于 2021-4-8 13:52
if(P0==0X00)
{P0=0Xff;}

关键他每次移位后的值不对呀,0xfd(11111101)之后应该是fb(11111011)呀
作者: 张天师    时间: 2021-4-8 18:51
貌似P0.1口被外部拉低或损坏了造成的
作者: jjkk11    时间: 2021-4-9 00:39
mjalk 发表于 2021-4-8 10:15
关键他每次移位后的值不对呀,0xfd(11111101)之后应该是fb(11111011)呀

在c++中,移位运算符有双目移位运算符:<<(左移)和>>(右移)。移位运算符组成的表达式也属于算术表达式,其值为算术值。左移运算是将一个二进制位的操作数按指定移动的位数向左移位,移出位被丢弃,右边的空位一律补0。右移运算是将一个二进制位的操作数按指定移动的位数向右移动,移出位被丢弃,左边移出的空位或者一律补0,或者补符号位,这由不同的机器而定。在使用补码作为机器数的机器中,正数的符号位为0,负数的符号位为1。
作者: wulin    时间: 2021-4-9 07:37
mjalk 发表于 2021-4-8 10:38
啥意思

这不是软件问题,是硬件条件导致的错误。当_crol_()函数对P0执行循环左移时要先读P0口当前状态。由于51单片机P0为开漏模式,虽然设置P0=0xfe;,但P0端口在没有外部高电平条件下呈现的是低电平0x00。所以对0x00循环左移得不到预想结果。楼主可以改用其它端口测试或在P0加上拉电阻就不会出错。也可以用一个中间变量缓冲解决问题:
  1. #include <reg51.H>
  2. #include <intrins.h>

  3. unsigned char T_count;
  4. unsigned char num;

  5. void main()       
  6. {                                                                       
  7.         num=0xfe;
  8.         P0=num;
  9.         TMOD=0x01;
  10.         TH0=15536/256;
  11.         TL0=15536%256;
  12.         IE=0x82;
  13.         TR0=1;
  14.         while(1);
  15. }
  16. void TIME0() interrupt 1
  17. {
  18.         TH0=15536/256;
  19.         TL0=15536%256;
  20.         if(++T_count==20)
  21.         {
  22.                 num=_crol_(num,1);
  23.                 P0=num;
  24.                 T_count=0;
  25.         }
  26. }
复制代码

作者: a4732710    时间: 2021-4-9 08:06
地板楼层和11楼都是答非所问。
变量=_crol_(变量名,移动位数),例如:P0=_crol_(P0,1); 这是循环左移,而_cror_则是循环右移,与_crol_用法相同。
<<是左移,最高位移出去了就丢弃,最低位补0,而 _crol_则是循环左移,最高位移出去后不丢弃,而是补到最低位,也就是说,最低位不补0
楼主问的就是_crol_问题。程序延时没问题的话,应该是P0口上拉电阻或电压被干扰问题
作者: jjkk11    时间: 2021-4-9 10:17
a4732710 发表于 2021-4-9 08:06
地板楼层和11楼都是答非所问。
变量=_crol_(变量名,移动位数),例如:P0=_crol_(P0,1); 这是循环左移, ...

学习了,以为楼主是<<,
作者: mjalk    时间: 2021-4-10 12:10
wulin 发表于 2021-4-9 07:37
这不是软件问题,是硬件条件导致的错误。当_crol_()函数对P0执行循环左移时要先读P0口当前状态。由于51单 ...

解决了,感谢。
作者: mjalk    时间: 2021-4-10 12:11
a4732710 发表于 2021-4-9 08:06
地板楼层和11楼都是答非所问。
变量=_crol_(变量名,移动位数),例如:P0=_crol_(P0,1); 这是循环左移, ...

了解了,感谢。
作者: Secret丶    时间: 2021-4-10 18:31
我看半天就纳闷,没啥问题啊,他们答得都是啥。。循环移动用的没有问题,问题原来出在没有上拉P0.。。。




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1