发新帖我要提问
12
返回列表
打印

急!!!谁帮我写个表达式?

[复制链接]
楼主: datouyuan
手机看帖
扫描二维码
随时随地手机跟帖
21
icmap| | 2009-10-19 22:59 | 只看该作者 回帖奖励 |倒序浏览
目前为止只有香版主提出了一个有效的方法。
大家还有没有更好的办法?不用分支和循环,仅仅用逻辑运算是否也能够解决此问题?
我认为这个问题很有代表性,在单片机软件开发中肯定会遇到类似的逻辑问题。
建议大家也来试解决一下。

使用特权

评论回复
22
hou| | 2009-10-19 23:30 | 只看该作者
本帖最后由 hou 于 2009-10-19 23:32 编辑

void abc()
{
  uint8 P1_changed_now;   //记录两次采样周期中P1各位的变化
  uint8 P1_changed_sum;   //记录P1变化的历史信息,曾经变化的位(无论次数)
  uint8 P1_changed_multi; //记录P1变化的历史信息,发生多次变化的位

  uint8 P1_old;
  uint8 P1_new;
  uint8 i=0;

  P1=1;//读引脚
  P1_old = P1;
  while (i<100)
  {
    P1=1;
    P1_new = P1;
    P1_changed_now   =  P1_new ^ P1_old;//记录相邻两次采样P1变化的位
    P1_changed_multi |= P1_changed_sum & P1_changed_now;//曾经变化过的且当前又变化过的位,记录下来;
    P1_changed_sum   |= P1_changed_now;
    P1_old = P1_new;
    i++;
    delay10ms();
  }
  P2 = P1_changed_sum ^ P1changed_multi; //曾经变化过的位中,减去多次变化的位
}
例:以4位为例
采样次数  P1   changed_now  changed_sum   changed_multi
---------------------------------------------------------
  0    1001       0000         0000        0000
---------------------------------------------------------
  1    1010       0011         0011        0000
---------------------------------------------------------
  2    1111       0101         0111        0001
---------------------------------------------------------
  3    1101       0010         0111        0011
---------------------------------------------------------
到此为止,有低三位发生变化,其中低两位曾多次变化;则可判定次高位应点亮。

使用特权

评论回复
23
香水城| | 2009-10-20 09:01 | 只看该作者
16楼解说得很清楚,代码也写出来了
我挑点骨头,加上后面的&运算,可以在次数很多时防止溢出
lxyppc 发表于 2009-10-19 22:47


不能增加这个&运算。

比如变化次数为17时,计算结果将变为1,会产生误判!

使用特权

评论回复
24
lxyppc| | 2009-10-20 09:09 | 只看该作者
不能增加这个&运算。

比如变化次数为17时,计算结果将变为1,会产生误判!
香水城 发表于 2009-10-20 09:01


的确如此,误人子弟了,这样只会更快的溢出
修改一下,改成判断大小

使用特权

评论回复
25
datouyuan|  楼主 | 2009-10-20 09:46 | 只看该作者
22# hou

22楼的大侠,谢谢了!!!!!

使用特权

评论回复
26
icmap| | 2009-10-20 14:49 | 只看该作者
22楼是高手,这样的答案很完美。

使用特权

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

本版积分规则