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

[复制链接]
 楼主| datouyuan 发表于 2009-10-19 14:05 | 显示全部楼层 |阅读模式
本帖最后由 datouyuan 于 2009-10-20 09:52 编辑

我有段程序是定时执行,把我搞懵了,谁能帮帮我?

我把问题简化一下:假如P1口相应位在1S内有电平变化(不要考虑尖刺),并且只有一次,P2相应位的指示灯亮,这样是否好理解?

我要的效果是:
假如P10在n次里有并且只有一次电平变化,P20指示灯亮。
假如P11在n次里有并且只有一次电平变化,P21指示灯亮。
~

void abc()
{
uint8 i;
uint8 P1_temp; //P1此次电平,输入
uint8 P1_Old; //P1上次电平  输入
uint8 SignalOK; //假如P1相应位有且只有1次电平变化,相应位置1,否则为0.
for(i=0;i<100;i++)
{
  P1_temp=P1;
  //{请帮我在这里写出表达式,可以用临时变量}
  
  
  P1_Old=P1_temp;
  delay10mS();
}
P2=SignalOK;
}

我就需要这个表达式或算法(有并且只有一次变化),不要考虑其它问题。就是多用几个临时变量也没关系。

或者这么说:
有N(就算100吧)个8bit数据Data[100],从Data[0]开始判断,N次结束判断,假如后一个的数据和前一个的数据相比,相应位有变化并且只变化1次,Out的相应位置1,否则为0。
请把这算法搞出来。

非常谢谢大家的帮助!!!!
22楼和16楼的帖子已经解决了。
 楼主| datouyuan 发表于 2009-10-19 15:40 | 显示全部楼层
今天这个“位运算”搞得我头昏昏沉沉的,实在是没办法,请大侠帮我想想这个表达式。

谢谢了。
 楼主| datouyuan 发表于 2009-10-19 16:53 | 显示全部楼层
是不是没说清楚,大侠们不愿意解答。

我要的效果是:
假如P10在100次检查里有并且只有一次电平变化,P20指示灯亮。
假如P11在100次检查里有并且只有一次电平变化,P21指示灯亮。
假如P12在100次检查里有并且只有一次电平变化,P22指示灯亮。
~类推
icmap 发表于 2009-10-19 17:18 | 显示全部楼层
3楼已经吧问题说清楚了。帮顶。
icmap 发表于 2009-10-19 17:24 | 显示全部楼层
考验解决问题的能力的时候到了。能独自解决此问题,说明不愧作这一行。
ZRL700424 发表于 2009-10-19 17:28 | 显示全部楼层
每隔20mS执行1次

你这个程序运行时间都大于1S了,你怎么做到20MS执行一次?
 楼主| datouyuan 发表于 2009-10-19 17:35 | 显示全部楼层
别的什么问题都不需要考虑,我只要这个“有并且只有1次”的表达式,用多少临时变量都没关系,我估计也用不了多少临时变量。

我只需要的效果是:
假如P10在100次检查里有并且只有一次电平变化,P20指示灯亮。
假如P11在100次检查里有并且只有一次电平变化,P21指示灯亮。
假如P12在100次检查里有并且只有一次电平变化,P22指示灯亮。
~类推

void abc()
{
uint8 i;
uint8 P1_temp; //P1此次电平,输入
uint8 P1_Old; //P1上次电平  输入
uint8 SignalOK; //假如P1相应位有且只有1次电平变化,相应位置1,否则为0.
for(i=0;i<100;i++)
{
  P1_temp=P1;
  //{请帮我在这里写出表达式,可以用临时变量}
  
  
  P1_Old=P1_temp;
  delay();
}
P2=SignalOK;
}
gaohq 发表于 2009-10-19 18:31 | 显示全部楼层
参考奇偶校验法,P1_new (检测到得值,1或者0);
P1_TEMP=0,
P1_TEMP+=P1_new;
IF(PI_TEMP/2);
{
   p2亮;
}
badbird1234 发表于 2009-10-19 20:09 | 显示全部楼层
相加等于99
或等于1
点亮
4366477 发表于 2009-10-19 21:04 | 显示全部楼层
期待高手
4366477 发表于 2009-10-19 21:10 | 显示全部楼层
按照你给出程序架构编出来的程序是肯定有问题的
 楼主| datouyuan 发表于 2009-10-19 21:13 | 显示全部楼层
我这问题看起来非常简单,可我画了下识别一个位(有且只有1次电平变化)的流程图,感觉很麻烦。

