找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2409|回复: 16
收起左侧

C语言_crol_()函数不能实现循环移位

[复制链接]
ID:901999 发表于 2021-4-7 18:16 | 显示全部楼层 |阅读模式
总程序
2.png
问题
3.png
在每次执行后P0的值变化:0xFE 0xFD 0xF9 0xF1 0xE1 0xC1 0x81 0x01 0x00 之后就一直是0x00
求解。
回复

使用道具 举报

ID:390416 发表于 2021-4-7 19:08 | 显示全部楼层
循环之前是先读一次IO口状态,然后再移位的。假设你外围拉低或者拉高了 结果就变了。
这个细节问题,只有人人学会单片机 这个视频教程讲过。其他老师录制的都没讲
回复

使用道具 举报

ID:675856 发表于 2021-4-7 19:10 | 显示全部楼层
程序中断都没开
回复

使用道具 举报

ID:384475 发表于 2021-4-8 00:17 | 显示全部楼层
都移为0了,再移不也是0吗?加上if(P0==0){P0=0xfe;} 或者加一个移位计数,移到8次后重新赋值P0=0xfe

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:901999 发表于 2021-4-8 10:13 来自手机 | 显示全部楼层
707794433 发表于 2021-4-7 19:10
程序中断都没开

我配置了IE呀
回复

使用道具 举报

ID:901999 发表于 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)呀
回复

使用道具 举报

ID:901999 发表于 2021-4-8 10:38 来自手机 | 显示全部楼层
人人学会单片机 发表于 2021-4-7 19:08
循环之前是先读一次IO口状态,然后再移位的。假设你外围拉低或者拉高了 结果就变了。
这个细节问题,只有 ...

啥意思
回复

使用道具 举报

ID:894154 发表于 2021-4-8 13:52 | 显示全部楼层
if(P0==0X00)
{P0=0Xff;}
回复

使用道具 举报

ID:901999 发表于 2021-4-8 17:45 | 显示全部楼层
ANT1987 发表于 2021-4-8 13:52
if(P0==0X00)
{P0=0Xff;}

关键他每次移位后的值不对呀,0xfd(11111101)之后应该是fb(11111011)呀
回复

使用道具 举报

ID:814525 发表于 2021-4-8 18:51 | 显示全部楼层
貌似P0.1口被外部拉低或损坏了造成的
回复

使用道具 举报

ID:384475 发表于 2021-4-9 00:39 | 显示全部楼层
mjalk 发表于 2021-4-8 10:15
关键他每次移位后的值不对呀,0xfd(11111101)之后应该是fb(11111011)呀

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

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:213173 发表于 2021-4-9 07:37 | 显示全部楼层

这不是软件问题,是硬件条件导致的错误。当_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. }
复制代码
回复

使用道具 举报

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

使用道具 举报

ID:384475 发表于 2021-4-9 10:17 | 显示全部楼层
a4732710 发表于 2021-4-9 08:06
地板楼层和11楼都是答非所问。
变量=_crol_(变量名,移动位数),例如:P0=_crol_(P0,1); 这是循环左移, ...

学习了,以为楼主是<<,
回复

使用道具 举报

ID:901999 发表于 2021-4-10 12:10 | 显示全部楼层
wulin 发表于 2021-4-9 07:37
这不是软件问题,是硬件条件导致的错误。当_crol_()函数对P0执行循环左移时要先读P0口当前状态。由于51单 ...

解决了,感谢。
回复

使用道具 举报

ID:901999 发表于 2021-4-10 12:11 | 显示全部楼层
a4732710 发表于 2021-4-9 08:06
地板楼层和11楼都是答非所问。
变量=_crol_(变量名,移动位数),例如:P0=_crol_(P0,1); 这是循环左移, ...

了解了,感谢。
回复

使用道具 举报

ID:808223 发表于 2021-4-10 18:31 | 显示全部楼层
我看半天就纳闷,没啥问题啊,他们答得都是啥。。循环移动用的没有问题,问题原来出在没有上拉P0.。。。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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