首页 上一页 1 2 下一页 尾页

寄存器加1方法 点击:1795 | 回复:22



猎隼

    
  • 精华:1帖
  • 求助:1帖
  • 帖子:151帖 | 1661回
  • 年度积分:0
  • 历史总积分:8983
  • 注册:2005年9月28日
发表于:2005-11-15 15:09:00
楼主
以下是我用keiluvision编的一个用P0.0口控制计数的小程序,但是运行后的问题就是当我将P0_0口置0时,变量a并未像我想像的那样只进行一次加1处理,而是不间断的循环执行,请各位高手帮我分析一下问题原因.谢谢.


#include<at89x51.h>
void main()
{
unsigned a;
do
{
if(!P0_0)
{
a++;
P0_0=1;
}
}
while(1);
}



周公

  • 精华:10帖
  • 求助:0帖
  • 帖子:119帖 | 5549回
  • 年度积分:0
  • 历史总积分:6446
  • 注册:2002年11月26日
发表于:2005-11-16 10:08:00
1楼
1. 如果变低一次只加一个数,应该检测到变低后[b]再检测变高[/b]作为一个计数值。
2. 如果是硬件开关要加防抖电路,或者延时一段时间如 10mS 消抖动。
另:P0_0作为输入应该在程序运初始即为 ‘1’,或者不设置、复位后自动为高。 

王晟磊

  • 精华:12帖
  • 求助:0帖
  • 帖子:70帖 | 687回
  • 年度积分:0
  • 历史总积分:1173
  • 注册:2004年2月11日
发表于:2005-11-16 19:35:00
2楼
1、po口是双向口,你要做输入用,请在前面初始化为输入,而不要在循环内重复的做。
2、你的变量a没有初始化,请在前面初始化。

studaybo

  • 精华:0帖
  • 求助:0帖
  • 帖子:5帖 | 34回
  • 年度积分:0
  • 历史总积分:49
  • 注册:2005年7月14日
发表于:2005-11-17 15:20:00
3楼
你既然用到do-while语句,你想运行一次就结束循环体,那么while(1)就又开始无限的循环下去,所以才无限的循环,你应该把while(0),这样才执行一次就结束循环体;
#include<at89x51.h>
void main()
{
unsigned a;
do
{
if(!P0_0)
{
a++;
P0_0=1;
}
}
while(0);
}

studaybo

  • 精华:0帖
  • 求助:0帖
  • 帖子:5帖 | 34回
  • 年度积分:0
  • 历史总积分:49
  • 注册:2005年7月14日
发表于:2005-11-17 15:29:00
4楼
do
{s;}
while(e);

do-while循环的执行流程是先执行循环体,在计算表达式e,然后判断它是否为非0,如果为非0,则返回重新执行循环体,否则结束循环。

你的程序while(1);说明是个死循环。改成while(0);就达到加一次就退出的目的。那样只进行一次加1处理。

猎隼

  • 精华:1帖
  • 求助:1帖
  • 帖子:151帖 | 1661回
  • 年度积分:0
  • 历史总积分:8983
  • 注册:2005年9月28日
发表于:2005-11-17 16:30:00
5楼
谢谢各位,我回去再好好研究研究,如果有问题还要麻烦各位。

猎隼

  • 精华:1帖
  • 求助:1帖
  • 帖子:151帖 | 1661回
  • 年度积分:0
  • 历史总积分:8983
  • 注册:2005年9月28日
发表于:2005-11-21 13:45:00
6楼
to:study波。
如果像你那样结束while循环“while(0)”,keil软件的调试运行就会出现一个错误,并退出运行状态。当我想要再加1的话就只能重新复位,并运行。这就达不到我想要计数的作用了,每次运行只能加到1,不能根据外围端口的触发,再进行计数操作了。

studaybo

  • 精华:0帖
  • 求助:0帖
  • 帖子:5帖 | 34回
  • 年度积分:0
  • 历史总积分:49
  • 注册:2005年7月14日
