找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1270|回复: 15
收起左侧

单片机一键启停程序,请大神看一下哪里出错了?

[复制链接]
ID:999123 发表于 2022-2-6 19:45 | 显示全部楼层 |阅读模式
单片机启停程序,设想是:按一下启动,再按停止。现在是通电后喇叭响,按一下就停了,再按没反应。大家看一下哪里有错误,找不出来了。

             #include"reg52.h"
        #define uchar unsigned char
        #define uint unsigned int
        sbit pp=P1^5;
         bit  flag=1;
        void delay(uint x)
        {
                uint i, j;
             for(i=x;i>0;i--)
                         for(j=0;j>0;j--);          


         }

                  void main()
          {         
          
           IT0=0;
                  EX1=1;
                  EA=1;
          
                   while(flag)
          {
          pp=~pp;
          
                   delay(10);
           }

        }         
                void int1_serv() interrupt 2

                {
                            delay(10);
                          if(P3^3==0)
                           {
                                flag=~flag;
                           }

         while(P3^3==1);

                }


                 
         

回复

使用道具 举报

ID:743654 发表于 2022-2-8 09:11 | 显示全部楼层

延时函数有问题,时间太短了,第一个for循环只执行一次
    void delay(uint x)
        {
             uint i, j;
             for(i=x;i>0;i--)
                  for(j=0;j>0;j--); //这句根本就不执行         
         }
回复

使用道具 举报

ID:161164 发表于 2022-2-8 10:39 | 显示全部楼层
1。main内的主while一定是while(1)
2。中断内不要用delay
3。一键启停请用下降沿触发,IT1 = 1;

  1. #include"reg52.h"
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. sbit pp=P1^5;
  5. bit  flag=1, flag_Swap;
  6. uint delay_cnt = 0;
  7. void delay(uint x)
  8. {
  9.         uint i, j;
  10.         for(i=x; i>0; i--)
  11.                 for(j=0; j>0; j--);
  12. }
  13. void main()
  14. {
  15.         IT1=1;
  16.         EX1=1;
  17.         EA=1;
  18.         while(1)
  19.         {
  20.                 if(flag)
  21.                 {
  22.                         pp=~pp;
  23.                 }       
  24.                 if(flag_Swap)
  25.                 {
  26.                         if(delay_cnt == 0)flag=~flag;
  27.                         if(++delay_cnt > 1000)//消抖
  28.                         {
  29.                                 delay_cnt = 0;
  30.                                 flag_Swap = 0;
  31.                         }
  32.                 }
  33.                 delay(10);
  34.         }
  35. }
  36. void int1_serv() interrupt 2
  37. {
  38.         flag_Swap = 1;
  39. }
复制代码
回复

使用道具 举报

ID:1004367 发表于 2022-2-8 12:23 | 显示全部楼层
单片机用什么语言写的呀
回复

使用道具 举报

ID:999123 发表于 2022-2-8 12:24 | 显示全部楼层
lkc8210 发表于 2022-2-8 10:39
1。main内的主while一定是while(1)
2。中断内不要用delay
3。一键启停请用下降沿触发,IT1 = 1;

太感谢了。
回复

使用道具 举报

ID:999123 发表于 2022-2-8 18:30 | 显示全部楼层
已经解决了,不过不是很理想,外中断程序里不能延时去抖动,造成按键仍然有一定的几率出错。
回复

使用道具 举报

ID:999123 发表于 2022-2-8 18:40 | 显示全部楼层
已经解决问题了,但是不理想,延时去抖不能用在中断程序里,造成按键不可靠,进入中断后关掉中断效果也不好。大家有什么好办法吗?


                             #include"reg52.h"
#define uchar unsigned char
#define uint unsigned int
sbit pp=P1^5;          sbit k8=P3^3;
bit  flag=1, flag1;
uint delay_cnt = 0;
void delay(uint x)
        {
        uint i, j;
        for(i=x; i>0; i--)
                for(j=0; j>0; j--);
        }
                        void main()
        {
        IT1=1;
        EX1=1;
        EA=0;
        while(1)
        {        if(flag==1)
               
                {
                        pp=~pp;
                                                delay(10);
                }  
                               
                        if(k8==0)
                          {         delay(10);
                                  if(k8==0);
                                     
                if(flag1==1)
                {
                   flag=~flag;
                                  
                                   flag1=0;
                                }       
                                       
                  
                                  EA=1;
                                }
               
        }
}
void int1_serv() interrupt 2
{                 EA=0;
        flag1 = 1;
}
                           
回复

使用道具 举报

ID:161164 发表于 2022-2-9 08:03 | 显示全部楼层
廖振基 发表于 2022-2-8 18:40
已经解决问题了,但是不理想,延时去抖不能用在中断程序里,造成按键不可靠,进入中断后关掉中断效果也不好 ...

请参考我的消抖方法~
其实你这种情况完全没必要用中断
回复

使用道具 举报