请高手帮忙想想,就当是脑力游戏。
4366477 发表于 2009-10-19 21:19 | 显示全部楼层
在delay10mS();延时时间中,比如:P1原来是0x01变化N次后,第N次变成0x01。这样在你的程序中就认为delay10mS();过程中P1是没有变化的。

你这里肯定要一个定时器来定时器的

void abc()
{
  {....} // 开始1S定时
  
  while{![1s时间到]}
  {
    {.....}  // 实际程序
  }
  P2 = 结果;
}
 楼主| datouyuan 发表于 2009-10-19 21:42 | 显示全部楼层
本帖最后由 datouyuan 于 2009-10-19 21:43 编辑
在delay10mS();延时时间中,比如:P1原来是0x01变化N次后,第N次变成0x01。这样在你的程序中就认为delay10mS();过程中P1是没有变化的。


4366477 发表于 2009-10-19 21:19


      假定在延时和下一次延时的开始(或结束)都检测到P1是0x01,可以认为P1的任何位没有变化。
      不过在n(>1)次延时后,P1还是0x01的话,P2上所有位灯不亮,不过不一定代表P1这期间没变化,有可能P1每个位变化了偶数次。

      我说过了,不要考虑其它。只要把“有且只有一次变化识别出来”这个算法搞出来就可以了。
icmap 发表于 2009-10-19 22:09 | 显示全部楼层
用不着流程图,纯粹就是逻辑运算,4个表达式就够了。
香水城 发表于 2009-10-19 22:18 | 显示全部楼层
本帖最后由 香水城 于 2009-10-19 22:29 编辑

这个算法很简单:有且只有1次电平变化,只需要把所有变化加起来就可以了:

先把这次读出的数值与上次读出的数值做“异或”运算,结果为'1'则表示有变化,结果为'0'表示没有变化。

uint8 P1_temp;
uint8 P1_Old;
uint8 P1_Change; // 本次采样与上次对比
uint8 P1_Changes[8]; // 累加每个位的变化
P1_Old = 0; // 初始化为0
for (i=0; i<8; i++) P1_Changes=0; // 初始化变化值为0

for(i=0; i<100; i++) {
  P1_temp=P1;
  P1_Change = P1_temp ^ P1_Old;  // P1_Change中哪位为'1'表示本次采样电平有变化
  P1_Old = P1_temp;
  if (P1_Change & 0x01) // 判断位0电平是否有变化
      P1_Changes[0]++;
  if (P1_Change & 0x02) // 判断位1电平是否有变化
      P1_Changes[1]++;
  ......
  if (P1_Change & 0x80) // 判断位7电平是否有变化
      P1_Changes[7]++;

// 以下自己完成吧!
}

最后P1_Changes[]中记录了100次采样中每个比特位的电平变化次数。
awmc_m 发表于 2009-10-19 22:20 | 显示全部楼层
本次与上次的值进行异或即可知道哪些位改变,然后p2口直接等于异或后的值,相应的灯就亮了。
qiuming 发表于 2009-10-19 22:25 | 显示全部楼层
只有有变化就亮了。
lxyppc 发表于 2009-10-19 22:47 | 显示全部楼层
本帖最后由 lxyppc 于 2009-10-20 09:12 编辑

16楼解说得很清楚,代码也写出来了
我挑点骨头,加上后面的&运算,可以在次数很多时防止溢出
for(i=0; i<100; i++) {
  P1_temp=P1;
  P1_Change = P1_temp ^ P1_Old;  // P1_Change中哪位为'1'表示本次采样电平有变化
  P1_Old = P1_temp;
  if (P1_Change & 0x01) // 判断位0电平是否有变化
      if(P1_Changes[0])<0xf{P1_Changes[0]++};
  if (P1_Change & 0x02) // 判断位1电平是否有变化
      if(P1_Changes[1])<0xf{P1_Changes[1]++};
  ......
  if (P1_Change & 0x80) // 判断位7电平是否有变化
      if(P1_Changes[7])<0xf{P1_Changes[7]++};

// 以下自己完成吧!
}

运行完成后,P1_Changes里面包含了端口改变的次数

23楼香版找出一个大bug,修改
 楼主| datouyuan 发表于 2009-10-19 22:49 | 显示全部楼层
本帖最后由 datouyuan 于 2009-10-19 23:00 编辑

16# 香水城

16楼的程序是正确的,只是P1Old不能初始化为0,应该为P1。

我总盯着“只有一次”,总以为会有个很简单的算法,反而没搞出了。

非常谢谢!!!!!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:maowenyuan@126.com

31

主题

1088

帖子

9

粉丝
快速回复 在线客服 返回列表 返回顶部