发表于:2005-11-22 10:32:00
7楼
To:苍鹰
  你的意思是计数处理呀;我没明白你的意思,对不起。现在有点明白了。那你用下面的程序试一试;
void main()
{
  unsigned a;
  do
  {
    if(P0_0 == 0)
    {
      a++;
      P0_0=1;
    }
//    else
//    {
//      a++;
//      P0_0 = 0;
//    }
  }
  while(1);
}

也许你用的if(!P0_0)不正确,因为你没做[color=#FF0000]初始化[/color],所以P0_0的状态不确定,当P0_0==0时可以做加1,但P0_0==1时,还是满足条件,所以又做加运算了。所以你加一个限定条件。

 如果不行的话 你在把你意思在说明白点。外部触发是当P0_0==0时加一次1,还是只要P0_0变化就计一次数。

studaybo

  • 精华:0帖
  • 求助:0帖
  • 帖子:5帖 | 34回
  • 年度积分:0
  • 历史总积分:49
  • 注册:2005年7月14日
发表于:2005-11-22 11:33:00
8楼
void main()
{
  unsigned a;
  do
  {
    if(!P0_0)
    {
      a++;
      P0_0=1;
    }

  }
  while(P0_0 == 0);//有效 继续执行循环体
}

你可以在循环体上加判断,你自己根据你的情况在试。综合一下。看那种满足你的要求。

猎隼

  • 精华:1帖
  • 求助:1帖
  • 帖子:151帖 | 1661回
  • 年度积分:0
  • 历史总积分:8983
  • 注册:2005年9月28日
发表于:2005-11-22 12:40:00
9楼
我的想法就是想做一个计数器,当外部有一次触发,我的单片机内的变量就进行一次加一,不能按一次按钮加很多的数.

猎隼

  • 精华:1帖
  • 求助:1帖
  • 帖子:151帖 | 1661回
  • 年度积分:0
  • 历史总积分:8983
  • 注册:2005年9月28日
发表于:2005-11-23 10:27:00
10楼
TO:Study波
void main()
{
  unsigned a;
  do
  {
    if(!P0_0)
    {
      a++;
      P0_0=1;
    }

  }
  while(P0_0 == 0);
}
运行监控程序后,当将P0_0端口置0后,就会出现以下的错误提示,并退出运行状态.
error 65:access Violation at C:0xA98F:no'execute/read'permission

studaybo

  • 精华:0帖
  • 求助:0帖
  • 帖子:5帖 | 34回
  • 年度积分:0
  • 历史总积分:49
  • 注册:2005年7月14日
发表于:2005-11-23 10:57:00
11楼
哦  那你用这个试试
void main()
{
  unsigned a = 0;
  P0_0 = 1; // 没按下按钮时为1  
  for(;;)   // 循环判断
  {   
     // 如果不行的话在[color=#FF0000]这[/color]加个延时 最好 1ms for(int i = 0; i < 1000; i++)

   if(P0_0 == 0)// 按下时 P0_0 = 0
   {   
    // 如果不行的话在[color=#FF0000]这[/color]加个延时 最好 1ms for(int i = 0; i < 1000; i++)

     if(P0_0 == 1)// 松开时 P0_0 = 1
     {
       a++;       // 松开时加1
     }
   }
  }
}
这样当没按下时,P0=1,然后进入循环判断,当按下时P0=0;进入if语句,当松开时P0=1;进入if2语句,这时再计数;但可能要加个延时,最好是1ms。因为当按下键时,CPU的速度很快,它不一定循环多少次,所以如果不行的话,加延时for(int i = 0; i < 1000; i++).如果硬件有去除抖动等一些干扰,也可以不加。但不一定好用。你再试试吧。

studaybo

  • 精华:0帖
  • 求助:0帖
  • 帖子:5帖 | 34回
  • 年度积分:0
  • 历史总积分:49
  • 注册:2005年7月14日
发表于:2005-11-24 11:19:00
12楼
怎样了  好用吗?

猎隼

  • 精华:1帖
  • 求助:1帖
  • 帖子:151帖 | 1661回
  • 年度积分:0
  • 历史总积分:8983
  • 注册:2005年9月28日
发表于:2005-11-24 12:41:00
13楼
好用,但是我在使用之前进行了一些修改,要不然还是有错误。
DO WHILE 进行了修改。
我正在一步步的完善我的计数器,目标是实现可以达到4位显示,且带有断电记忆功能。

studaybo

  • 精华:0帖
  • 求助:0帖
  • 帖子:5帖 | 34回
  • 年度积分:0
  • 历史总积分:49
  • 注册:2005年7月14日
发表于:2005-11-24 16:28:00
14楼
那 恭喜你呀!
  迈进了成功的第一步;以后会越走越好的;加油吧!!!
  对了,给你改过的代码发给我行吗!我看看。因为我以前没做过计数器。
谢谢了!

猎隼

  • 精华:1帖
  • 求助:1帖
  • 帖子:151帖 | 1661回
  • 年度积分:0
  • 历史总积分:8983
  • 注册:2005年9月28日
发表于:2005-11-25 13:12:00
15楼
void main()
{
  unsigned a = 0;
int i;  
P0_0 = 1;  
do  
{     
   if(P0_0 == 0)
   {   
  for(i=0;i<100;i++)     
     if(P0_0 == 1)
     {
       a++;       
     }
   }
  }
while(1);

我把循环时间缩小了,因为这是我不是我的电脑在上网,我背下来的,可能有不对的地方.

studaybo

  • 精华:0帖
  • 求助:0帖
  • 帖子:5帖 | 34回
  • 年度积分:0
  • 历史总积分:49
  • 注册:2005年7月14日
发表于:2005-11-25 15:13:00
16楼

  好了我看到了,你为什么不用for循环呀,毕竟do-while不常用。
只是建议,你根据你的情况再说吧。
 GoodLuck!!!!!!!!!!!!!!!

studaybo

  • 精华:0帖
  • 求助:0帖
  • 帖子:5帖 | 34回
  • 年度积分:0
  • 历史总积分:49
  • 注册:2005年7月14日
发表于:2005-11-25 15:13:00
17楼

  好了我看到了,你为什么不用for循环呀,毕竟do-while不常用。
只是建议,你根据你的情况再说吧。
 GoodLuck!!!!!!!!!!!!!!!

猎隼

  • 精华:1帖
  • 求助:1帖
  • 帖子:151帖 | 1661回
  • 年度积分:0
  • 历史总积分:8983
  • 注册:2005年9月28日
发表于:2005-11-25 16:24:00
18楼
我现在在考虑类似断电保持的功能,想通过单片机的I/O口将断电后的数字信号储存到一块特定的FLASHROM或EEPROM芯片内,或通过串行通信口将数字信号储存到串行存储器上,以达到断电保持的功能.然后每次上电的时候首先读取这块特定的存储芯片,以达到设定初始计数值的目的.
其设想原理为通过单片机上的3个I/O口对存储芯片进行地址选择,然后再通过单片机上的一个8位的端口,当作数据端口,每次传输一位字节.
这种想法是否可行.

周公

  • 精华:10帖
  • 求助:0帖
  • 帖子:119帖 | 5549回
  • 年度积分:0
  • 历史总积分:6446
  • 注册:2002年11月26日
发表于:2005-11-25 17:38:00
19楼
数据多少?时间要求?

猎隼

  • 精华:1帖
  • 求助:1帖
  • 帖子:151帖 | 1661回
  • 年度积分:0
  • 历史总积分:8983
  • 注册:2005年9月28日
发表于:2005-11-29 12:40:00
20楼
只要不大于9999就行,双向计数,5KHz.

热门招聘
相关主题

官方公众号

智造工程师
    首页 上一页 1 2 下一页 尾页