ID:999123 发表于 2022-2-9 13:49 | 显示全部楼层
谢谢指点,用中断主要是考虑到,:如果程序有较长时间的循环等待时,非中断暂停键就不会快速响应,当然,这个程序例可以不需要。
回复

使用道具 举报

ID:213173 发表于 2022-2-9 15:43 | 显示全部楼层
廖振基 发表于 2022-2-8 18:40
已经解决问题了,但是不理想,延时去抖不能用在中断程序里,造成按键不可靠,进入中断后关掉中断效果也不好 ...

简单的问题不要用复杂的方法解决
  1. #include"reg52.h"
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. sbit pp=P1^5;
  5. sbit k8=P3^3;
  6. bit  flag=0;
  7. uint delay_cnt=0;
  8. /*
  9. void delay(uint x)
  10. {
  11.         uint i, j;
  12.         for(i=x; i>0; i--)
  13.                 for(j=0; j>0; j--);
  14. }*/
  15. void main()
  16. {
  17. //        IT1=1;
  18. //        EX1=1;
  19. //        EA=0;
  20.         while(1)
  21.         {
  22. //                if(flag==1)
  23. //                {
  24. //                        pp=~pp;
  25. //                        delay(10);
  26. //                }  
  27.                 if(k8==0)
  28.                 {
  29. //                        delay(10);
  30. //                        if(k8==0);
  31.                         if(++delay_cnt>=500 && flag==0)
  32.                         {
  33.                                 flag=1;
  34.                                 pp=~pp;
  35.                         }        
  36. //                        EA=1;
  37.                 }
  38.                 else
  39.                 {
  40.                         flag=0;
  41.                         delay_cnt=0;
  42.                 }
  43.         }
  44. }
  45. /*
  46. void int1_serv() interrupt 2
  47. {
  48.         EA=0;
  49.         flag1=1;
  50. }*/
复制代码
回复

使用道具 举报

ID:999123 发表于 2022-2-10 16:29 | 显示全部楼层
非常感谢回答,将程序下载单片机后,喇叭不响,自己稍微改动一下,仍然不响,可是按照程序推理应该可以运行的。确定硬件没有问题,更换以前程序可以响的,只是不可靠。

                                 #include"reg52.h"
#define uchar unsigned char
#define uint unsigned int
sbit pp=P1^5;
sbit k8=P3^3;
bit  flag=0;
uint delay_cnt=0;
/*
void delay(uint x)
{
        uint i, j;
        for(i=x; i>0; i--)
                for(j=0; j>0; j--);
}*/
void main()
{
//        IT1=1;
//        EX1=1;
//        EA=0;
        while(1)
        {
//                if(flag==1)
//                {
//                        pp=~pp;
//                        delay(10);
//                }  
                if(k8==0)
                {
//                        delay(10);
//                        if(k8==0);
                        if(++delay_cnt>=500 && flag==0)
                        {
                                flag=1;
                                pp=~pp;
                        }        delay_cnt>10; //自己增加的部分
//                        EA=1;
                }
                else
                {
                        flag=0;
                        delay_cnt=0;
                }
        }
}
/*
void int1_serv() interrupt 2
{
        EA=0;
        flag1=1;
}*/        
回复

使用道具 举报

ID:161164 发表于 2022-2-10 20:51 来自手机 | 显示全部楼层
廖振基 发表于 2022-2-9 13:49
谢谢指点,用中断主要是考虑到,:如果程序有较长时间的循环等待时,非中断暂停键就不会快速响应,当然,这 ...

正常写程序应避免产生长时间的循环
见到那些Delay(10)的按键消抖/数码管显示和while(!key)松开检测
就觉得是白白浪费了单片机的速度
就算是最老的51单片机都可以1微秒一条指令
10毫秒可以跑上千条指令
所以你的思路不应该去想用中断快速反应按键
而是要去想如何减少使用阻塞式延时
回复

使用道具 举报

ID:313048 发表于 2022-2-11 10:13 | 显示全部楼层
按键可以使用状态机,能够有效的去除阻塞延时。
回复

使用道具 举报

ID:311903 发表于 2022-2-11 10:20 | 显示全部楼层
按键按下后,开启定时器计时消抖
回复

使用道具 举报

ID:451718 发表于 2022-2-11 13:55 | 显示全部楼层
廖振基 发表于 2022-2-8 18:40
已经解决问题了,但是不理想,延时去抖不能用在中断程序里,造成按键不可靠,进入中断后关掉中断效果也不好 ...

好办法就是学会用定时器中断,通过定时器中断,在程序中植入毫秒计时,也就是经常在例程中看到的 SysTick++操作。程序中所有的延迟,都可以通过对SysTick时钟的比对来实现。 如你要Delay(20ms);可以对时间变量T1= SysTick;取值,然后判断 通过判断 SysTick-T1是否大于20来实现延迟,多看例程。
回复

使用道具 举报

ID:999123 发表于 2022-2-11 16:49 | 显示全部楼层
谢谢大家的指点,知识量有点多,我先去研究研究了。再次谢谢大家。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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