打印

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

[复制链接]
4978|25
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
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楼已经吧问题说清楚了。帮顶。

使用特权

评论回复
5
icmap| | 2009-10-19 17:24 | 只看该作者
考验解决问题的能力的时候到了。能独自解决此问题,说明不愧作这一行。

使用特权

评论回复
6
ZRL700424| | 2009-10-19 17:28 | 只看该作者
每隔20mS执行1次

你这个程序运行时间都大于1S了,你怎么做到20MS执行一次?

使用特权

评论回复
7
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;
}

使用特权

评论回复
8
gaohq| | 2009-10-19 18:31 | 只看该作者
参考奇偶校验法,P1_new (检测到得值,1或者0);
P1_TEMP=0,
P1_TEMP+=P1_new;
IF(PI_TEMP/2);
{
   p2亮;
}

使用特权

评论回复
9
badbird1234| | 2009-10-19 20:09 | 只看该作者
相加等于99
或等于1
点亮

使用特权

评论回复
10
4366477| | 2009-10-19 21:04 | 只看该作者
期待高手

使用特权

评论回复
11
4366477| | 2009-10-19 21:10 | 只看该作者
按照你给出程序架构编出来的程序是肯定有问题的

使用特权

评论回复
12
datouyuan|  楼主 | 2009-10-19 21:13 | 只看该作者
我这问题看起来非常简单,可我画了下识别一个位(有且只有1次电平变化)的流程图,感觉很麻烦。

请高手帮忙想想,就当是脑力游戏。

使用特权

评论回复
13
4366477| | 2009-10-19 21:19 | 只看该作者
在delay10mS();延时时间中,比如:P1原来是0x01变化N次后,第N次变成0x01。这样在你的程序中就认为delay10mS();过程中P1是没有变化的。

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

void abc()
{
  {....} // 开始1S定时
  
  while{![1s时间到]}
  {
    {.....}  // 实际程序
  }
  P2 = 结果;
}

使用特权

评论回复
14
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每个位变化了偶数次。

      我说过了,不要考虑其它。只要把“有且只有一次变化识别出来”这个算法搞出来就可以了。

使用特权

评论回复
15
icmap| | 2009-10-19 22:09 | 只看该作者
用不着流程图,纯粹就是逻辑运算,4个表达式就够了。

使用特权

评论回复
16
香水城| | 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次采样中每个比特位的电平变化次数。

使用特权

评论回复
17
awmc_m| | 2009-10-19 22:20 | 只看该作者
本次与上次的值进行异或即可知道哪些位改变,然后p2口直接等于异或后的值,相应的灯就亮了。

使用特权

评论回复
18
qiuming| | 2009-10-19 22:25 | 只看该作者
只有有变化就亮了。

使用特权

评论回复
19
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,修改

使用特权

评论回复
20
datouyuan|  楼主 | 2009-10-19 22:49 | 只看该作者
本帖最后由 datouyuan 于 2009-10-19 23:00 编辑

16# 香水城

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

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

非常谢谢!!!!!

使用特权

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

本版积分规则

个人签名:maowenyuan@126.com

31

主题

1083

帖子

9

粉丝